<commit_before>import lzma
import struct

from osrparse.utils import (ReplayEventOsu, ReplayEventTaiko, ReplayEventCatch,
    ReplayEventMania)
from osrparse.replay import Replay

def pack_byte(data: int):
    return struct.pack("<B", data)

def pack_short(data: int):
    return struct.pack("<H", data)

def pack_int(data: int):
    return struct.pack("<I", data)

def pack_long(data: int):
    return struct.pack("<Q", data)

def pack_ULEB128(data):
    # taken from https://github.com/mohanson/leb128
    r, i = [], len(data)

    while True:
        byte = i & 0x7f
        i = i >> 7

        if (i == 0 and byte & 0x40 == 0) or (i == -1 and byte & 0x40 != 0):
            r.append(byte)
            return b"".join(map(pack_byte, r))

        r.append(0x80 | byte)

def pack_string(data: str):
    if data:
        return pack_byte(11) + pack_ULEB128(data) + data.encode("utf-8")
    return pack_byte(11) + pack_byte(0)

def dump_timestamp(replay):
    # due to converting ticks into an int, there appears to be some
    # precision loss in the ticks value even though it's small (around 4
    # ticks), it might be an issue with reproccessing the same replay for
    # many times in a row

    # when it's negative, it represents January 1st 0001, 01:00:00 AM UTC
    shift = 62135596800 + 3600
    ticks = (replay.timestamp.timestamp() + shift) * 10_000_000

    return pack_long(int(ticks))

def dump_replay_data(replay):
    replay_data = ""
    for event in replay.play_data:
        if isinstance(event, ReplayEventOsu):
            replay_data += f"{event.time_delta}|{event.x}|{event.y}|{event.keys.value},"
        elif isinstance(event, ReplayEventTaiko):
            replay_data += f"{event.time_delta}|{event.x}|0|{event.keys.value},"
        elif isinstance(event, ReplayEventCatch):
            replay_data += f"{event.time_delta}|{event.x}|0|{int(event.dashing)},"
        elif isinstance(event, ReplayEventMania):
            replay_data += f"{event.time_delta}|{event.keys}|0|0,"

    filters = [{"id": lzma.FILTER_LZMA1, "dict_size": 2097152, "mode": lzma.MODE_FAST}]
    compressed = lzma.compress(replay_data.encode("ascii"), format=lzma.FORMAT_ALONE, filters=filters)

    return pack_int(len(compressed)) + compressed

def dump_replay(replay: Replay):
    data = b""

    data += pack_byte(replay.game_mode.value)
    data += pack_int(replay.game_version)
    data += pack_string(replay.beatmap_hash)

    data += pack_string(replay.player_name)
    data += pack_string(replay.replay_hash)

    data += pack_short(replay.number_300s)
    data += pack_short(replay.number_100s)
    data += pack_short(replay.number_50s)
    data += pack_short(replay.gekis)
    data += pack_short(replay.katus)
    data += pack_short(replay.misses)

    data += pack_int(replay.score)
    data += pack_short(replay.max_combo)
    data += pack_byte(replay.is_perfect_combo)

    data += pack_int(replay.mod_combination.value)
    data += pack_string(replay.life_bar_graph)
    data += dump_timestamp(replay)

    data += dump_replay_data(replay)
    data += pack_long(replay.replay_id)

    return data

def dump_replay_file(replay: Replay, file_name: str):
    with open(file_name, "wb") as f:
        f.write(dump_replay(replay))
<commit_msg>fix and clean up dump_timestamp<commit_after>import lzma
import struct

from osrparse.utils import (ReplayEventOsu, ReplayEventTaiko, ReplayEventCatch,
    ReplayEventMania)
from osrparse.replay import Replay

def pack_byte(data: int):
    return struct.pack("<B", data)

def pack_short(data: int):
    return struct.pack("<H", data)

def pack_int(data: int):
    return struct.pack("<I", data)

def pack_long(data: int):
    return struct.pack("<Q", data)

def pack_ULEB128(data):
    # taken from https://github.com/mohanson/leb128
    r, i = [], len(data)

    while True:
        byte = i & 0x7f
        i = i >> 7

        if (i == 0 and byte & 0x40 == 0) or (i == -1 and byte & 0x40 != 0):
            r.append(byte)
            return b"".join(map(pack_byte, r))

        r.append(0x80 | byte)

def pack_string(data: str):
    if data:
        return pack_byte(11) + pack_ULEB128(data) + data.encode("utf-8")
    return pack_byte(11) + pack_byte(0)

def dump_timestamp(replay):
    # windows ticks starts at year 0001, in contrast to unix time (1970).
    # 62135596800 is the number of seconds between these two years and is added
    # to account for this difference.
    # The factor of 10000000 converts seconds to ticks.
    ticks = (62135596800 + replay.timestamp.timestamp()) * 10000000
    ticks = int(ticks)
    return pack_long(ticks)

def dump_replay_data(replay):
    replay_data = ""
    for event in replay.play_data:
        if isinstance(event, ReplayEventOsu):
            replay_data += f"{event.time_delta}|{event.x}|{event.y}|{event.keys.value},"
        elif isinstance(event, ReplayEventTaiko):
            replay_data += f"{event.time_delta}|{event.x}|0|{event.keys.value},"
        elif isinstance(event, ReplayEventCatch):
            replay_data += f"{event.time_delta}|{event.x}|0|{int(event.dashing)},"
        elif isinstance(event, ReplayEventMania):
            replay_data += f"{event.time_delta}|{event.keys}|0|0,"

    filters = [{"id": lzma.FILTER_LZMA1, "dict_size": 2097152, "mode": lzma.MODE_NORMAL}]
    compressed = lzma.compress(replay_data.encode("ascii"), format=lzma.FORMAT_ALONE, filters=filters)

    return pack_int(len(compressed)) + compressed

def dump_replay(replay: Replay):
    data = b""

    data += pack_byte(replay.game_mode.value)
    data += pack_int(replay.game_version)
    data += pack_string(replay.beatmap_hash)

    data += pack_string(replay.player_name)
    data += pack_string(replay.replay_hash)

    data += pack_short(replay.number_300s)
    data += pack_short(replay.number_100s)
    data += pack_short(replay.number_50s)
    data += pack_short(replay.gekis)
    data += pack_short(replay.katus)
    data += pack_short(replay.misses)

    data += pack_int(replay.score)
    data += pack_short(replay.max_combo)
    data += pack_byte(replay.is_perfect_combo)

    data += pack_int(replay.mod_combination.value)
    data += pack_string(replay.life_bar_graph)
    data += dump_timestamp(replay)

    data += dump_replay_data(replay)
    data += pack_long(replay.replay_id)

    return data

def dump_replay_file(replay: Replay, file_name: str):
    with open(file_name, "wb") as f:
        f.write(dump_replay(replay))
<|endoftext|>


<commit_before>"""
Serialized Data Converter.

Licensed under MIT
Copyright (c) 2012 - 2015 Isaac Muse <isaacmuse@gmail.com>
"""
import sublime
from . import plistlib
import datetime

__all__ = ("read_plist_from_view", "read_plist_from_file", "plist_dumps", "plist_binary_dumps")

def convert_from_hex(view):
    """Convert Sublime hex view to bytes."""

    text = view.substr(sublime.Region(0, view.size())).replace(' ', '').replace('\n', '')
    byte = []
    offset = 0
    for x in range(0, int(len(text) / 2)):
        byte.append(int(text[x + offset:x + offset + 2], 16))
        offset += 1
    return bytes(byte)

def plist_dumps(obj, detect_timestamp=False, none_handler="fail"):
    """Wrapper for PLIST dump."""

    return plistlib.writePlistToBytes(
        plist_convert_to(obj, detect_timestamp, none_handler)
    ).decode('utf-8')

def plist_binary_dumps(obj, detect_timestamp=False, none_handler="fail"):
    """Wrapper for PLIST binary dump."""

    return plistlib.dumps(
        plist_convert_to(obj, detect_timestamp, none_handler),
        fmt=plistlib.FMT_BINARY
    )

def read_plist_from_hex_view(view):
    """Read PLIST from a Sublime hex view."""

    return plist_convert_from(
        plistlib.readPlistFromBytes(
            convert_from_hex(view)
        )
    )

def read_plist_from_view(view):
    """Read PLIST from  a Sublime view."""

    return plist_convert_from(
        plistlib.readPlistFromBytes(
            view.substr(
                sublime.Region(0, view.size())
            ).encode('utf8')
        )
    )

def read_plist_from_file(filename):
    """Read PLIST from filename."""

    return plist_convert_from(
        plistlib.readPlist(filename)
    )

def convert_timestamp(obj):
    """Convert plist timestamp."""

    time_stamp = None
    if plistlib._dateParser.match(obj):
        time_stamp = plistlib._dateFromString(obj)
    return time_stamp

def plist_convert_from(obj):
    """Convert specific plist items to a form usable by others."""

    if isinstance(obj, plistlib._InternalDict):
        for k, v in obj.items():
            obj[k] = plist_convert_from(v)
    elif isinstance(obj, list):
        count = 0
        for v in obj:
            obj[count] = plist_convert_from(v)
            count += 1
    elif isinstance(obj, datetime.datetime):
        obj = plistlib._dateToString(obj)

    return obj

def plist_convert_to(obj, detect_timestamp=False, none_handler="fail"):
    """Convert specific serialized items to a plist format."""

    if isinstance(obj, dict):
        for k, v in (list(obj.items()) if none_handler == "strip" else obj.items()):
            if none_handler == "strip" and v is None:
                del obj[k]
            elif none_handler == "false" and v is None:
                obj[k] = False
            else:
                obj[k] = plist_convert_to(v, detect_timestamp, none_handler)
    elif isinstance(obj, list):
        count = 0
        offset = 0
        for v in (obj[:] if none_handler == "strip" else obj):
            if none_handler == "strip" and v is None:
                del obj[count - offset]
                offset += 1
            elif none_handler == "false" and v is None:
                obj[count - offset] = False
            else:
                obj[count - offset] = plist_convert_to(v, detect_timestamp, none_handler)
            count += 1
    elif isinstance(obj, str) and detect_timestamp:
        time_stamp = convert_timestamp(obj)
        if time_stamp is not None:
            obj = time_stamp

    return obj
<commit_msg>Strip comments before parsing plist.<commit_after>"""
Serialized Data Converter.

Licensed under MIT
Copyright (c) 2012 - 2015 Isaac Muse <isaacmuse@gmail.com>
"""
import sublime
from . import plistlib
import datetime
import re

__all__ = ("read_plist_from_view", "read_plist_from_file", "plist_dumps", "plist_binary_dumps")

def strip_plist_comments(text):
    """Strip comments from plist."""

    return re.sub(
        br"^[\r\n\s]*<!--[\s\S]*?-->[\s\r\n]*|<!--[\s\S]*?-->", b'',
        text
    )

def convert_from_hex(view):
    """Convert Sublime hex view to bytes."""

    text = view.substr(sublime.Region(0, view.size())).replace(' ', '').replace('\n', '')
    byte = []
    offset = 0
    for x in range(0, int(len(text) / 2)):
        byte.append(int(text[x + offset:x + offset + 2], 16))
        offset += 1
    return bytes(byte)

def plist_dumps(obj, detect_timestamp=False, none_handler="fail"):
    """Wrapper for PLIST dump."""

    return plistlib.writePlistToBytes(
        plist_convert_to(obj, detect_timestamp, none_handler)
    ).decode('utf-8')

def plist_binary_dumps(obj, detect_timestamp=False, none_handler="fail"):
    """Wrapper for PLIST binary dump."""

    return plistlib.dumps(
        plist_convert_to(obj, detect_timestamp, none_handler),
        fmt=plistlib.FMT_BINARY
    )

def read_plist_from_hex_view(view):
    """Read PLIST from a Sublime hex view."""

    return plist_convert_from(
        plistlib.readPlistFromBytes(
            strip_plist_comments(convert_from_hex(view))
        )
    )

def read_plist_from_view(view):
    """Read PLIST from  a Sublime view."""

    return plist_convert_from(
        plistlib.readPlistFromBytes(
            strip_plist_comments(
                view.substr(
                    sublime.Region(0, view.size())
                ).encode('utf8')
            )
        )
    )

def read_plist_from_file(filename):
    """
    Read PLIST from filename.

    This is only used when reading binary plists,
    so no need to strip comments.
    """

    return plist_convert_from(
        plistlib.readPlist(filename)
    )

def convert_timestamp(obj):
    """Convert plist timestamp."""

    time_stamp = None
    if plistlib._dateParser.match(obj):
        time_stamp = plistlib._dateFromString(obj)
    return time_stamp

def plist_convert_from(obj):
    """Convert specific plist items to a form usable by others."""

    if isinstance(obj, plistlib._InternalDict):
        for k, v in obj.items():
            obj[k] = plist_convert_from(v)
    elif isinstance(obj, list):
        count = 0
        for v in obj:
            obj[count] = plist_convert_from(v)
            count += 1
    elif isinstance(obj, datetime.datetime):
        obj = plistlib._dateToString(obj)

    return obj

def plist_convert_to(obj, detect_timestamp=False, none_handler="fail"):
    """Convert specific serialized items to a plist format."""

    if isinstance(obj, dict):
        for k, v in (list(obj.items()) if none_handler == "strip" else obj.items()):
            if none_handler == "strip" and v is None:
                del obj[k]
            elif none_handler == "false" and v is None:
                obj[k] = False
            else:
                obj[k] = plist_convert_to(v, detect_timestamp, none_handler)
    elif isinstance(obj, list):
        count = 0
        offset = 0
        for v in (obj[:] if none_handler == "strip" else obj):
            if none_handler == "strip" and v is None:
                del obj[count - offset]
                offset += 1
            elif none_handler == "false" and v is None:
                obj[count - offset] = False
            else:
                obj[count - offset] = plist_convert_to(v, detect_timestamp, none_handler)
            count += 1
    elif isinstance(obj, str) and detect_timestamp:
        time_stamp = convert_timestamp(obj)
        if time_stamp is not None:
            obj = time_stamp

    return obj
<|endoftext|>


<commit_before>#!/usr/bin/env python
###
### plot_functions.py
### function for producing plots

NCPU = 6 # number of CPUs

import numpy
import matplotlib
import matplotlib.pyplot
import os
import glob
import sys
from multiprocessing import Pool

#
# Plotting initial data
#
def plot_initial_data(pirates, levels = 10):

    # contour plot of inital density of pirates
    plt_contour(pirates.x, pirates.y, pirates.initial_density_pirates, 'Pirate initial density', 'plot_pirate_initial_density.png', pirates.base_directory, pirates.police_initial_positions, levels)

    # contour plot of inital density of ships
    plt_contour(pirates.x, pirates.y, pirates.initial_density_ships, 'Ship initial density', 'plot_ship_initial_density.png', pirates.base_directory, pirates.police_initial_positions, levels)

#
# Plotting data at a specific time
#
def plot_data(pirates, density_pirates, density_ships, police_positions, time, levels = 10):

    # contour plot of pirate's density at time time
    plt_contour(pirates.x, pirates.y, density_pirates, 'Density of pirates at time ' + str(time), 'plot_pirate_density_' + str(time) + '.png', pirates.base_directory, police_positions, levels)

    # contour plot of ships' density at time time
    plt_contour(pirates.x, pirates.y, density_ships, 'Density of ships at time ' + str(time), 'plot_ship_density_' + str(time) + '.png', pirates.base_directory, police_positions, levels)

#
# function for plotting contour
#
def plt_contour(x, y, function, title, name, dir, police_position, levels=10):
    matplotlib.pyplot.figure(1)

    # adjusting police positions
    px = [i[0] for i in police_position]
    py = [i[1] for i in police_position]

    v = numpy.linspace(0., 1.0, 35, endpoint=True)

    # plotting contour with colorbar
    # matplotlib.pyplot.contourf(x, y, function, levels)
    matplotlib.pyplot.contourf(x, y, function, v, cmap=matplotlib.pyplot.cm.jet)
    matplotlib.pyplot.colorbar()

    # plotting police positions as white points
    matplotlib.pyplot.plot(px, py, 'wo')

    # plotting title
    matplotlib.pyplot.title(title)

    # saving the plot
    matplotlib.pyplot.draw()
    full_name = os.path.join(dir, name)
    matplotlib.pyplot.savefig(full_name)
    matplotlib.pyplot.close(1)

#
# plot the geometric vector speed
#
def plt_geometric_vector_speed(pirates, h_p, v_p):
    x = numpy.linspace(pirates.x[0], pirates.x[-1], h_p)
    y = numpy.linspace(pirates.y[0], pirates.y[-1], v_p)
    x_mesh, y_mesh = numpy.meshgrid(x, y)
    vf = matplotlib.pyplot.figure(1)

    (dx, dy) = pirates.ships_direction(x, y)
    matplotlib.pyplot.quiver(x_mesh, y_mesh, dx, dy)
    matplotlib.pyplot.title('Geometric vector field $\\nu$', fontsize = 18)
    #matplotlib.pyplot.show(vf)
    matplotlib.pyplot.draw()
    full_name = os.path.join(pirates.base_directory, 'plot_gvf.png')
    matplotlib.pyplot.savefig(full_name)
    matplotlib.pyplot.close(vf)

#
# plot the kernels and the cut-off functions
#
def plt_kernels(pirates, x, y, h_p = 50, v_p = 50, levels = 50):

    x_mesh, y_mesh = numpy.meshgrid(x, y)

    vf = matplotlib.pyplot.figure(1)

    # plotting contour with colorbar
    matplotlib.pyplot.contourf(x, y, pirates.mathcal_K(x, y), levels)
    matplotlib.pyplot.colorbar()

    # plotting title
    title = '$\\mathcal{K}$ kernel'
    matplotlib.pyplot.title(title)

    # saving the plot
    matplotlib.pyplot.draw()
    #matplotlib.pyplot.show(vf)
    full_name = os.path.join(pirates.base_directory, 'plot_kernel_K.png')
    matplotlib.pyplot.savefig(full_name)
    matplotlib.pyplot.close(vf)

    vf = matplotlib.pyplot.figure(1)

    # plotting contour with colorbar
    matplotlib.pyplot.contourf(x, y, pirates.cut_off_C(x, y), levels)
    matplotlib.pyplot.colorbar()

    # plotting title
    title = 'Cut-off function $\\mathcal{C}$'
    matplotlib.pyplot.title(title)

    # saving the plot
    matplotlib.pyplot.draw()
    #matplotlib.pyplot.show(vf)
    full_name = os.path.join(pirates.base_directory, 'plot_cut-off_C.png')
    matplotlib.pyplot.savefig(full_name)
    matplotlib.pyplot.close(vf)

#
# plot the solutions
#
def plt_solutions(pirates, levels = 10):

    dirName = pirates.base_directory

    list_files = glob.glob(os.path.join(dirName, 'saving*.npz'))
    list_files.sort()

    # plotting initial conditions
    plt_contour(pirates.x, pirates.y, pirates.initial_density_pirates, 'Pirates density at time t=0', 'pirates_plot_0000.png', pirates.base_directory, pirates.police_initial_positions, levels)
    plt_contour(pirates.x, pirates.y, pirates.initial_density_ships, 'Ships density at time t=0', 'ships_plot_0000.png', pirates.base_directory, pirates.police_initial_positions, levels)

    # pirates' and ships pictures
    for FileName in list_files:
        name = '_plot' + os.path.splitext(FileName)[0][1:][-5:] + '.png'
        pirate_file = 'pirates' + name
        ship_file = 'ships' + name

        # read the file
        npzf = numpy.load(FileName)
        t = npzf['t']
        p_density = npzf['r']
        s_density = npzf['A']
        police = npzf['d']
        npzf.close()

        # contour plot of density of pirates
        plt_contour(pirates.x, pirates.y, p_density, 'Pirates density at time t=' + str("%.3f" %t), pirate_file, dirName, pirates.police_initial_positions, levels)

        # contour plot of inital density of ships
        plt_contour(pirates.x, pirates.y, s_density, 'Ships density at time t=' + str("%.3f" %t), ship_file, dirName, pirates.police_initial_positions, levels)

#
# final movie
#
def movie(pirates):
    pirate = os.path.join(pirates.base_directory, 'pirates_plot*')
    movie_p = os.path.join(pirates.base_directory, 'movie_pirates.mpg')
    ship = os.path.join(pirates.base_directory, 'ships_plot*')
    movie_s = os.path.join(pirates.base_directory, 'movie_ships.mpg')

    os.system("mencoder 'mf://'" + pirate + " -mf type=png:fps=5 -ovc lavc -lavcopts vcodec=wmv2 -oac copy -o " + movie_p)
    os.system("mencoder 'mf://'" + ship + " -mf type=png:fps=5 -ovc lavc -lavcopts vcodec=wmv2 -oac copy -o " + movie_s)
<commit_msg>Corrected the plot of police!!!<commit_after>#!/usr/bin/env python
###
### plot_functions.py
### function for producing plots

NCPU = 6 # number of CPUs

import numpy
import matplotlib
import matplotlib.pyplot
import os
import glob
import sys
from multiprocessing import Pool

#
# Plotting initial data
#
def plot_initial_data(pirates, levels = 10):

    # contour plot of inital density of pirates
    plt_contour(pirates.x, pirates.y, pirates.initial_density_pirates, 'Pirate initial density', 'plot_pirate_initial_density.png', pirates.base_directory, pirates.police_initial_positions, levels)

    # contour plot of inital density of ships
    plt_contour(pirates.x, pirates.y, pirates.initial_density_ships, 'Ship initial density', 'plot_ship_initial_density.png', pirates.base_directory, pirates.police_initial_positions, levels)

#
# Plotting data at a specific time
#
def plot_data(pirates, density_pirates, density_ships, police_positions, time, levels = 10):

    # contour plot of pirate's density at time time
    plt_contour(pirates.x, pirates.y, density_pirates, 'Density of pirates at time ' + str(time), 'plot_pirate_density_' + str(time) + '.png', pirates.base_directory, police_positions, levels)

    # contour plot of ships' density at time time
    plt_contour(pirates.x, pirates.y, density_ships, 'Density of ships at time ' + str(time), 'plot_ship_density_' + str(time) + '.png', pirates.base_directory, police_positions, levels)

#
# function for plotting contour
#
def plt_contour(x, y, function, title, name, dir, police_position, levels=10):
    matplotlib.pyplot.figure(1)

    # adjusting police positions
    px = [i[0] for i in police_position]
    py = [i[1] for i in police_position]

    v = numpy.linspace(0., 1.0, 35, endpoint=True)

    # plotting contour with colorbar
    # matplotlib.pyplot.contourf(x, y, function, levels)
    matplotlib.pyplot.contourf(x, y, function, v, cmap=matplotlib.pyplot.cm.jet)
    matplotlib.pyplot.colorbar()

    # plotting police positions as white points
    matplotlib.pyplot.plot(px, py, 'wo')

    # plotting title
    matplotlib.pyplot.title(title)

    # saving the plot
    matplotlib.pyplot.draw()
    full_name = os.path.join(dir, name)
    matplotlib.pyplot.savefig(full_name)
    matplotlib.pyplot.close(1)

#
# plot the geometric vector speed
#
def plt_geometric_vector_speed(pirates, h_p, v_p):
    x = numpy.linspace(pirates.x[0], pirates.x[-1], h_p)
    y = numpy.linspace(pirates.y[0], pirates.y[-1], v_p)
    x_mesh, y_mesh = numpy.meshgrid(x, y)
    vf = matplotlib.pyplot.figure(1)

    (dx, dy) = pirates.ships_direction(x, y)
    matplotlib.pyplot.quiver(x_mesh, y_mesh, dx, dy)
    matplotlib.pyplot.title('Geometric vector field $\\nu$', fontsize = 18)
    #matplotlib.pyplot.show(vf)
    matplotlib.pyplot.draw()
    full_name = os.path.join(pirates.base_directory, 'plot_gvf.png')
    matplotlib.pyplot.savefig(full_name)
    matplotlib.pyplot.close(vf)

#
# plot the kernels and the cut-off functions
#
def plt_kernels(pirates, x, y, h_p = 50, v_p = 50, levels = 50):

    x_mesh, y_mesh = numpy.meshgrid(x, y)

    vf = matplotlib.pyplot.figure(1)

    # plotting contour with colorbar
    matplotlib.pyplot.contourf(x, y, pirates.mathcal_K(x, y), levels)
    matplotlib.pyplot.colorbar()

    # plotting title
    title = '$\\mathcal{K}$ kernel'
    matplotlib.pyplot.title(title)

    # saving the plot
    matplotlib.pyplot.draw()
    #matplotlib.pyplot.show(vf)
    full_name = os.path.join(pirates.base_directory, 'plot_kernel_K.png')
    matplotlib.pyplot.savefig(full_name)
    matplotlib.pyplot.close(vf)

    vf = matplotlib.pyplot.figure(1)

    # plotting contour with colorbar
    matplotlib.pyplot.contourf(x, y, pirates.cut_off_C(x, y), levels)
    matplotlib.pyplot.colorbar()

    # plotting title
    title = 'Cut-off function $\\mathcal{C}$'
    matplotlib.pyplot.title(title)

    # saving the plot
    matplotlib.pyplot.draw()
    #matplotlib.pyplot.show(vf)
    full_name = os.path.join(pirates.base_directory, 'plot_cut-off_C.png')
    matplotlib.pyplot.savefig(full_name)
    matplotlib.pyplot.close(vf)

#
# plot the solutions
#
def plt_solutions(pirates, levels = 10):

    dirName = pirates.base_directory

    list_files = glob.glob(os.path.join(dirName, 'saving*.npz'))
    list_files.sort()

    # plotting initial conditions
    plt_contour(pirates.x, pirates.y, pirates.initial_density_pirates, 'Pirates density at time t=0', 'pirates_plot_0000.png', pirates.base_directory, pirates.police_initial_positions, levels)
    plt_contour(pirates.x, pirates.y, pirates.initial_density_ships, 'Ships density at time t=0', 'ships_plot_0000.png', pirates.base_directory, pirates.police_initial_positions, levels)

    # pirates' and ships pictures
    for FileName in list_files:
        name = '_plot' + os.path.splitext(FileName)[0][1:][-5:] + '.png'
        pirate_file = 'pirates' + name
        ship_file = 'ships' + name

        # read the file
        npzf = numpy.load(FileName)
        t = npzf['t']
        p_density = npzf['r']
        s_density = npzf['A']
        police = npzf['d']
        npzf.close()

        # contour plot of density of pirates
        plt_contour(pirates.x, pirates.y, p_density, 'Pirates density at time t=' + str("%.3f" %t), pirate_file, dirName, police, levels)

        # contour plot of inital density of ships
        plt_contour(pirates.x, pirates.y, s_density, 'Ships density at time t=' + str("%.3f" %t), ship_file, dirName, police, levels)

#
# final movie
#
def movie(pirates):
    pirate = os.path.join(pirates.base_directory, 'pirates_plot*')
    movie_p = os.path.join(pirates.base_directory, 'movie_pirates.mpg')
    ship = os.path.join(pirates.base_directory, 'ships_plot*')
    movie_s = os.path.join(pirates.base_directory, 'movie_ships.mpg')

    os.system("mencoder 'mf://'" + pirate + " -mf type=png:fps=5 -ovc lavc -lavcopts vcodec=wmv2 -oac copy -o " + movie_p)
    os.system("mencoder 'mf://'" + ship + " -mf type=png:fps=5 -ovc lavc -lavcopts vcodec=wmv2 -oac copy -o " + movie_s)
<|endoftext|>


<commit_before># Copyright 2019 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://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.
# ==============================================================================
"""Tests for triplet loss."""

import numpy as np
import tensorflow as tf

from tensorflow_addons.losses import triplet
from tensorflow_addons.utils import test_utils

def pairwise_distance_np(feature, squared=False):
    """Computes the pairwise distance matrix in numpy.

    Args:
      feature: 2-D numpy array of size [number of data, feature dimension]
      squared: Boolean. If true, output is the pairwise squared euclidean
        distance matrix; else, output is the pairwise euclidean distance
        matrix.

    Returns:
      pairwise_distances: 2-D numpy array of size
        [number of data, number of data].
    """
    triu = np.triu_indices(feature.shape[0], 1)
    upper_tri_pdists = np.linalg.norm(feature[triu[1]] - feature[triu[0]], axis=1)
    if squared:
        upper_tri_pdists **= 2.0
    num_data = feature.shape[0]
    pairwise_distances = np.zeros((num_data, num_data))
    pairwise_distances[np.triu_indices(num_data, 1)] = upper_tri_pdists
    # Make symmetrical.
    pairwise_distances = (
        pairwise_distances
        + pairwise_distances.T
        - np.diag(pairwise_distances.diagonal())
    )
    return pairwise_distances

def triplet_hard_loss_np(labels, embedding, margin, soft=False):

    num_data = embedding.shape[0]
    # Reshape labels to compute adjacency matrix.
    labels_reshaped = np.reshape(labels.astype(np.float32), (labels.shape[0], 1))
    # Compute the loss in NP.
    adjacency = np.equal(labels_reshaped, labels_reshaped.T)

    pdist_matrix = pairwise_distance_np(embedding, squared=True)
    loss_np = 0.0
    for i in range(num_data):
        pos_distances = []
        neg_distances = []
        for j in range(num_data):
            if adjacency[i][j] == 0:
                neg_distances.append(pdist_matrix[i][j])
            if adjacency[i][j] > 0.0 and i != j:
                pos_distances.append(pdist_matrix[i][j])

        # if there are no positive pairs, distance is 0
        if len(pos_distances) == 0:
            pos_distances.append(0)

        # Sort by distance.
        neg_distances.sort()
        min_neg_distance = neg_distances[0]
        pos_distances.sort(reverse=True)
        max_pos_distance = pos_distances[0]

        if soft:
            loss_np += np.log1p(np.exp(max_pos_distance - min_neg_distance))
        else:
            loss_np += np.maximum(0.0, max_pos_distance - min_neg_distance + margin)

    loss_np /= num_data
    return loss_np

@test_utils.run_all_in_graph_and_eager_modes
class TripletSemiHardLossTest(tf.test.TestCase):
    def test_unweighted(self):
        num_data = 10
        feat_dim = 6
        margin = 1.0
        num_classes = 4

        embedding = np.random.rand(num_data, feat_dim).astype(np.float32)
        labels = np.random.randint(0, num_classes, size=(num_data))

        # Reshape labels to compute adjacency matrix.
        labels_reshaped = np.reshape(labels.astype(np.float32), (labels.shape[0], 1))
        # Compute the loss in NP.
        adjacency = np.equal(labels_reshaped, labels_reshaped.T)

        pdist_matrix = pairwise_distance_np(embedding, squared=True)
        loss_np = 0.0
        num_positives = 0.0
        for i in range(num_data):
            for j in range(num_data):
                if adjacency[i][j] > 0.0 and i != j:
                    num_positives += 1.0

                    pos_distance = pdist_matrix[i][j]
                    neg_distances = []

                    for k in range(num_data):
                        if adjacency[i][k] == 0:
                            neg_distances.append(pdist_matrix[i][k])

                    # Sort by distance.
                    neg_distances.sort()
                    chosen_neg_distance = neg_distances[0]

                    for l in range(len(neg_distances)):
                        chosen_neg_distance = neg_distances[l]
                        if chosen_neg_distance > pos_distance:
                            break

                    loss_np += np.maximum(
                        0.0, margin - chosen_neg_distance + pos_distance
                    )

        loss_np /= num_positives

        # Compute the loss in TF.
        y_true = tf.constant(labels)
        y_pred = tf.constant(embedding)
        cce_obj = triplet.TripletSemiHardLoss()
        loss = cce_obj(y_true, y_pred)
        self.assertAlmostEqual(self.evaluate(loss), loss_np, 3)

    def test_keras_model_compile(self):
        model = tf.keras.models.Sequential(
            [tf.keras.layers.Input(shape=(784,)), tf.keras.layers.Dense(10),]
        )
        model.compile(loss="Addons>triplet_semihard_loss", optimizer="adam")

    def test_serialization(self):
        loss = triplet.TripletSemiHardLoss()
        tf.keras.losses.deserialize(tf.keras.losses.serialize(loss))

def test_unweighted():
    num_data = 20
    feat_dim = 6
    margin = 1.0
    num_classes = 4

    embedding = np.random.rand(num_data, feat_dim).astype(np.float32)
    labels = np.random.randint(0, num_classes, size=(num_data))

    loss_np = triplet_hard_loss_np(labels, embedding, margin)

    # Compute the loss in TF.
    y_true = tf.constant(labels)
    y_pred = tf.constant(embedding)
    cce_obj = triplet.TripletHardLoss()
    loss = cce_obj(y_true, y_pred)
    np.testing.assert_allclose(loss, loss_np, rtol=1e-6, atol=1e-6)

def test_unweighted_soft():
    num_data = 20
    feat_dim = 6
    margin = 1.0
    num_classes = 4

    embedding = np.random.rand(num_data, feat_dim).astype(np.float32)
    labels = np.random.randint(0, num_classes, size=(num_data))

    loss_np = triplet_hard_loss_np(labels, embedding, margin, soft=True)

    # Compute the loss in TF.
    y_true = tf.constant(labels)
    y_pred = tf.constant(embedding)
    cce_obj = triplet.TripletHardLoss(soft=True)
    loss = cce_obj(y_true, y_pred)
    np.testing.assert_allclose(loss, loss_np, rtol=1e-6, atol=1e-6)

def test_keras_model_compile():
    model = tf.keras.models.Sequential(
        [tf.keras.layers.Input(shape=(784,)), tf.keras.layers.Dense(10),]
    )
    model.compile(loss="Addons>triplet_hard_loss", optimizer="adam")

def test_serialization():
    loss = triplet.TripletHardLoss()
    tf.keras.losses.deserialize(tf.keras.losses.serialize(loss))
<commit_msg>Moved test out of run_in_graph_and_eager_mode in triplet_test (#1540)<commit_after># Copyright 2019 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://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.
# ==============================================================================
"""Tests for triplet loss."""

import numpy as np
import tensorflow as tf

from tensorflow_addons.losses import triplet

def pairwise_distance_np(feature, squared=False):
    """Computes the pairwise distance matrix in numpy.

    Args:
      feature: 2-D numpy array of size [number of data, feature dimension]
      squared: Boolean. If true, output is the pairwise squared euclidean
        distance matrix; else, output is the pairwise euclidean distance
        matrix.

    Returns:
      pairwise_distances: 2-D numpy array of size
        [number of data, number of data].
    """
    triu = np.triu_indices(feature.shape[0], 1)
    upper_tri_pdists = np.linalg.norm(feature[triu[1]] - feature[triu[0]], axis=1)
    if squared:
        upper_tri_pdists **= 2.0
    num_data = feature.shape[0]
    pairwise_distances = np.zeros((num_data, num_data))
    pairwise_distances[np.triu_indices(num_data, 1)] = upper_tri_pdists
    # Make symmetrical.
    pairwise_distances = (
        pairwise_distances
        + pairwise_distances.T
        - np.diag(pairwise_distances.diagonal())
    )
    return pairwise_distances

def triplet_hard_loss_np(labels, embedding, margin, soft=False):

    num_data = embedding.shape[0]
    # Reshape labels to compute adjacency matrix.
    labels_reshaped = np.reshape(labels.astype(np.float32), (labels.shape[0], 1))
    # Compute the loss in NP.
    adjacency = np.equal(labels_reshaped, labels_reshaped.T)

    pdist_matrix = pairwise_distance_np(embedding, squared=True)
    loss_np = 0.0
    for i in range(num_data):
        pos_distances = []
        neg_distances = []
        for j in range(num_data):
            if adjacency[i][j] == 0:
                neg_distances.append(pdist_matrix[i][j])
            if adjacency[i][j] > 0.0 and i != j:
                pos_distances.append(pdist_matrix[i][j])

        # if there are no positive pairs, distance is 0
        if len(pos_distances) == 0:
            pos_distances.append(0)

        # Sort by distance.
        neg_distances.sort()
        min_neg_distance = neg_distances[0]
        pos_distances.sort(reverse=True)
        max_pos_distance = pos_distances[0]

        if soft:
            loss_np += np.log1p(np.exp(max_pos_distance - min_neg_distance))
        else:
            loss_np += np.maximum(0.0, max_pos_distance - min_neg_distance + margin)

    loss_np /= num_data
    return loss_np

def test_unweighted_triple_loss():
    num_data = 10
    feat_dim = 6
    margin = 1.0
    num_classes = 4

    embedding = np.random.rand(num_data, feat_dim).astype(np.float32)
    labels = np.random.randint(0, num_classes, size=(num_data))

    # Reshape labels to compute adjacency matrix.
    labels_reshaped = np.reshape(labels.astype(np.float32), (labels.shape[0], 1))
    # Compute the loss in NP.
    adjacency = np.equal(labels_reshaped, labels_reshaped.T)

    pdist_matrix = pairwise_distance_np(embedding, squared=True)
    loss_np = 0.0
    num_positives = 0.0
    for i in range(num_data):
        for j in range(num_data):
            if adjacency[i][j] > 0.0 and i != j:
                num_positives += 1.0

                pos_distance = pdist_matrix[i][j]
                neg_distances = []

                for k in range(num_data):
                    if adjacency[i][k] == 0:
                        neg_distances.append(pdist_matrix[i][k])

                # Sort by distance.
                neg_distances.sort()
                chosen_neg_distance = neg_distances[0]

                for l in range(len(neg_distances)):
                    chosen_neg_distance = neg_distances[l]
                    if chosen_neg_distance > pos_distance:
                        break

                loss_np += np.maximum(0.0, margin - chosen_neg_distance + pos_distance)

    loss_np /= num_positives

    # Compute the loss in TF.
    y_true = tf.constant(labels)
    y_pred = tf.constant(embedding)
    cce_obj = triplet.TripletSemiHardLoss()
    loss = cce_obj(y_true, y_pred)
    # self.assertAlmostEqual(self.evaluate(loss), loss_np, 3)
    np.testing.assert_allclose(loss, loss_np, rtol=1e-6, atol=1e-6)

def test_keras_model_compile_semihard():
    model = tf.keras.models.Sequential(
        [tf.keras.layers.Input(shape=(784,)), tf.keras.layers.Dense(10),]
    )
    model.compile(loss="Addons>triplet_semihard_loss", optimizer="adam")

def test_serialization_semihard():
    loss = triplet.TripletSemiHardLoss()
    tf.keras.losses.deserialize(tf.keras.losses.serialize(loss))

def test_unweighted():
    num_data = 20
    feat_dim = 6
    margin = 1.0
    num_classes = 4

    embedding = np.random.rand(num_data, feat_dim).astype(np.float32)
    labels = np.random.randint(0, num_classes, size=(num_data))

    loss_np = triplet_hard_loss_np(labels, embedding, margin)

    # Compute the loss in TF.
    y_true = tf.constant(labels)
    y_pred = tf.constant(embedding)
    cce_obj = triplet.TripletHardLoss()
    loss = cce_obj(y_true, y_pred)
    np.testing.assert_allclose(loss, loss_np, rtol=1e-6, atol=1e-6)

def test_unweighted_soft():
    num_data = 20
    feat_dim = 6
    margin = 1.0
    num_classes = 4

    embedding = np.random.rand(num_data, feat_dim).astype(np.float32)
    labels = np.random.randint(0, num_classes, size=(num_data))

    loss_np = triplet_hard_loss_np(labels, embedding, margin, soft=True)

    # Compute the loss in TF.
    y_true = tf.constant(labels)
    y_pred = tf.constant(embedding)
    cce_obj = triplet.TripletHardLoss(soft=True)
    loss = cce_obj(y_true, y_pred)
    np.testing.assert_allclose(loss, loss_np, rtol=1e-6, atol=1e-6)

def test_keras_model_compile_hard():
    model = tf.keras.models.Sequential(
        [tf.keras.layers.Input(shape=(784,)), tf.keras.layers.Dense(10),]
    )
    model.compile(loss="Addons>triplet_hard_loss", optimizer="adam")

def test_serialization_hard():
    loss = triplet.TripletHardLoss()
    tf.keras.losses.deserialize(tf.keras.losses.serialize(loss))
<|endoftext|>


<commit_before>"""
Copyright (C) 2017 Open Source Robotics Foundation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://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.
"""

from geometry.point import Point

from models.city import City
from models.street import Street
from models.trunk import Trunk
from models.block import Block
from models.building import Building
from models.ground_plane import GroundPlane
from models.road import *

from builders.abstract_city_builder import AbstractCityBuilder

class SimpleCityBuilder(AbstractCityBuilder):

    def get_city(self):
        # Must be odd
        size = 5
        city = City()
        self.multiplier = 100

        self._create_ground_plane(city, size)
        self._setup_intersections(city, size)
        self._create_inner_streets(city, size)
        self._create_surrounding_ring_road(city, size)
        self._create_blocks(city, size)
        self._create_buildings(city, size)
        return city

    def _setup_intersections(self, city, size):
        self.intersections = [[Point(self.multiplier * x, self.multiplier * y, 0)
                              for y in range(size)] for x in range(size)]

        for x in range(size - 1):
            self.intersections[x][0] = self.intersections[x][0] + Point(0, -2)
        self.intersections[size - 1][0] = self.intersections[size - 1][0] + Point(2, -2)

        for y in range(1, size):
            self.intersections[size - 1][y] = self.intersections[size - 1][y] + Point(2, 0)

        for x in range(size - 1):
            self.intersections[size - x - 1][size - 1] = self.intersections[size - x - 1][size - 1] + Point(0, 2)
        self.intersections[0][size - 1] = self.intersections[0][size - 1] + Point(-2, 2)

        for y in range(1, size):
            self.intersections[0][size - y - 1] = self.intersections[0][size - y - 1] + Point(-2, 0)

        for x in range(size):
            for y in range(size):
                city.add_intersection_at(self.intersections[x][y])

    def _create_ground_plane(self, city, size):
        ground_plane_size = size * self.multiplier
        ground_plane = GroundPlane(ground_plane_size,
                                   Point(ground_plane_size / 2,
                                         ground_plane_size / 2,
                                         0),
                                   'ground_plane')
        city.set_ground_plane(ground_plane)

    def _create_inner_streets(self, city, size):

        # Vertical
        for x in range(1, size - 1):
            road = Street()
            for y in range(size):
                road.add_point(self.intersections[x][y])
            city.add_road(road)

        # Horizontal
        for y in range(1, size - 1):
            road = Street()
            for x in range(size):
                road.add_point(self.intersections[x][y])
            city.add_road(road)

        # Diagonals
        road = Street()
        for i in range(size):
            road.add_point(self.intersections[i][i])
        city.add_road(road)

        road = Street()
        for i in range(size):
            road.add_point(self.intersections[i][size - i - 1])
        city.add_road(road)

    def _create_surrounding_ring_road(self, city, size):
        ring_road_1 = Trunk(name='RingRoad1')
        for x in range(size):
            ring_road_1.add_point(self.intersections[x][0])
        city.add_road(ring_road_1)

        ring_road_2 = Trunk(name='RingRoad2')
        for y in range(size):
            ring_road_2.add_point(self.intersections[size - 1][y])
        city.add_road(ring_road_2)

        ring_road_3 = Trunk(name='RingRoad3')
        for x in range(size):
            ring_road_3.add_point(self.intersections[size - x - 1][size - 1])
        city.add_road(ring_road_3)

        ring_road_4 = Trunk(name='RingRoad4')
        for y in range(size):
            ring_road_4.add_point(self.intersections[0][size - y - 1])
        city.add_road(ring_road_4)

    def _create_blocks(self, city, size):
        blocks_count = size - 1
        block_size = 96
        inital_offset = 50
        street_width = 4
        half_street_width = street_width / 2.0
        triangle_delta = 93

        for x in range(blocks_count):
            for y in range(blocks_count):
                if x == y:
                    origin = Point(street_width + 1 + x * self.multiplier,
                                   half_street_width + y * self.multiplier, 0)
                    vertices = [Point(0, 0, 0), Point(triangle_delta, 0, 0), Point(triangle_delta, triangle_delta, 0)]
                    block = Block(origin, vertices)
                    city.add_block(block)

                    origin = Point(half_street_width + x * self.multiplier,
                                   street_width + 1 + y * self.multiplier, 0)
                    vertices = [Point(0, 0, 0), Point(0, triangle_delta, 0), Point(triangle_delta, triangle_delta, 0)]
                    block = Block(origin, vertices)
                    city.add_block(block)
                elif x + y == blocks_count - 1:
                    origin = Point(half_street_width + x * self.multiplier,
                                   half_street_width + y * self.multiplier, 0)
                    vertices = [Point(0, 0, 0), Point(triangle_delta, 0, 0), Point(0, triangle_delta, 0)]
                    block = Block(origin, vertices)
                    city.add_block(block)

                    origin = Point((x + 1) * self.multiplier - half_street_width,
                                   street_width + 1 + y * self.multiplier, 0)
                    vertices = [Point(0, 0, 0), Point(0, triangle_delta, 0), Point(-triangle_delta, triangle_delta, 0)]
                    block = Block(origin, vertices)
                    city.add_block(block)
                else:
                    origin = Point(inital_offset + x * self.multiplier,
                                   inital_offset + y * self.multiplier, 0)
                    block = Block.square(origin, block_size)
                    city.add_block(block)

    def _create_buildings(self, city, size):
        blocks_count = size - 1
        building_spacing = 18
        for x in range(blocks_count):
            for y in range(blocks_count):
                for block_x in range(3):
                    for block_y in range(3):
                        pos = Point(x * self.multiplier + block_x * 30 + building_spacing,
                                    y * self.multiplier + block_y * 30 + building_spacing, 0)
                        if abs(pos.y - pos.x) > building_spacing and \
                           abs(pos.y + pos.x - self.multiplier * blocks_count) > building_spacing:
                            building = Building.square(pos, 20, 40)
                            city.add_building(building)
<commit_msg>Change trunks to streets in simple builder as trunks are not yet supported in monolane<commit_after>"""
Copyright (C) 2017 Open Source Robotics Foundation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://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.
"""

from geometry.point import Point

from models.city import City
from models.street import Street
from models.trunk import Trunk
from models.block import Block
from models.building import Building
from models.ground_plane import GroundPlane
from models.road import *

from builders.abstract_city_builder import AbstractCityBuilder

class SimpleCityBuilder(AbstractCityBuilder):

    def get_city(self):
        # Must be odd
        size = 5
        city = City()
        self.multiplier = 100

        self._create_ground_plane(city, size)
        self._setup_intersections(city, size)
        self._create_inner_streets(city, size)
        self._create_surrounding_ring_road(city, size)
        self._create_blocks(city, size)
        self._create_buildings(city, size)
        return city

    def _setup_intersections(self, city, size):
        self.intersections = [[Point(self.multiplier * x, self.multiplier * y, 0)
                              for y in range(size)] for x in range(size)]

        for x in range(size - 1):
            self.intersections[x][0] = self.intersections[x][0] + Point(0, -2)
        self.intersections[size - 1][0] = self.intersections[size - 1][0] + Point(2, -2)

        for y in range(1, size):
            self.intersections[size - 1][y] = self.intersections[size - 1][y] + Point(2, 0)

        for x in range(size - 1):
            self.intersections[size - x - 1][size - 1] = self.intersections[size - x - 1][size - 1] + Point(0, 2)
        self.intersections[0][size - 1] = self.intersections[0][size - 1] + Point(-2, 2)

        for y in range(1, size):
            self.intersections[0][size - y - 1] = self.intersections[0][size - y - 1] + Point(-2, 0)

        for x in range(size):
            for y in range(size):
                city.add_intersection_at(self.intersections[x][y])

    def _create_ground_plane(self, city, size):
        ground_plane_size = size * self.multiplier
        ground_plane = GroundPlane(ground_plane_size,
                                   Point(ground_plane_size / 2,
                                         ground_plane_size / 2,
                                         0),
                                   'ground_plane')
        city.set_ground_plane(ground_plane)

    def _create_inner_streets(self, city, size):

        # Vertical
        for x in range(1, size - 1):
            road = Street()
            for y in range(size):
                road.add_point(self.intersections[x][y])
            city.add_road(road)

        # Horizontal
        for y in range(1, size - 1):
            road = Street()
            for x in range(size):
                road.add_point(self.intersections[x][y])
            city.add_road(road)

        # Diagonals
        road = Street()
        for i in range(size):
            road.add_point(self.intersections[i][i])
        city.add_road(road)

        road = Street()
        for i in range(size):
            road.add_point(self.intersections[i][size - i - 1])
        city.add_road(road)

    def _create_surrounding_ring_road(self, city, size):
        ring_road_1 = Street(name='RingRoad1')
        for x in range(size):
            ring_road_1.add_point(self.intersections[x][0])
        city.add_road(ring_road_1)

        ring_road_2 = Street(name='RingRoad2')
        for y in range(size):
            ring_road_2.add_point(self.intersections[size - 1][y])
        city.add_road(ring_road_2)

        ring_road_3 = Street(name='RingRoad3')
        for x in range(size):
            ring_road_3.add_point(self.intersections[size - x - 1][size - 1])
        city.add_road(ring_road_3)

        ring_road_4 = Street(name='RingRoad4')
        for y in range(size):
            ring_road_4.add_point(self.intersections[0][size - y - 1])
        city.add_road(ring_road_4)

    def _create_blocks(self, city, size):
        blocks_count = size - 1
        block_size = 96
        inital_offset = 50
        street_width = 4
        half_street_width = street_width / 2.0
        triangle_delta = 93

        for x in range(blocks_count):
            for y in range(blocks_count):
                if x == y:
                    origin = Point(street_width + 1 + x * self.multiplier,
                                   half_street_width + y * self.multiplier, 0)
                    vertices = [Point(0, 0, 0), Point(triangle_delta, 0, 0), Point(triangle_delta, triangle_delta, 0)]
                    block = Block(origin, vertices)
                    city.add_block(block)

                    origin = Point(half_street_width + x * self.multiplier,
                                   street_width + 1 + y * self.multiplier, 0)
                    vertices = [Point(0, 0, 0), Point(0, triangle_delta, 0), Point(triangle_delta, triangle_delta, 0)]
                    block = Block(origin, vertices)
                    city.add_block(block)
                elif x + y == blocks_count - 1:
                    origin = Point(half_street_width + x * self.multiplier,
                                   half_street_width + y * self.multiplier, 0)
                    vertices = [Point(0, 0, 0), Point(triangle_delta, 0, 0), Point(0, triangle_delta, 0)]
                    block = Block(origin, vertices)
                    city.add_block(block)

                    origin = Point((x + 1) * self.multiplier - half_street_width,
                                   street_width + 1 + y * self.multiplier, 0)
                    vertices = [Point(0, 0, 0), Point(0, triangle_delta, 0), Point(-triangle_delta, triangle_delta, 0)]
                    block = Block(origin, vertices)
                    city.add_block(block)
                else:
                    origin = Point(inital_offset + x * self.multiplier,
                                   inital_offset + y * self.multiplier, 0)
                    block = Block.square(origin, block_size)
                    city.add_block(block)

    def _create_buildings(self, city, size):
        blocks_count = size - 1
        building_spacing = 18
        for x in range(blocks_count):
            for y in range(blocks_count):
                for block_x in range(3):
                    for block_y in range(3):
                        pos = Point(x * self.multiplier + block_x * 30 + building_spacing,
                                    y * self.multiplier + block_y * 30 + building_spacing, 0)
                        if abs(pos.y - pos.x) > building_spacing and \
                           abs(pos.y + pos.x - self.multiplier * blocks_count) > building_spacing:
                            building = Building.square(pos, 20, 40)
                            city.add_building(building)
<|endoftext|>


<commit_before>#!/usr/bin/env python2

"""
Base class for Rhino Journal JSON related services
"""

__author__ = 'jgray@plos.org'

from ...Base.base_service_test import BaseServiceTest
from ...Base.Config import API_BASE_URL
from ...Base.api import needs

JOURNALS_API = API_BASE_URL + '/v1/journals'
DEFAULT_HEADERS = {'Accept': 'application/json'}
HEADER = '-H'
EXPECTED_KEYS = [u'PLoSBiology', u'PLoSPathogens', u'PLoSDefault', u'PLoSMedicine', u'PLoSNTD', u'PLoSCompBiol', u'PLoSCollections', u'PLoSClinicalTrials', u'PLoSGenetics', u'PLoSONE']

class JournalCCJson(BaseServiceTest):

  def get_journals(self):
    """
    Calls Rhino API to get journal list
    :param
    :return:JSON response
    """
    header = {'header': HEADER}
    self.doGet('%s' % JOURNALS_API, header, DEFAULT_HEADERS)
    self.parse_response_as_json()

  @needs('parsed', 'parse_response_as_json()')
  def verify_journals(self):
    """
    Verifies a valid response
    :param
    :return: Journal List + OK
    """
    print ('Validating journals...'),
    #actual_journals = self.parsed.get_journals()
    #print(str(actual_journals))
    actual_keys = self.parsed.get_journalKey()
    assert actual_keys == EXPECTED_KEYS
    #print(str(actual_keys))
    print ('OK')
<commit_msg>DPRO-865 Addressed CR comments.<commit_after>#!/usr/bin/env python2

"""
Base class for Rhino Journal JSON related services
"""

__author__ = 'jgray@plos.org'

from ...Base.base_service_test import BaseServiceTest
from ...Base.Config import API_BASE_URL
from ...Base.api import needs

JOURNALS_API = API_BASE_URL + '/v1/journals'
DEFAULT_HEADERS = {'Accept': 'application/json'}
HEADER = '-H'
EXPECTED_KEYS = [u'PLoSBiology', u'PLoSPathogens', u'PLoSDefault', u'PLoSMedicine', u'PLoSNTD', u'PLoSCompBiol', u'PLoSCollections', u'PLoSClinicalTrials', u'PLoSGenetics', u'PLoSONE']

class JournalCCJson(BaseServiceTest):

  def get_journals(self):
    """
    Calls Rhino API to get journal list
    :param
    :return:JSON response
    """
    header = {'header': HEADER}
    self.doGet('%s' % JOURNALS_API, header, DEFAULT_HEADERS)
    self.parse_response_as_json()

  @needs('parsed', 'parse_response_as_json()')
  def verify_journals(self):
    """
    Verifies a valid response
    :param
    :return: Journal List + OK
    """
    print ('Validating journals...'),
    actual_keys = self.parsed.get_journalKey()
    assert actual_keys == EXPECTED_KEYS, 'Journals keys did not match: Actual Keys %s != Expected Keys %s' % (actual_keys, EXPECTED_KEYS)
    print ('OK')
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""RE pattern objects for detecting and splitting Pinyin.

Splitting pinyin into syllables is not as simple as looking for the maximum
length matches using valid syllables. Instead, lookahead/lookbehind assertions
must be used to validate possible matches. For syllables, the rough approach
used is:
    * Get the longest valid syllable.
    * If it ends in a consonant make sure it's not followed directly by a
        vowel (a hyphen or apostrophe doesn't count).
    * If the above didn't match, repeat for the next longest valid match.

Lookahead/lookbehind assertions are used to ensure that hyphens and
apostrophes are only included in words if used correctly. This helps to weed
out non-Pinyin strings.

"""

from __future__ import unicode_literals
from string import whitespace

vowels = (
    'aɑeiouüvAEIOUÜV'
    'āɑ̄ēīōūǖĀĒĪŌŪǕ'
    'áɑ́éíóúǘÁÉÍÓÚǗ'
    'ǎɑ̌ěǐǒǔǚǍĚǏǑǓǙ'
    'àɑ̀èìòùǜÀÈÌÒÙǛ'
)
consonants = 'bpmfdtnlgkhjqxzcsrzcswyBPMFDTNLGKHJQXZCSRZCSWY'
marks = "·012345:-'"
non_stops = """"#$%&'()*+,-/:;<=>@[\]^_`{|}~"""
stops = '.!?'
punctuation = non_stops + stops
printable = vowels + consonants + marks[:-3] + whitespace + punctuation

_a = 'a\u0101\u00E0\u00E1\u01CE'
_e = 'e\u0113\u00E9\u011B\u00E8'
_i = 'i\u012B\u00ED\u01D0\u00EC'
_o = 'o\u014D\u00F3\u01D2\u00F2'
_u = 'u\u016B\u00FA\u01D4\u00F9'
_v = 'v\u00FC\u01D6\u01D8\u01DA\u01DC'
_a_vowels = {'a': _a, 'e': _e, 'i': _i, 'o': _o, 'u': _u, 'v': _v}
_n_vowels = {'a': 'a', 'e': 'e', 'i': 'i', 'o': 'o', 'u': 'u', 'v': 'v\u00FC'}

def _build_syl(vowels, tone_numbers=False):
    # This is the end-of-syllable-consonant lookahead assertion.
    consonant_end = '(?![%(a)s%(e)s%(i)s%(o)s%(u)s%(v)s]|u:)' % {
        'a': _a, 'e': _e, 'i': _i, 'o': _o, 'u': _u, 'v': _v
    }
    _vowels = vowels.copy()
    for v, s in _vowels.items():
        if len(s) > 1:
            _vowels[v] = '[%s]' % s
    return (
        '(?:\u00B7|\u2027)?'
        '(?:'
        '(?:(?:[zcs]h|[gkh])u%(a)sng%(consonant_end)s)|'
        '(?:[jqx]i%(o)sng%(consonant_end)s)|'
        '(?:[nljqx]i%(a)sng%(consonant_end)s)|'
        '(?:(?:[zcs]h?|[dtnlgkhrjqxy])u%(a)sn%(consonant_end)s)|'
        '(?:(?:[zcs]h|[gkh])u%(a)si)|'
        '(?:(?:[zc]h?|[rdtnlgkhsy])%(o)sng%(consonant_end)s)|'
        '(?:(?:[zcs]h?|[rbpmfdtnlgkhw])?%(e)sng%(consonant_end)s)|'
        '(?:(?:[zcs]h?|[rbpmfdtnlgkhwy])?%(a)sng%(consonant_end)s)|'
        '(?:[bpmdtnljqxy]%(i)sng%(consonant_end)s)|'
        '(?:[bpmdtnljqx]i%(a)sn%(consonant_end)s)|'
        '(?:[bpmdtnljqx]i%(a)so)|'
        '(?:[nl](?:v|u:|\u00FC)%(e)s)|'
        '(?:[nl](?:%(v)s|u:))|'
        '(?:[jqxy]u%(e)s)|'
        '(?:[bpmnljqxy]%(i)sn%(consonant_end)s)|'
        '(?:[mdnljqx]i%(u)s)|'
        '(?:[bpmdtnljqx]i%(e)s)|'
        '(?:[dljqx]i%(a)s)|'
        '(?:(?:[zcs]h?|[rdtnlgkhxqjy])%(u)sn%(consonant_end)s)|'
        '(?:(?:[zcs]h?|[rdtgkh])u%(i)s)|'
        '(?:(?:[zcs]h?|[rdtnlgkh])u%(o)s)|'
        '(?:(?:[zcs]h|[rgkh])u%(a)s)|'
        '(?:(?:[zcs]h?|[rbpmfdngkhw])?%(e)sn%(consonant_end)s)|'
        '(?:(?:[zcs]h?|[rbpmfdtnlgkhwy])?%(a)sn%(consonant_end)s)|'
        '(?:(?:[zcs]h?|[rpmfdtnlgkhy])?%(o)su)|'
        '(?:(?:[zcs]h?|[rbpmdtnlgkhy])?%(a)so)|'
        '(?:(?:[zs]h|[bpmfdtnlgkhwz])?%(e)si)|'
        '(?:(?:[zcs]h?|[bpmdtnlgkhw])?%(a)si)|'
        '(?:(?:[zcs]h?|[rjqxybpmdtnl])%(i)s)|'
        '(?:(?:[zcs]h?|[rwbpmfdtnlgkhjqxwy])%(u)s)|'
        '(?:(?:[zcs]h?|[rmdtnlgkhy])?%(e)s)|'
        '(?:[bpmfwyl]?%(o)s)|'
        '(?:(?:[zcs]h|[bpmfdtnlgkhzcswy])?%(a)s)'
        ')(?:r%(consonant_end)s)?' + ('[0-5]?' if tone_numbers else '')
    ) % {
        'consonant_end': consonant_end, 'a': _vowels['a'], 'e': _vowels['e'],
        'i': _vowels['i'], 'o': _vowels['o'], 'u': _vowels['u'],
        'v': _vowels['v']
    }

def _build_word(syl, vowels):
    return (
        "(?:%(syl)s(?:-(?=%(syl)s)|'(?=[%(a)s%(e)s%(o)s])(?=%(syl)s))?)+"
    ) % {'syl': syl, 'a': vowels['a'], 'e': vowels['e'], 'o': vowels['o']}

def _build_sentence(word):
    return (
        """(?:%(word)s|[%(non_stops)s\s])+[%(stops)s]['"\]\}\)]*"""
    ) % {'word': word, 'non_stops': non_stops, 'stops': stops}

a_syl = acc_syl = accented_syllable = _build_syl(_a_vowels, tone_numbers=False)
n_syl = num_syl = numbered_syllable = _build_syl(_n_vowels, tone_numbers=True)
syl = syllable = _build_syl(_a_vowels, tone_numbers=True)

a_word = acc_word = accented_word = _build_word(a_syl, _a_vowels)
n_word = num_word = numbered_word = _build_word(n_syl, _n_vowels)
word = _build_word(syl, _a_vowels)

a_sent = acc_sent = accented_sentence = _build_sentence(a_word)
n_sent = num_sent = numbered_sentence = _build_sentence(n_word)
sent = sentence = _build_sentence(word)
<commit_msg>Adds comments to Pinyin _build_* functions.<commit_after># -*- coding: utf-8 -*-
"""RE pattern objects for detecting and splitting Pinyin.

Splitting pinyin into syllables is not as simple as looking for the maximum
length matches using valid syllables. Instead, lookahead/lookbehind assertions
must be used to validate possible matches. For syllables, the rough approach
used is:
    * Get the longest valid syllable.
    * If it ends in a consonant make sure it's not followed directly by a
        vowel (a hyphen or apostrophe doesn't count).
    * If the above didn't match, repeat for the next longest valid match.

Lookahead/lookbehind assertions are used to ensure that hyphens and
apostrophes are only included in words if used correctly. This helps to weed
out non-Pinyin strings.

"""

from __future__ import unicode_literals
from string import whitespace

vowels = (
    'aɑeiouüvAEIOUÜV'
    'āɑ̄ēīōūǖĀĒĪŌŪǕ'
    'áɑ́éíóúǘÁÉÍÓÚǗ'
    'ǎɑ̌ěǐǒǔǚǍĚǏǑǓǙ'
    'àɑ̀èìòùǜÀÈÌÒÙǛ'
)
consonants = 'bpmfdtnlgkhjqxzcsrzcswyBPMFDTNLGKHJQXZCSRZCSWY'
marks = "·012345:-'"
non_stops = """"#$%&'()*+,-/:;<=>@[\]^_`{|}~"""
stops = '.!?'
punctuation = non_stops + stops
printable = vowels + consonants + marks[:-3] + whitespace + punctuation

_a = 'a\u0101\u00E0\u00E1\u01CE'
_e = 'e\u0113\u00E9\u011B\u00E8'
_i = 'i\u012B\u00ED\u01D0\u00EC'
_o = 'o\u014D\u00F3\u01D2\u00F2'
_u = 'u\u016B\u00FA\u01D4\u00F9'
_v = 'v\u00FC\u01D6\u01D8\u01DA\u01DC'
_a_vowels = {'a': _a, 'e': _e, 'i': _i, 'o': _o, 'u': _u, 'v': _v}
_n_vowels = {'a': 'a', 'e': 'e', 'i': 'i', 'o': 'o', 'u': 'u', 'v': 'v\u00FC'}

def _build_syl(vowels, tone_numbers=False):
    """Builds a Pinyin syllable re pattern.

    Syllables can be preceded by a middle dot (tone mark). Syllables that end
    in a consonant are only valid if they aren't followed directly by a vowel
    with no apostrophe in between.

    """
    # This is the end-of-syllable-consonant lookahead assertion.
    consonant_end = '(?![%(a)s%(e)s%(i)s%(o)s%(u)s%(v)s]|u:)' % {
        'a': _a, 'e': _e, 'i': _i, 'o': _o, 'u': _u, 'v': _v
    }
    _vowels = vowels.copy()
    for v, s in _vowels.items():
        if len(s) > 1:
            _vowels[v] = '[%s]' % s
    return (
        '(?:\u00B7|\u2027)?'
        '(?:'
        '(?:(?:[zcs]h|[gkh])u%(a)sng%(consonant_end)s)|'
        '(?:[jqx]i%(o)sng%(consonant_end)s)|'
        '(?:[nljqx]i%(a)sng%(consonant_end)s)|'
        '(?:(?:[zcs]h?|[dtnlgkhrjqxy])u%(a)sn%(consonant_end)s)|'
        '(?:(?:[zcs]h|[gkh])u%(a)si)|'
        '(?:(?:[zc]h?|[rdtnlgkhsy])%(o)sng%(consonant_end)s)|'
        '(?:(?:[zcs]h?|[rbpmfdtnlgkhw])?%(e)sng%(consonant_end)s)|'
        '(?:(?:[zcs]h?|[rbpmfdtnlgkhwy])?%(a)sng%(consonant_end)s)|'
        '(?:[bpmdtnljqxy]%(i)sng%(consonant_end)s)|'
        '(?:[bpmdtnljqx]i%(a)sn%(consonant_end)s)|'
        '(?:[bpmdtnljqx]i%(a)so)|'
        '(?:[nl](?:v|u:|\u00FC)%(e)s)|'
        '(?:[nl](?:%(v)s|u:))|'
        '(?:[jqxy]u%(e)s)|'
        '(?:[bpmnljqxy]%(i)sn%(consonant_end)s)|'
        '(?:[mdnljqx]i%(u)s)|'
        '(?:[bpmdtnljqx]i%(e)s)|'
        '(?:[dljqx]i%(a)s)|'
        '(?:(?:[zcs]h?|[rdtnlgkhxqjy])%(u)sn%(consonant_end)s)|'
        '(?:(?:[zcs]h?|[rdtgkh])u%(i)s)|'
        '(?:(?:[zcs]h?|[rdtnlgkh])u%(o)s)|'
        '(?:(?:[zcs]h|[rgkh])u%(a)s)|'
        '(?:(?:[zcs]h?|[rbpmfdngkhw])?%(e)sn%(consonant_end)s)|'
        '(?:(?:[zcs]h?|[rbpmfdtnlgkhwy])?%(a)sn%(consonant_end)s)|'
        '(?:(?:[zcs]h?|[rpmfdtnlgkhy])?%(o)su)|'
        '(?:(?:[zcs]h?|[rbpmdtnlgkhy])?%(a)so)|'
        '(?:(?:[zs]h|[bpmfdtnlgkhwz])?%(e)si)|'
        '(?:(?:[zcs]h?|[bpmdtnlgkhw])?%(a)si)|'
        '(?:(?:[zcs]h?|[rjqxybpmdtnl])%(i)s)|'
        '(?:(?:[zcs]h?|[rwbpmfdtnlgkhjqxwy])%(u)s)|'
        '(?:(?:[zcs]h?|[rmdtnlgkhy])?%(e)s)|'
        '(?:[bpmfwyl]?%(o)s)|'
        '(?:(?:[zcs]h|[bpmfdtnlgkhzcswy])?%(a)s)'
        ')(?:r%(consonant_end)s)?' + ('[0-5]?' if tone_numbers else '')
    ) % {
        'consonant_end': consonant_end, 'a': _vowels['a'], 'e': _vowels['e'],
        'i': _vowels['i'], 'o': _vowels['o'], 'u': _vowels['u'],
        'v': _vowels['v']
    }

def _build_word(syl, vowels):
    """Builds a Pinyin word re pattern from a Pinyin syllable re pattern.

    A word is defined as a series of consecutive valid Pinyin syllables
    with optional hyphens and apostrophes interspersed. Hyphens must be
    followed immediately by another valid Pinyin syllable. Apostrophes must be
    followed by another valid Pinyin syllable that starts with an 'a', 'e', or
    'o'.

    """
    return (
        "(?:%(syl)s(?:-(?=%(syl)s)|'(?=[%(a)s%(e)s%(o)s])(?=%(syl)s))?)+"
    ) % {'syl': syl, 'a': vowels['a'], 'e': vowels['e'], 'o': vowels['o']}

def _build_sentence(word):
    """Builds a Pinyin sentence re pattern from a Pinyin word re pattern.

    A sentence is defined as a series of valid Pinyin words, punctuation
    (non-stops), and spaces followed by a single stop and zero or more
    end-container punctuation marks.

    """
    return (
        """(?:%(word)s|[%(non_stops)s\s])+[%(stops)s]['"\]\}\)]*"""
    ) % {'word': word, 'non_stops': non_stops, 'stops': stops}

a_syl = acc_syl = accented_syllable = _build_syl(_a_vowels, tone_numbers=False)
n_syl = num_syl = numbered_syllable = _build_syl(_n_vowels, tone_numbers=True)
syl = syllable = _build_syl(_a_vowels, tone_numbers=True)

a_word = acc_word = accented_word = _build_word(a_syl, _a_vowels)
n_word = num_word = numbered_word = _build_word(n_syl, _n_vowels)
word = _build_word(syl, _a_vowels)

a_sent = acc_sent = accented_sentence = _build_sentence(a_word)
n_sent = num_sent = numbered_sentence = _build_sentence(n_word)
sent = sentence = _build_sentence(word)
<|endoftext|>


<commit_before>from zinc_request_processor import ZincRequestProcessor
import sys
import json

WELCOME_BANNER = """
 ____      ____             __
|_  _|    |_  _|           [  |
  \ \  /\  / /.---.  .---.  | |  .--.   _ .--..--.  .---.
   \ \/  \/ // /__\\/ /'`\] | |/ .'`\ \[ `.-. .-. |/ /__\\
    \  /\  / | \__.,| \__.  | || \__. | | | | | | || \__.,
     \/  \/   '.__.''.___.'[___]'.__.' [___||__||__]'.__.'

                     _________
                    |  _   _  |
                    |_/ | | \_|.--.
                        | |  / .'`\ \
                       _| |_ | \__. |
                      |_____| '.__.'

            ________   _                   _
           |  __   _| (_)                 | |
           |_/  / /   __   _ .--.   .---. | |
              .'.' _ [  | [ `.-. | / /'`\]| |
            _/ /__/ | | |  | | | | | \__. |_|
           |________|[___][___||__]'.___.'(_)
"""

class ValidationHelpers(object):
    @classmethod
    def validate_number(klass, maximum, minimum=0):
        def validate(x):
            if (int(x) <= maximum and int(x) >= minimum):
                return True
            else:
                print "You must enter a number between %s and %s\n" % (minimum, maximum)
        return validate

    @classmethod
    def validate_boolean(klass):
        def validate(x):
            if (x == "y" or x == "n"):
                return True
            else:
                print "You must enter either 'y' or 'n'"
        return validate

class ZincWizard(object):
    PROMPTS = {
        "product_variants": WELCOME_BANNER + "\nPlease please enter a product URL.",
        "product_quantity": "How many would you like to purchase? (Default: 1)",
        "select_product_variants": "This item comes in multiple variants. Please choose an option.",
        "select_shipping_methods": "This item has multiple shipping options. Please choose an option.",
        "security_code": "Please enter the CVV security code on your credit card.",
        "place_order": "Would you like to place this order? (y)/n",
        "gift": "Do you want this to be shipped as a gift? (y)/n",
        "shipping_address": {
            "start_message": "\nNow we'd like to get your shipping information.",
            "end_message": "\nYou've finished entering your shipping address!"
            },
        "address": {
            "first_name": "Please input your first name:",
            "last_name": "Please input your last name:",
            "address_line1": "Please input the first line of your shipping address:",
            "address_line2": "Please input the second line of your shipping address: (optional)",
            "city": "Please input your city:",
            "state": "Please input your state (e.g. CA, MA, etc.):",
            "zip_code": "Please input your zip code:",
            "country": "Please input your country (e.g. US):",
            "confirmation_message": "Is this your correct shipping address? (y)/n"
            },
        "billing_address" : {
            "start_message": "\nIs your billing address the same as your shipping address? (y)/n",
            "end_message": "\nYou've finished entering you billing address!"
            },
        "credit_card": {
            "start_message": "\nNow we'd like to get your credit card information.",
            "number": "Please input your credit card number",
            "expiration_month": "Please input your credit card expiration month (e.g. 03)",
            "expiration_year": "Please input your credit card expiration year (e.g. 2017)",
            "security_code": "Please input the CVV security code from your credit card",
            "end_message": "\nYou've finished entering your credit card information!"
            }
        }

    def __init__(self, options = None):
        self.options = (options if options is not None else {})
        self.response_data = {}
        self.security_code = None

    def start(self):
        self.get_product_variants(self.response_data)
        self.get_shipping_methods(self.response_data)
        self.get_store_card(self.response_data)
        self.get_review_order(self.response_data)
        self.get_place_order(self.response_data)

    def prompt(self, prompt, validation=None, max_attempts=3):
        attempts = 0
        while True:
            raw = raw_input(prompt + "\n")
            if (validation == None) or (validation != None and validation(raw)):
                return raw
            else:
                attempts += 1
                if attempts >= max_attempts:
                    print "You've reached the maximum number of attempts. Exiting!"
                    sys.exit()

    def prompt_boolean(self, prompt):
        result = self.prompt(prompt, ValidationHelpers.validate_boolean()).strip()
        if (result == "y" or result == ""):
            return True
        return False

    def get_product_variants(self, response_data):
        if "product_url" in self.options:
            product_url = self.options["product_url"]
        else:
            product_url = self.prompt(self.PROMPTS["product_variants"])

        print "\nProcessing request...\n"
        variants_response = ZincRequestProcessor.process("variant_options", {
                    "client_token": self.options["client_token"],
                    "retailer": self.options["retailer"],
                    "product_url": product_url
                    })
        response_data["variant_options_response"] = variants_response
        response_data["products"] = self.select_product_variants(variants_response)

    def get_shipping_methods(self, response_data):
        shipping_address = self.load_file_contents("shipping_address")
        print "\nProcessing request...\n"
        shipping_response = ZincRequestProcessor.process("shipping_methods", {
                    "client_token": self.options["client_token"],
                    "retailer": self.options["retailer"],
                    "products": response_data["products"],
                    "shipping_address": shipping_address
                })

        response_data["shipping_response"] = shipping_response
        response_data["shipping_address"] = shipping_address
        response_data["shipping_method_id"] = self.select_shipping_methods(shipping_response)

    def get_store_card(self, response_data):
        if "cc_token" in self.options and self.options["cc_token"] != None:
            response_data["cc_token"] = self.options["cc_token"]
        else:
            cc_data = self.load_file_contents("credit_card")
            print "\nProcessing request...\n"
            store_card_response = ZincRequestProcessor.process("store_card", {
                        "client_token": self.options["client_token"],
                        "retailer": self.options["retailer"],
                        "billing_address": self.load_file_contents("billing_address"),
                        "number": cc_data["number"],
                        "expiration_month": cc_data["expiration_month"],
                        "expiration_year": cc_data["expiration_year"]
                    })

            response_data["store_card_response"] = store_card_response
            response_data["cc_token"] = store_card_response["cc_token"]

    def get_review_order(self, response_data):
        payment_method = {
                "cc_token": response_data["cc_token"],
                "security_code": self.get_security_code()
                }
        print "\nProcessing request...\n"
        review_order_response = ZincRequestProcessor.process("review_order", {
                    "client_token": self.options["client_token"],
                    "retailer": self.options["retailer"],
                    "products": response_data["products"],
                    "shipping_address": response_data["shipping_address"],
                    "is_gift": self.get_is_gift(),
                    "shipping_method_id": response_data["shipping_method_id"],
                    "payment_method": payment_method,
                    "customer_email": "support@zinc.io"
                })

        response_data["review_order_response"] = review_order_response

    def get_place_order(self, response_data):
        self.print_price_components(response_data)
        if self.prompt_boolean(self.PROMPTS["place_order"]):
            print "\nProcessing request...\n"
            place_order_resonse = ZincRequestProcessor.process("place_order", {
                        "client_token": self.options["client_token"],
                        "place_order_key": response_data["review_order_response"]["place_order_key"]
                    })

            response_data["place_order_response"] = place_order_response
            print "HOORAY! You've successfully placed an order. Here are the details:\n"
            print "Amazon Order Id: %s" % place_order_response["merchant_order"]["merchant_order_id"]
            print "Total Price: %s" % place_order_response["price_components"]["total"]
            print place_order_response["shipping_method"]["name"] + ": " + place_order_response["shipping_method"]["description"]

    def print_price_components(self, response_data):
        components = response_data["review_order_response"]["price_components"]
        self.print_indent("Product Subtotal: %s" % self.format_price(components["subtotal"]))
        self.print_indent("Shipping Cost:    %s" % self.format_price(components["shipping"]))
        self.print_indent("Tax:              %s" % self.format_price(components["tax"]))
        if "gift_card" in components:
            self.print_indent("Gift Card:        %s" % self.format_price(components["gift_card"]))
        self.print_indent("Total:            %s" % self.format_price(components["total"]))

    def print_indent(self, value):
        print "    ", value

    def get_is_gift(self):
        if "gift" in self.options:
            return self.options["gift"]
        return self.prompt_boolean(self.PROMPTS["gift"])

    def get_security_code(self):
        if self.security_code != None:
            return self.security_code
        return self.prompt(self.PROMPTS["security_code"])

    def load_file_contents(self, filetype):
        if filetype in self.options and self.options[filetype] != None:
            with open(self.options[filetype], 'rb') as f:
                return json.loads(f.read())
        elif filetype == "shipping_address":
            print self.PROMPTS[filetype]["start_message"]
            return self.get_address(filetype)
        elif filetype == "billing_address":
            if self.prompt_boolean(self.PROMPTS[filetype]["start_message"]):
                return self.response_data["shipping_address"]
            else:
                return self.get_address(filetype)
        elif filetype == "credit_card":
            return self.get_credit_card_information()

    def get_credit_card_information(self):
        print self.PROMPTS["credit_card"]["start_message"]
        response = {}
        response["number"] = self.prompt(self.PROMPTS["credit_card"]["number"])
        response["expiration_month"] = self.prompt(self.PROMPTS["credit_card"]["expiration_month"])
        response["expiration_year"] = self.prompt(self.PROMPTS["credit_card"]["expiration_year"])
        self.security_code = self.prompt(self.PROMPTS["credit_card"]["security_code"])
        print self.PROMPTS["credit_card"]["end_message"]
        return response

    def get_address(self, filetype):
        address = {}
        for label in ["first_name", "last_name", "address_line1", "address_line2",
                "city", "state", "zip_code", "country"]:
            address[label] = self.prompt(self.PROMPTS["address"][label])

        print "\nYou typed the following:\n"
        self.print_indent("    %s %s" % (address["first_name"], address["last_name"]))
        self.print_indent("    %s" % (address["address_line1"]))
        self.print_indent("    %s" % (address["address_line2"]))
        self.print_indent("    %s, %s %s" % (address["city"], address["state"], address["zip_code"]))
        self.print_indent("    %s" % (address["country"]))
        print ""

        if self.prompt_boolean(self.PROMPTS["address"]["confirmation_message"]):
            print self.PROMPTS[filetype]["end_message"]
            return address
        else:
            self.get_address(filetype)

    def build_prompt(self, base_prompt, description_list):
        prompt = base_prompt + "\n"
        prompt += "\n".join(description_list)
        return prompt

    def select_product_variants(self, variants_response):
        descriptions = []
        product_ids = []
        if (len(variants_response["variant_options"]) > 1):
            for i in xrange(len(variants_response["variant_options"])):
                current_descriptions_list = []
                current_option = variants_response["variant_options"][i]
                for dimension in current_option["dimensions"]:
                    current_descriptions_list.append(dimension["name"] + ": " + dimension["value"])
                if "unit_price" in current_option:
                    current_descriptions_list.append("Price: " + self.format_price(current_option["unit_price"]))
                product_ids.append(current_option["product_id"])
                descriptions.append(str(i) + ") " + ", ".join(current_descriptions_list))

            prompt = self.build_prompt(self.PROMPTS["select_product_variants"], descriptions)

            description_number = self.prompt(prompt,
                    ValidationHelpers.validate_number(len(descriptions)))
            chosen_product_id = product_ids[int(description_number)]
        else:
            chosen_product_id = variants_response["variant_options"][0]["product_id"]

        quantity = self.get_quantity()
        return [{
                "product_id": chosen_product_id,
                "quantity": quantity
                }]

    def format_price(self, price):
        if len(price) > 2:
            return "$" + price[:(-2)] + "." + price[(-2):]
        elif len(price) == 2:
            return "$0." + price
        elif len(price) == 1:
            return "$0.0" + price

    def get_quantity(self):
        quantity = self.prompt(self.PROMPTS["product_quantity"]).strip()
        if quantity == "":
            return 1
        else:
            return quantity

    def select_shipping_methods(self, shipping_response):
        descriptions = []
        shipping_ids = []
        for i in xrange(len(shipping_response["shipping_methods"])):
            current_method = shipping_response["shipping_methods"][i]
            descriptions.append(str(i) + ") " + current_method["name"] + \
                    ": " + current_method["description"])
            shipping_ids.append(current_method["shipping_method_id"])

        prompt = self.build_prompt(self.PROMPTS["select_shipping_methods"], descriptions)
        description_number = self.prompt(prompt,
                ValidationHelpers.validate_number(len(descriptions)))
        chosen_id = shipping_ids[int(description_number)]
        return chosen_id

if __name__ == '__main__':
    ZincWizard({'retailer': 'amazon',
        'client_token': 'public',
        #'shipping_address': "examples/shipping_address.json",
        #'billing_address': "examples/shipping_address.json",
        #'credit_card': "examples/credit_card.json"
        }).start()
<commit_msg>Use string when formatting price.<commit_after>from zinc_request_processor import ZincRequestProcessor
import sys
import json

WELCOME_BANNER = """
 ____      ____             __
|_  _|    |_  _|           [  |
  \ \  /\  / /.---.  .---.  | |  .--.   _ .--..--.  .---.
   \ \/  \/ // /__\\/ /'`\] | |/ .'`\ \[ `.-. .-. |/ /__\\
    \  /\  / | \__.,| \__.  | || \__. | | | | | | || \__.,
     \/  \/   '.__.''.___.'[___]'.__.' [___||__||__]'.__.'

                     _________
                    |  _   _  |
                    |_/ | | \_|.--.
                        | |  / .'`\ \
                       _| |_ | \__. |
                      |_____| '.__.'

            ________   _                   _
           |  __   _| (_)                 | |
           |_/  / /   __   _ .--.   .---. | |
              .'.' _ [  | [ `.-. | / /'`\]| |
            _/ /__/ | | |  | | | | | \__. |_|
           |________|[___][___||__]'.___.'(_)
"""

class ValidationHelpers(object):
    @classmethod
    def validate_number(klass, maximum, minimum=0):
        def validate(x):
            if (int(x) <= maximum and int(x) >= minimum):
                return True
            else:
                print "You must enter a number between %s and %s\n" % (minimum, maximum)
        return validate

    @classmethod
    def validate_boolean(klass):
        def validate(x):
            if (x == "y" or x == "n"):
                return True
            else:
                print "You must enter either 'y' or 'n'"
        return validate

class ZincWizard(object):
    PROMPTS = {
        "product_variants": WELCOME_BANNER + "\nPlease please enter a product URL.",
        "product_quantity": "How many would you like to purchase? (Default: 1)",
        "select_product_variants": "This item comes in multiple variants. Please choose an option.",
        "select_shipping_methods": "This item has multiple shipping options. Please choose an option.",
        "security_code": "Please enter the CVV security code on your credit card.",
        "place_order": "Would you like to place this order? (y)/n",
        "gift": "Do you want this to be shipped as a gift? (y)/n",
        "shipping_address": {
            "start_message": "\nNow we'd like to get your shipping information.",
            "end_message": "\nYou've finished entering your shipping address!"
            },
        "address": {
            "first_name": "Please input your first name:",
            "last_name": "Please input your last name:",
            "address_line1": "Please input the first line of your shipping address:",
            "address_line2": "Please input the second line of your shipping address: (optional)",
            "city": "Please input your city:",
            "state": "Please input your state (e.g. CA, MA, etc.):",
            "zip_code": "Please input your zip code:",
            "country": "Please input your country (e.g. US):",
            "confirmation_message": "Is this your correct shipping address? (y)/n"
            },
        "billing_address" : {
            "start_message": "\nIs your billing address the same as your shipping address? (y)/n",
            "end_message": "\nYou've finished entering you billing address!"
            },
        "credit_card": {
            "start_message": "\nNow we'd like to get your credit card information.",
            "number": "Please input your credit card number",
            "expiration_month": "Please input your credit card expiration month (e.g. 03)",
            "expiration_year": "Please input your credit card expiration year (e.g. 2017)",
            "security_code": "Please input the CVV security code from your credit card",
            "end_message": "\nYou've finished entering your credit card information!"
            }
        }

    def __init__(self, options = None):
        self.options = (options if options is not None else {})
        self.response_data = {}
        self.security_code = None

    def start(self):
        self.get_product_variants(self.response_data)
        self.get_shipping_methods(self.response_data)
        self.get_store_card(self.response_data)
        self.get_review_order(self.response_data)
        self.get_place_order(self.response_data)

    def prompt(self, prompt, validation=None, max_attempts=3):
        attempts = 0
        while True:
            raw = raw_input(prompt + "\n")
            if (validation == None) or (validation != None and validation(raw)):
                return raw
            else:
                attempts += 1
                if attempts >= max_attempts:
                    print "You've reached the maximum number of attempts. Exiting!"
                    sys.exit()

    def prompt_boolean(self, prompt):
        result = self.prompt(prompt, ValidationHelpers.validate_boolean()).strip()
        if (result == "y" or result == ""):
            return True
        return False

    def get_product_variants(self, response_data):
        if "product_url" in self.options:
            product_url = self.options["product_url"]
        else:
            product_url = self.prompt(self.PROMPTS["product_variants"])

        print "\nProcessing request...\n"
        variants_response = ZincRequestProcessor.process("variant_options", {
                    "client_token": self.options["client_token"],
                    "retailer": self.options["retailer"],
                    "product_url": product_url
                    })
        response_data["variant_options_response"] = variants_response
        response_data["products"] = self.select_product_variants(variants_response)

    def get_shipping_methods(self, response_data):
        shipping_address = self.load_file_contents("shipping_address")
        print "\nProcessing request...\n"
        shipping_response = ZincRequestProcessor.process("shipping_methods", {
                    "client_token": self.options["client_token"],
                    "retailer": self.options["retailer"],
                    "products": response_data["products"],
                    "shipping_address": shipping_address
                })

        response_data["shipping_response"] = shipping_response
        response_data["shipping_address"] = shipping_address
        response_data["shipping_method_id"] = self.select_shipping_methods(shipping_response)

    def get_store_card(self, response_data):
        if "cc_token" in self.options and self.options["cc_token"] != None:
            response_data["cc_token"] = self.options["cc_token"]
        else:
            cc_data = self.load_file_contents("credit_card")
            print "\nProcessing request...\n"
            store_card_response = ZincRequestProcessor.process("store_card", {
                        "client_token": self.options["client_token"],
                        "retailer": self.options["retailer"],
                        "billing_address": self.load_file_contents("billing_address"),
                        "number": cc_data["number"],
                        "expiration_month": cc_data["expiration_month"],
                        "expiration_year": cc_data["expiration_year"]
                    })

            response_data["store_card_response"] = store_card_response
            response_data["cc_token"] = store_card_response["cc_token"]

    def get_review_order(self, response_data):
        payment_method = {
                "cc_token": response_data["cc_token"],
                "security_code": self.get_security_code()
                }
        is_gift = self.get_is_gift()
        print "\nProcessing request...\n"
        review_order_response = ZincRequestProcessor.process("review_order", {
                    "client_token": self.options["client_token"],
                    "retailer": self.options["retailer"],
                    "products": response_data["products"],
                    "shipping_address": response_data["shipping_address"],
                    "is_gift": is_gift,
                    "shipping_method_id": response_data["shipping_method_id"],
                    "payment_method": payment_method,
                    "customer_email": "support@zinc.io"
                })

        response_data["review_order_response"] = review_order_response

    def get_place_order(self, response_data):
        self.print_price_components(response_data)
        if self.prompt_boolean(self.PROMPTS["place_order"]):
            print "\nProcessing request...\n"
            place_order_resonse = ZincRequestProcessor.process("place_order", {
                        "client_token": self.options["client_token"],
                        "place_order_key": response_data["review_order_response"]["place_order_key"]
                    })

            response_data["place_order_response"] = place_order_response
            print "HOORAY! You've successfully placed an order. Here are the details:\n"
            print "Amazon Order Id: %s" % place_order_response["merchant_order"]["merchant_order_id"]
            print "Total Price: %s" % place_order_response["price_components"]["total"]
            print place_order_response["shipping_method"]["name"] + ": " + place_order_response["shipping_method"]["description"]

    def print_price_components(self, response_data):
        components = response_data["review_order_response"]["price_components"]
        self.print_indent("Product Subtotal: %s" % self.format_price(components["subtotal"]))
        self.print_indent("Shipping Cost:    %s" % self.format_price(components["shipping"]))
        self.print_indent("Tax:              %s" % self.format_price(components["tax"]))
        if "gift_card" in components:
            self.print_indent("Gift Card:        %s" % self.format_price(components["gift_card"]))
        self.print_indent("Total:            %s" % self.format_price(components["total"]))

    def print_indent(self, value):
        print "    ", value

    def get_is_gift(self):
        if "gift" in self.options:
            return self.options["gift"]
        return self.prompt_boolean(self.PROMPTS["gift"])

    def get_security_code(self):
        if self.security_code != None:
            return self.security_code
        return self.prompt(self.PROMPTS["security_code"])

    def load_file_contents(self, filetype):
        if filetype in self.options and self.options[filetype] != None:
            with open(self.options[filetype], 'rb') as f:
                return json.loads(f.read())
        elif filetype == "shipping_address":
            print self.PROMPTS[filetype]["start_message"]
            return self.get_address(filetype)
        elif filetype == "billing_address":
            if self.prompt_boolean(self.PROMPTS[filetype]["start_message"]):
                return self.response_data["shipping_address"]
            else:
                return self.get_address(filetype)
        elif filetype == "credit_card":
            return self.get_credit_card_information()

    def get_credit_card_information(self):
        print self.PROMPTS["credit_card"]["start_message"]
        response = {}
        response["number"] = self.prompt(self.PROMPTS["credit_card"]["number"])
        response["expiration_month"] = self.prompt(self.PROMPTS["credit_card"]["expiration_month"])
        response["expiration_year"] = self.prompt(self.PROMPTS["credit_card"]["expiration_year"])
        self.security_code = self.prompt(self.PROMPTS["credit_card"]["security_code"])
        print self.PROMPTS["credit_card"]["end_message"]
        return response

    def get_address(self, filetype):
        address = {}
        for label in ["first_name", "last_name", "address_line1", "address_line2",
                "city", "state", "zip_code", "country"]:
            address[label] = self.prompt(self.PROMPTS["address"][label])

        print "\nYou typed the following:\n"
        self.print_indent("    %s %s" % (address["first_name"], address["last_name"]))
        self.print_indent("    %s" % (address["address_line1"]))
        self.print_indent("    %s" % (address["address_line2"]))
        self.print_indent("    %s, %s %s" % (address["city"], address["state"], address["zip_code"]))
        self.print_indent("    %s" % (address["country"]))
        print ""

        if self.prompt_boolean(self.PROMPTS["address"]["confirmation_message"]):
            print self.PROMPTS[filetype]["end_message"]
            return address
        else:
            self.get_address(filetype)

    def build_prompt(self, base_prompt, description_list):
        prompt = base_prompt + "\n"
        prompt += "\n".join(description_list)
        return prompt

    def select_product_variants(self, variants_response):
        descriptions = []
        product_ids = []
        if (len(variants_response["variant_options"]) > 1):
            for i in xrange(len(variants_response["variant_options"])):
                current_descriptions_list = []
                current_option = variants_response["variant_options"][i]
                for dimension in current_option["dimensions"]:
                    current_descriptions_list.append(dimension["name"] + ": " + dimension["value"])
                if "unit_price" in current_option:
                    current_descriptions_list.append("Price: " + self.format_price(current_option["unit_price"]))
                product_ids.append(current_option["product_id"])
                descriptions.append(str(i) + ") " + ", ".join(current_descriptions_list))

            prompt = self.build_prompt(self.PROMPTS["select_product_variants"], descriptions)

            description_number = self.prompt(prompt,
                    ValidationHelpers.validate_number(len(descriptions)))
            chosen_product_id = product_ids[int(description_number)]
        else:
            chosen_product_id = variants_response["variant_options"][0]["product_id"]

        quantity = self.get_quantity()
        return [{
                "product_id": chosen_product_id,
                "quantity": quantity
                }]

    def format_price(self, price):
        price = str(price)
        if len(price) > 2:
            return "$" + price[:(-2)] + "." + price[(-2):]
        elif len(price) == 2:
            return "$0." + price
        elif len(price) == 1:
            return "$0.0" + price

    def get_quantity(self):
        quantity = self.prompt(self.PROMPTS["product_quantity"]).strip()
        if quantity == "":
            return 1
        else:
            return quantity

    def select_shipping_methods(self, shipping_response):
        descriptions = []
        shipping_ids = []
        for i in xrange(len(shipping_response["shipping_methods"])):
            current_method = shipping_response["shipping_methods"][i]
            descriptions.append(str(i) + ") " + current_method["name"] + \
                    ": " + current_method["description"])
            shipping_ids.append(current_method["shipping_method_id"])

        prompt = self.build_prompt(self.PROMPTS["select_shipping_methods"], descriptions)
        description_number = self.prompt(prompt,
                ValidationHelpers.validate_number(len(descriptions)))
        chosen_id = shipping_ids[int(description_number)]
        return chosen_id

if __name__ == '__main__':
    ZincWizard({'retailer': 'amazon',
        'client_token': 'public',
        #'shipping_address': "examples/shipping_address.json",
        #'billing_address': "examples/shipping_address.json",
        #'credit_card': "examples/credit_card.json"
        }).start()
<|endoftext|>