from __future__ import print_function
import sys
import os
import importlib
import click
import numpy as np
import timeit
import ast
import sklearn.metrics.regression as reg
import sklearn.model_selection._validation as skv
import mlxtend.feature_selection.sequential_feature_selector as SFS

# Infer the name of this package from the path of __file__
package_parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
package_root_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
package_name = os.path.basename(package_root_dir)

# Make sure that what's in this path takes precedence
# over an installed version of the project
sys.path.insert(0, package_parent_dir)

# Import needed internal modules
pkg = importlib.import_module(package_name)
prj = importlib.import_module(package_name + '._internal.project')

# Import package submodules
pkg.import_submodules()

CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])

def callback_literal_eval(ctx, param, value):
    return np.asarray(ast.literal_eval(value))

@click.command(context_settings=CONTEXT_SETTINGS)
@click.option('--func_name', default='xsinx', show_default=True, help='Model ("xsinx" or "gauss")')
@click.option('--coeffs', is_flag=False, default="((1,1),(1,1))",
              show_default=True, metavar='<array>',
              required=True, type=click.STRING, help='Set model parameters',
              callback=callback_literal_eval)
@click.option('--x_range', type=(float, float), default=(0, 10), help='Range to be covered for all axes.')
@click.option('--n_plot', type=int, default=100, show_default=True, help='Model parameter: alpha0')
@click.option('--n_fit', type=int, default=20, show_default=True, help='Model parameter: alpha0')
@click.option('--sigma', type=float, default=0.5, show_default=True, help='Dispersion to add to model for data')
@click.option('--poly_order', type=int, default=10, show_default=True, help='Model parameter: alpha0')
@click.option('--write2stdout/--no-write2stdout', default=True, show_default=True, help='Write to standard out?')
@click.option('--write2bin/--no-write2bin', default=False, show_default=True, help='Write to binary files?')
@click.option('--check/--no-check', default=False, show_default=True,
              help='Check result against stored results for standard parameter sets (if a match is detected).')
@click.option('--filename_input', default=None, show_default=True, help='Filename to read inputs from.')
@click.option('--filename_plot', default=None, show_default=True, help='Filename to write plot to.')
@click.option(
    '--timing',
    type=(
        float,
        float,
        int,
        int),
    default=(
        None,
        None,
        None,
        None),
    help='Run in timing mode (all previous parameters are ignored).  Specify run as POLY_ORDER_LO POLY_ORDER_HI POLY_ORDER_STEP N_AVG.')
def mlxtend_cuda_test(
        func_name,
        coeffs,
        x_range,
        n_plot,
        n_fit,
        sigma,
        poly_order,
        write2stdout,
        write2bin,
        check,
        filename_input,
        filename_plot,
        timing):
    """This executable runs test fits of the polynomial fitting pipeline used
    by PRISM.

    Gaussian and xsinx models can be used to generate and then
    subsequently fit a model, for various numbers of data points, etc.
    Cuda support can be switched-off by setting the environment variable
    'ENABLE_CUDA' to something false-like (0, 'OFF', etc).
    """

    pkg.log.open("Running mlxtend_cuda...")

    # Write the CLI arguments to the log stream
    pkg.log.open("CLI arguments:")
    ctx = click.get_current_context()
    params = sorted(ctx.params)
    max_param_len = max([len(param) for param in ctx.params])
    for param in params:
        val = str(locals()[param]).replace('\n', '')
        pkg.log.comment(("%s: " + (max_param_len - len(param)) * ' ' + val) % (param))
    pkg.log.close()

    # Parse the 'timing' option.  If it is given,
    # then assume that it specifies a range of frequencies
    # to test, the number of frequencies to test, and the
    # number of calls to average results over
    if(timing[0] is not None):
        flag_timing = True
        poly_order_lo, poly_order_hi, poly_order_step, n_avg = timing
    # ... if it isn't given, just perform one run
    else:
        flag_timing = False
        poly_order_lo = 2
        poly_order_hi = 10
        poly_order_step = 1
        n_avg = 0

    # Generate timing tests
    if(flag_timing):

        # Generate the list of n_freq's that we are going to time
        poly_order_list = np.arange(poly_order_lo, poly_order_hi, poly_order_step)

        # Generate timing results for each n_freq
        n_burn = 1
        pkg.log.set_verbosity(False)
        for i_poly_order, poly_order_i in enumerate(poly_order_list):

            # Initialize the model call (apply some unit conversions here)
            f_model = pkg.mlxtend_cuda.fit_inputs.model(name=func_name, coeffs=coeffs)
            inputs = pkg.mlxtend_cuda.fit_inputs.dataset(
                f_model=f_model, x_range=x_range, n_plot=n_plot, n_fit=n_fit, sigma=sigma)

            # Create a timing callable
            t = timeit.Timer(lambda: pkg.mlxtend_cuda.fit.polynomial(inputs=inputs, poly_order=poly_order_i))

            # Burn a number of calls (to avoid contamination from Cuda context initialization if buf=None, for example)
            if(n_burn > 0):
                if(n_burn == 1):
                    pkg.log.comment("Burning a call: %f seconds." % (t.timeit(number=n_burn)))
                else:
                    pkg.log.comment("Burning %d calls: %f seconds." % (n_burn, t.timeit(number=n_burn)))
                n_burn = 0

            # Call the model n_avg times to generate the timing result
            wallclock_i = t.timeit(number=n_avg)

            # Print timing result
            if(len(poly_order_list) == 1):
                pkg.log.comment("Average timing of %d calls: %.5f seconds." % (n_avg, wallclock_i / float(n_avg)))
            else:
                if(i_poly_order == 0):
                    print("# model: %s" % (inputs.f_model))
                    print("# Column 01: Iteration")
                    print("#        02: No. polynomial terms")
                    print("#        03: Total time for %d calls [s]" % (n_avg))
                    print("#        04: Avg. time per call [s]")
                print("%3d %8d %10.3le %10.3le" % (i_poly_order, poly_order_i, wallclock_i, wallclock_i / float(n_avg)))
        pkg.log.unset_verbosity()

    # ... if n_avg<=1, then just run the model and exit.
    else:

        # Initialize model call
        if filename_input:
            inputs = pkg.mlxtend_cuda.fit_inputs.dataset.load(filename_input)
        else:
            f_model = pkg.mlxtend_cuda.fit_inputs.model(name=func_name, coeffs=coeffs)
            inputs = pkg.mlxtend_cuda.fit_inputs.dataset(
                f_model=f_model, x_range=x_range, n_plot=n_plot, n_fit=n_fit, sigma=sigma)

        # Perform call
        output = pkg.mlxtend_cuda.fit.polynomial(inputs, poly_order=poly_order)

        # Generate plot
        if filename_plot:
            output.plot(inputs, filename_plot)

        # Write results to stdout &/or binary files
        if(write2stdout):
            pkg.log.comment(output)
        if(write2bin):
            inputs.save()
            output.save()

        # Check results against standards (if parameters match)
        if(check):
            pkg.test.calc_difference_from_reference(inputs, results)

    pkg.mlxtend_cuda.estimator.timer.print()
    pkg.log.close("Done.")
    pkg.log._unhang()

# Permit script execution
if __name__ == '__main__':
    status = mlxtend_cuda_test()
    sys.exit(status)


#!/usr/bin/env python3
from PIL import Image
import face_recognition
import argparse
import os

# from face_recognition examples: https://github.com/ageitgey/face_recognition/blob/master/examples/find_faces_in_picture.py

# parsing arguments
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--input", type=str, help="path to input file")
parser.add_argument("-o", "--output", type=str, help="path to output folder", default="assets/faces/")

args = parser.parse_args()

IN_URI = args.input
OUT_URI = args.output

# Load the jpg file into a numpy array
image = face_recognition.load_image_file(IN_URI)
size = (150, 150)

# Find all the faces in the image using the default HOG-based model.
# This method is fairly accurate, but not as accurate as the CNN model and not GPU accelerated.
face_locations = face_recognition.face_locations(image)

print("Found {} face(s) in this photograph.".format(len(face_locations)))

if face_locations:
    try:
        old = os.listdir(OUT_URI)
        for file in old:
            os.remove(OUT_URI + file)
    except:
        print("No files found in chosen output directory")

i = 0
for face_location in face_locations:

    # Print the location of each face in this image
    top, right, bottom, left = face_location
    print("A face is located at pixel location Top: {}, Left: {}, Bottom: {}, Right: {}".format(top, left, bottom, right))

    # You can access the actual face itself like this:
    face_image = image[top:bottom, left:right]
    pil_image = Image.fromarray(face_image)
    pil_image = pil_image.resize(size)
    pil_image = pil_image.convert('1') # convert to bw
    pil_image.save(f"{OUT_URI}face{i}.png")
    # pil_image.show()
    i += 1


MAX_CHARS = 26

def isValid(count, k):
    val = 0
    for i in range(MAX_CHARS):
        if count[i] > 0:
            val += 1
    return (k >= val)

def findUniques(s, k):
    numberOfUniqueCharacters = 0
    length = len(s)

    count = [0] * MAX_CHARS

    for i in range(length):
        if count[ord(s[i])-ord('a')] == 0:
            numberOfUniqueCharacters += 1
        count[ord(s[i])-ord('a')] += 1

    if numberOfUniqueCharacters < k:
        print ("Not enough unique characters")
        return

    curr_start = 0
    curr_end = 0

    max_window_size = 1
    max_window_start = 0

    count = [0] * len(count)

    count[ord(s[0])-ord('a')] += 1

    for i in range(1,length):

        count[ord(s[i])-ord('a')] += 1
        curr_end+=1

        while not isValid(count, k):
            count[ord(s[curr_start])-ord('a')] -= 1
            curr_start += 1

        if curr_end-curr_start+1 > max_window_size:
            max_window_size = curr_end-curr_start+1
            max_window_start = curr_start

    print (s[max_window_start:max_window_start  + max_window_size])

s = "abcba"
k = 2
findUniques(s, k)


import os
import pathlib
import time

import numpy as np
import pandas as pd
import wandb

from bowel.controller import Controller
from bowel.data.data_loader import DataLoader
from bowel.data.label_creator import LabelCreator
from bowel.factories import instantiate_normalizers
from bowel.utils.io import silence_librosa_userwarnings, load_config, load_divsion_file
from bowel.utils.reproducibility_utils import setup_seed

def measure_prediction_performance():
    """Measure performance for various length input size."""
    setup_seed()
    silence_librosa_userwarnings()
    # paths
    CONFIG_DIR = pathlib.Path("./configs/")
    DATA_DIR = pathlib.Path("./data/processed/")
    # path to the file specifying samples names and division in folds
    division_file_path = pathlib.Path("./data/processed/files.csv")
    transform_config_path = CONFIG_DIR / "best_model_transformation.yaml"
    train_config_path = CONFIG_DIR / "best_model_train.yaml"
    transform_config = load_config(transform_config_path)
    train_config = load_config(train_config_path)
    save_path = pathlib.Path("models/best_model")
    division_data = load_divsion_file(division_file_path)
    # make the data seem as if it was from the last fold
    division_data.loc[:, "kfold"] = 5
    # repeat 7 time to go over 10_000 samples
    division_data = pd.DataFrame(np.repeat(division_data.values, 7, axis=0), columns=division_data.columns)
    print(division_data)
    print(division_data.shape)
    data_sizes = [10, 30, 100, 300, 1_000, 3_000]  # number of 2 second files
    results = {}
    for data_size in data_sizes:
        start_time = time.time()
        part_of_division_data = division_data.iloc[:data_size]
        data_loader = DataLoader(DATA_DIR, part_of_division_data)
        label_creator = LabelCreator(DATA_DIR, part_of_division_data, transform_config)
        data = data_loader.load_data()
        labels = label_creator.labels

        controller = Controller(
            transform_config,
            train_config,
            data,
            labels
        )
        controller.audio_normalizer, controller.features_normalizer = instantiate_normalizers(
            controller.transform_config, mode="test", save_path=save_path)
        controller.test_from_saved(save_path=save_path)
        end_time = time.time()
        time_taken = end_time - start_time
        results[data_size] = time_taken
    return results

if __name__ == "__main__":
    os.environ['WANDB_MODE'] = 'disabled'  # do not register the results in wandb
    wandb.init()
    results = measure_prediction_performance()
    results = pd.DataFrame(np.array([list(results.keys()), list(results.values())]).T, columns=["data_size", "time"])
    results.to_csv("./results/performance.csv")
    print(results)


# -*- coding: utf-8 -*-
"""
Created on Fri Aug  6 16:52:49 2021

@author: Hera
"""
from nplab.instrument.serial_instrument import SerialInstrument
from nplab.instrument import Instrument
from nplab.utils.notified_property import NotifiedProperty
from nplab.ui.ui_tools import QuickControlBox

def bytes_to_binary(bytearr, debug=0):
    '''
    Helper method for converting a bytearray datatype to a binary representation
    '''
    if debug > 0: print(bytearr)
    bytes_as_binary = [format(int(b, base=16), "#06b").replace(
        "0b", "") for b in bytearr]
    if debug > 0: print(bytes_as_binary)
    binary = "".join(bytes_as_binary)
    return binary

def twos_complement_to_int(binary, debug=0):
    '''
    Compute 2s complement of binary number representation
    '''
    if debug > 0: print(binary)
    N = len(binary)
    a_N = int(binary[0])
    return float(-a_N*2**(N-1) + int(binary[1:], base=2))

def int_to_hex(integer, padded_length=8, debug=0):
    '''
    Convert integer number to hexidecimal. Return value is zero-padded at the beginning
    until its length matches the value passed in "padded_length"
    '''
    outp = (format(integer, "#0{}x".format(
        padded_length+2)).replace("0x", "")).upper()
    return outp

def int_to_twos_complement(integer, padded_length=16, debug=0):
    '''
    Two's complement in integer representation. Padded length specifies the padding on the
    binary representation used to compute the twos complement
    '''
    #number is above 0 - return binary representation:
    if integer >= 0:
        return integer

    #number is below zero - return twos complement representation:
    elif integer < 0:
        if debug > 0: print("Below zero - returning twos complement")
        integer = -1*integer
        binary = format(integer, "0{}b".format(
            padded_length+2)).replace("0b", "")
        ones_complement = [str(1-int(b)) for b in str(binary)]
        ones_complement = int("".join(ones_complement))
        twos_complement = int("0b"+str(ones_complement), base=2) + 1
        twos_complement = format(twos_complement, "034b").replace("0b", "")
        if debug > 0:
            print("input:", integer)
            print("binary:", binary)
            print("ones comp:", ones_complement)
            print("twos comp (int):", int(twos_complement, base=2))
        return int("0b"+twos_complement, base=2)

class BusDistributor(SerialInstrument):
    ''' a class to handle the port settings of a thorlabs ELLB distributor bus.
    Each of these can have several devices attached. They are assigned device
    indices by the thorlabs Ello software - otherwise they all default to 0 and
    don't work separately.
    '''

    def __init__(self, port):
        self.termination_character = '\n'
        self.port_settings = dict(baudrate=9600,
                                  bytesize=8,
                                  stopbits=1,
                                  parity='N',
                                  timeout=2,
                                  writeTimeout=2,
                                  xonxoff=False)
        super().__init__(port)

class ThorlabsELL6(Instrument):

    #default id is 0, but if multiple devices of same type connected may have others
    VALID_DEVICE_IDs = [str(v) for v in list(
        range(11)) + ["A", "B", "C", "D", "E", "F"]]

    #How much a stage sleeps (in seconds) between successive calls to .get_position.
    #Used to make blocking calls to move_absolute and move_relative.
    BLOCK_SLEEPING_TIME = 0.02
    #Theshold for position accuracy when stage is meant to be stationary
    #If difference between successive calls to get_position returns value
    #whose difference is less than jitter - consider stage to have stopped
    POSITION_JITTER_THRESHOLD = 0.02

    #human readable status codes
    DEVICE_STATUS_CODES = {
            0: "OK, no error",
            1: "Communication Timeout",
            2: "Mechanical time out",
            3: "Command error or not supported",
            4: "Value out of range",
            5: "Module isolated",
            6: "Module out of isolation",
            7: "Initialization error",
            8: "Thermal error",
            9: "Busy",
            10: "Sensor Error",
            11: "Motor Error",
            12: "Out of Range",
            13: "Over current error",
            14: "OK, no error",
            "OutOfBounds": "Reserved"
        }
    positions = 2

    def __init__(self, serial_device, device_index=0, debug=0):
        '''can be passed either a BusDistributor instance, or  "COM5"  '''
        super().__init__()
        if type(serial_device) is str:
            self.serial_device = BusDistributor(serial_device)
        else:
            self.serial_device = serial_device
        self.debug = debug

        if str(device_index) not in self.VALID_DEVICE_IDs:
            raise ValueError(
                "Device ID: {} is not valid!".format(device_index))
        self.device_index = device_index
        self.home()

    def home(self):
        self.query_device('ho')
        self._position = 0

    def set_position(self, pos):
        assert 0 <= pos < self.positions

        while pos > self._position:
            self.move_forward()
        while pos < self._position:
            self.move_backward()

    def get_position(self):
        return self._position

    position = NotifiedProperty(get_position, set_position)

    def query_device(self, query):
        '''
        Wrap a generic query with the ID of the device (integer in range: 0-F)
        so that we dont need to be explicit about this id
        '''
        raw_query = "{0}{1}".format(self.device_index, query)
        if self.debug > 0:
            print("raw_query", raw_query)
        raw_response = self.serial_device.query(raw_query)
        if self.debug > 0:
            print("raw_response", raw_response)
        return raw_response

    def get_qt_ui(self):
        '''
        Get UI for stage
        '''

        return ELL6UI(self)

    def move_forward(self):
        self.query_device('fw')
        self._position += 1

    def move_backward(self):
        self.query_device('bw')
        self._position -= 1

class ThorlabsELL9(ThorlabsELL6):
    positions = 4

    def get_qt_ui(self):
        '''
        Get UI for stage
        '''

        return ELL9UI(self)

class ELL6UI(QuickControlBox):
    def __init__(self, instr):
        super().__init__('ELL6')
        self.add_spinbox('position', vmin=0, vmax=1)
        self.auto_connect_by_name(controlled_object=instr)

class ELL9UI(QuickControlBox):
    def __init__(self, instr):
        super().__init__('ELL9')
        self.add_spinbox('position', vmin=0, vmax=3)
        self.auto_connect_by_name(controlled_object=instr)

if __name__ == '__main__':
    # f = ThorlabsELL6('COM9')
    f = ThorlabsELL9('COM6')
    f.show_gui(False)


import re
import unicodedata
from pytube import YouTube
from pytube.cli import on_progress

def convert_seconds(seconds):
    units = ["seconds", "minutes", "hours", "days"]
    temp = None

    if seconds < 0:
        return None
    duration = [0, 0, 0, 0]

   # days
    temp = seconds // 86400 # 86400 seconds in a day
    duration[3] = temp
    # hours
    temp = (seconds % 86400) // 3600 # 3600 seconds in an hour
    duration[2] = temp
    # minutes
    temp = (seconds % 3600) // 60 # 60 seconds in a minute
    duration[1] = temp
    # seconds
    temp = (seconds % 60)
    duration[0] = temp

    duration_to_string = ""
    for i in range(len(duration)-1, -1, -1):
        if duration[i] == 1:
            duration_to_string += str(duration[i]) + " " + units[i][:-1] + ", "
        elif duration[i] != 0:
            duration_to_string += str(duration[i]) + " " + units[i] + ", "
    return duration_to_string[:-2]

def download_video(yt, tag, output_path, filename, ext):
    ys = yt.streams.get_by_itag(tag)
    if filename == "":
        filename = yt.title
    filename = unicodedata.normalize('NFKD', filename).encode('ascii', 'ignore').decode('ascii')
    filename = re.sub(r'[^\w\s-]', '', filename.lower())
    filename = re.sub(r'[-\s]+', '-', filename).strip('-_')
    filename = filename + "." + ext
    ys.download(output_path=output_path, filename=filename)


from PIL import Image
import os, re
background='BSIS_2'
project='BSIS_2'

filenames = next(os.walk(f'result/{project}/'), (None, None, []))[2]  # [] if no file

# 打开所有PNG图像并将它们添加到一个列表中
images = []
for file_name in filenames:
    img = Image.open(f'result/{project}/{file_name}')
    images.append(img)

# 保存为GIF动画
output_gif = f'result/{project}.gif'
images[0].save(output_gif, save_all=True, append_images=images[1:], duration=800, loop=0)

# 清理打开的图像对象
for img in images:
    img.close()

print(f'GIF动画已保存为 {output_gif}')


import time
from random import randint
import os

def log(function):
    log_msg = '(cmaxime)Running: {:19}[ exec-time = {:.3f} {} ]'

    def wrapper(*args, **kwargs):
        t = time.time()
        result = function(*args, **kwargs)
        t = time.time() - t
        fun_name = function.__name__.replace('_', ' ').title()
        fa = (fun_name, t, 'ms' if t < 1 else 's')
        with open('machine.log', 'a') as f:
            if (f):
                print(log_msg.format(*fa), file=f)
        return result
    return wrapper

class CoffeeMachine():

    water_level = 100

    @log
    def start_machine(self):
        if self.water_level > 20:
            return True
        else:
            print("Please add water!")
        return False

    @log
    def boil_water(self):
        return "boiling..."

    @log
    def make_coffee(self):
        if self.start_machine():
            for _ in range(20):
                time.sleep(0.1)
                self.water_level -= 1

        print(self.boil_water())
        print("Coffee is ready!")

    @log
    def add_water(self, water_level):
        time.sleep(randint(1, 5))
        self.water_level += water_level
        print("Blub blub blub...")

if __name__ == "__main__":
    machine = CoffeeMachine()
for i in range(0, 5):
    machine.make_coffee()
    machine.make_coffee()
    machine.add_water(70)


import lib, libnat
from random import random
from lib import mcarlo
from math import e, factorial, sqrt, pi, exp
from itertools import chain
from functools import partial

def ej1_play():
		perm = lib.permutacion(list(range(1, 101)))
		return sum(1 for (i, c) in enumerate(perm) if i + 1 == c)

def ej1(n):
	"""
	https://www.johndcook.com/blog/2010/04/06/subfactorial/
	n: numero de muestras
	"""
	sample = [ej1_play() for _ in range(n)]
	print("n: {0}".format(n))
	print("sum: {0}".format(sum(sample)))
	print("media: {0}".format(lib.media(sample)))
	print("varianza: {0}".format(lib.varianza(sample)))

def ej2(n):
    """sum exp(k/N) from k=1 to N con N=10**4"""
	#return e**(1/10**4)*10**4*mcarlo(lambda k: e**k, n)
    N = 10**4
    return N*sum(exp(lib.udiscreta(1, N)/N) for _ in range(n))/n

def roll_dice():
	return lib.udiscreta(1, 6)

def ej3(n):
	def rolluntil():
		count = 0
		all = set(range(2,13))
		while all != set():
			all.discard(roll_dice() + roll_dice())
			count += 1
		return count

	sample = [rolluntil() for _ in range(n)]
	print("n: {0}".format(n))
	print("sum: {0}".format(sum(sample)))
	print("media: {0}".format(lib.media(sample)))
	print("varianza: {0}".format(lib.varianza(sample)))

def ej4(l, k, U=None):
    """

    """
    U = random() if U is None else U
    g = lib.poissonseriesgen(l)
    next(g)
    sumaabajo = sum(l**j/factorial(j) for j in range(k))*exp(-l)
    return lib.transf_inv((x for x in range(10**10)),
        chain(iter([exp(-l)/sumaabajo]), g), U=U)

def ej5():
    p1gen = (2**-j for j in range(1, 10**10))
    p2gen = (1/2 * (2/3)**j for j in range(1, 10**10))
    Ngen1 = (n for n in range(1, 10**10))
    Ngen2 = (n for n in range(1, 10**10))
    return lib.met_comp(
        lib.transf_inv(Ngen1, p1gen),
        lib.transf_inv(Ngen2, p2gen),
        1/2)


import math

metadata = {
    'protocolName': 'Mastermix Creation and Sample Transfer',
    'author': 'Chaz <chaz@opentrons.com>',
    'source': 'Custom Protocol Request',
    'apiLevel': '2.5'
}

def run(protocol):
    [p_csv, num_samples, ex_opti] = get_values(  # noqa: F821
        'p_csv', 'num_samples', 'ex_opti')

    # load labware and pipettes
    tip20 = [
        protocol.load_labware(
            'opentrons_96_tiprack_20ul', str(s)) for s in range(1, 4)]

    p20s = protocol.load_instrument('p20_single_gen2', 'left', tip_racks=tip20)
    p20m = protocol.load_instrument('p20_multi_gen2', 'right', tip_racks=tip20)

    stock = protocol.load_labware(
        'opentrons_96_aluminumblock_generic_pcr_strip_200ul',
        '4', 'Al Block with PCR strips and stock')

    mm = protocol.load_labware(
        'opentrons_96_aluminumblock_generic_pcr_strip_200ul',
        '5', 'Al Block with PCR strips for Mastermix')

    samplePlate = protocol.load_labware(
        'corning_96_wellplate_360ul_flat', '6')

    tubeRack = protocol.load_labware(
        'opentrons_24_tuberack_eppendorf_1.5ml_safelock_snapcap', '7')

    num_cols = math.ceil(num_samples/8)
    mm_cols = mm.rows()[0][:num_cols]
    samp_cols = samplePlate.rows()[0][:num_cols*3]
    s_cols = [samp_cols[i:i + 3] for i in range(0, len(samp_cols), 3)]

    # reagents
    optimem = tubeRack['D6']
    viafect = mm['A12']

    # create list of data from csv
    data = [row.split(',') for row in p_csv.strip().splitlines() if row][1:]

    # Add optimem to wells
    protocol.comment('Adding OptiMEM to all sample wells...')
    p20s.pick_up_tip()

    for well in mm.wells()[:num_samples-1]:
        p20s.aspirate(5.3, optimem)
        p20s.dispense(5.3, well)

    if ex_opti != '31.7':
        p20s.aspirate(5.3, optimem)
        p20s.dispense(5.3, mm.wells()[num_samples-1])
    else:
        p20s.aspirate(16, optimem)
        p20s.dispense(16, mm.wells()[num_samples-1])
        p20s.aspirate(15.7, optimem)
        p20s.dispense(15.7, mm.wells()[num_samples-1])

    p20s.drop_tip()

    # Add 4.4ul of sample to well per CSV
    protocol.comment('Adding sample to all sample wells...')
    for d in data:
        p20s.transfer(4.4, stock[d[0].strip()], mm[d[1].strip()])

    # Add 1.3ul of viafect to each well
    protocol.comment('Adding viafect to all sample wells...')
    for col in mm_cols:
        p20m.pick_up_tip()
        p20m.aspirate(1.3, viafect)
        p20m.dispense(1.3, col)
        p20m.mix(3, 20, col)
        p20m.blow_out()
        p20m.drop_tip()

    protocol.pause('Please let incubate for 10 minutes.')

    # transfer
    protocol.comment('Transferring mastermix to samples...')
    for src, dest in zip(mm_cols, s_cols):
        p20m.pick_up_tip()
        p20m.mix(3, 20, src)
        for d in dest:
            p20m.transfer(10, src, d, new_tip='never')
        p20m.drop_tip()


import pytest
import src.channel
from src.auth import auth_register_v2
from src.channels import channels_create_v2
from src.other import clear_v1
from src.helper import load_data
import src.error

#channels_create_v1(auth_user_id, name, is_public)
def test_token_invalid():
    clear_v1()
    user1 = auth_register_v2('validemail@gmail.com', '123abcde', 'Hayden', 'Everest')

    token1 = user1['token']
    with pytest.raises(src.error.AccessError):
        channels_create_v2(token1+'abc', 'channel_one', True)
def test_channel_name_too_long():
    clear_v1()
    auth_user1 = auth_register_v2('testchannelprivate1@gmail.com','a123456789','tom','h0')
    with pytest.raises(src.error.InputError):
        channels_create_v2(auth_user1['token'],'abcdefghijklmnopqrstuvwxyz',True)

def test_channel_create_success():
    clear_v1()
    auth_user1 = auth_register_v2('testchannelprivate1@gmail.com','a123456789','tom','h0')
    channel_id = channels_create_v2(auth_user1['token'],'name',True)
    create_success = False
    data = load_data()
    for channel in data['channels']:
        if channel_id['channel_id'] == channel['channel_id']:
            create_success = True
    assert create_success == True

def test_channel_create_information():
    clear_v1()
    user1 = auth_register_v2('testmessage@gmail.com','a123456789','tom','h')
    channel_id = channels_create_v2(user1['token'],'name',False)
    data = load_data()
    assert (data['channels'][channel_id['channel_id']-1]['name'] == 'name' and data['channels'][channel_id['channel_id']-1]['is_public'] == False)


import netCDF4 as nc4
import numpy as np
from collections import OrderedDict
from geo_Collection import geo_web as gs
from geo_Collection import geo_self as gss
from QAAV6GOCI import QAAv6
import os
import glob
import datetime
import warnings
import concurrent.futures
import math
from deco import *
import multiprocessing as mp

# from multiprocess import Pool
warnings.filterwarnings("ignore")  # 用来去掉Warning,
os.environ['PROJ_LIB'] = '/Users/zhenjia/opt/anaconda3/share/proj'
import pandas as pd
import matplotlib.pyplot as plt

# os.chdir('I:/Nagoya University/Project/Seto/MODIS')
# path='I:/Nagoya University/Project/Seto/MODIS/'
os.chdir('/Users/zhenjia/Downloads/')
path = '/Users/zhenjia/Downloads/'
datalist = glob.glob('G2018*.nc')
# 20150715 Uwajima
# 20180723 Osaka
# minlat = 32
# minlon = 130
# maxlat = 35
# maxlon = 136
# area of full seto-inland sea
# # # for a1 in range(1):
# minlat = 32.32
# minlon = 131.39
# maxlat = 33.48
# maxlon = 132.77

# # bun go si i to
minlat = 33.88
minlon = 132.85
maxlat = 34.8
maxlon = 135
# middle
# minlat = 34.18
# minlon = 134.00
# maxlat = 34.88
# maxlon = 135.59
# # Osaka
l = np.arange(len(datalist))

def bbpp(i):
    file = datalist[i]
    filename = path + file
    nc_file = nc4.Dataset(filename, 'r')
    print(nc_file.time_coverage_end)
    lon = nc_file.groups['navigation_data'].variables['longitude'][:]
    lat = nc_file.groups['navigation_data'].variables['latitude'][:]
    variables = nc_file.groups['geophysical_data'].variables

    x = np.arange(minlon, maxlon, 0.005)  # 1 km grid,
    y = np.arange(maxlat, minlat, -0.005)

    for i in variables:
        var = variables[i][:]
        np.where(var <= 0, var, np.nan)
        if i != 'l2_flags':
            var_re, grid = gs.swath_resampling(var, lon, lat, x, y, 2500)  # 1 km grid
            # var_re=var_re.filled()
            if np.ma.is_mask(var_re):
                var_re = var_re.filled(np.nan)
                var_re[var_re == -32767.0] = np.nan
            variables[i] = var_re
        else:
            # var_re = var_re.filled()
            variables[i] = var

    lons = grid.lons
    lats = grid.lats
    Rrs_412 = variables['Rrs_412']
    Rrs_443 = variables['Rrs_443']
    Rrs_490 = variables['Rrs_490']

    Rrs_555 = variables['Rrs_555']

    Rrs_660 = variables['Rrs_660']
    Rrs_680 = variables['Rrs_680']

    Rrs = np.array([
        Rrs_412,
        Rrs_443,

        Rrs_490,

        Rrs_555,
        Rrs_660,
        Rrs_680])
    # nflh = nlw678 - (70 / 81) * nlw667 - (11 / 81) * nlw748
    chl = variables['chlor_a']

    def rrs_to_qaa(Rrs):
        bbp555QAA = np.zeros(np.shape(chl))

        for m in range(len(y)):
            for n in range(len(x)):
                # for k in range(10):
                # if (Rrs[k, i, j] < 0) or (Rrs[k, i, j] == np.nan):
                # bbp[k] = np.nan
                # else:
                bbp = QAAv6(Rrs[:, m, n])
                bbp555QAA[m, n] = bbp[3]

        return bbp555QAA

    bbp555qaa = rrs_to_qaa(Rrs)
    bbpindex = 0.37 * (Rrs_555 * Rrs_660) / (Rrs_555 - Rrs_660)
    chlanorm_bbp555qaa = bbp555qaa / chl
    chlanorm_bbpindex = bbpindex / chl
    gs.plot_geo_image(chlanorm_bbp555qaa, lons, lats, log10=False,
                      title='chlanorm_bbp555qaa' + nc_file.time_coverage_end[0:13],
                      save_image='chlanorm_bbp555qaa' + nc_file.time_coverage_end[0:13])
    gs.plot_geo_image(chlanorm_bbpindex, lons, lats, log10=False,
                      title='chlanorm_bbpindex' + nc_file.time_coverage_end[0:13],
                      save_image='chlanorm_bbpindex' + nc_file.time_coverage_end[0:13])
    gs.plot_geo_image(bbp555qaa, lons, lats, log10=False, title='bbp555qaa' + nc_file.time_coverage_end[0:13],
                      caxis=[0, 0.03], save_image='bbp555qaa' + nc_file.time_coverage_end[0:13])
    gs.plot_geo_image(bbpindex, lons, lats, log10=False, title='bbp555index' + nc_file.time_coverage_end[0:13],
                      save_image='bbp555index' + nc_file.time_coverage_end[0:13])

if __name__ == '__main__':
    mp.set_start_method("spawn")
    pool = mp.Pool(processes=8)
    pool.map(bbpp, l)


defaults = {}

@metadata_reactor
def add_iptables(metadata):
    if not node.has_bundle("iptables"):
        raise DoNotRunAgain

    iptables_rules = {}
    for name,conf in metadata.get('wireguard').items():
        iptables_rules += repo.libs.iptables.accept(). \
            input(conf.get('interface', 'main_interface')). \
            udp(). \
            dest_port(metadata.get('wireguard').get(name).get('port')). \
            comment(f'wireguard {name}')

        # Ignore forward rules
        iptables_rules += repo.libs.iptables.jump('ACCEPT').chain('FORWARD').output(name).ignore()
        iptables_rules += repo.libs.iptables.jump('ACCEPT').chain('FORWARD').input(name).ignore()

    return iptables_rules


# -*- coding: utf-8 -*-
# ============================================================================
# Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
# Copyright (c) 2011-2012 University of Pennsylvania
# Copyright (c) 2013-2014 Andreas Schuh
# All rights reserved.
# ============================================================================
"""

    @file  diff3.py
    @brief Three-way file comparison algorithm.

    This is a line-by-line translation of the Text::Diff3 Perl module version
    0.10 written by MIZUTANI Tociyuki <tociyuki@gmail.com>.

    The Text::Diff3 Perl module in turn was based on the diff3 program:

    Three way file comparison program (diff3) for Project GNU.
    Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
    Written by Randy Smith

    The two-way file comparison procedure was based on the article:
    P. Heckel. ``A technique for isolating differences between files.''
    Communications of the ACM, Vol. 21, No. 4, page 264, April 1978.

    jsb: added newlines for conflict markers
"""

from operator import xor

# ----------------------------------------------------------------------------
def diff3(yourtext, origtext, theirtext):
    """Three-way diff based on the GNU diff3.c by R. Smith.

    @param [in] yourtext   Array of lines of your text.
    @param [in] origtext   Array of lines of original text.
    @param [in] theirtext  Array of lines of their text.

    @returns Array of tuples containing diff results. The tuples consist of
             (cmd, loA, hiA, loB, hiB), where cmd is either one of
             '0', '1', '2', or 'A'.

    """
    # diff result => [(cmd, loA, hiA, loB, hiB), ...]
    d2 = (diff(origtext, yourtext), diff(origtext, theirtext))
    d3 = []
    r3 = [None, 0, 0, 0, 0, 0, 0]
    while d2[0] or d2[1]:
        # find a continual range in origtext lo2..hi2
        # changed by yourtext or by theirtext.
        #
        #     d2[0]        222    222222222
        #  origtext     ...L!!!!!!!!!!!!!!!!!!!!H...
        #     d2[1]          222222   22  2222222
        r2 = ([], [])
        if not d2[0]: i = 1
        else:
            if not d2[1]: i = 0
            else:
                if d2[0][0][1] <= d2[1][0][1]: i = 0
                else: i = 1
        j = i
        k = xor(i, 1)
        hi = d2[j][0][2]
        r2[j].append(d2[j].pop(0))
        while d2[k] and d2[k][0][1] <= hi + 1:
            hi_k = d2[k][0][2]
            r2[k].append(d2[k].pop(0))
            if hi < hi_k:
                hi = hi_k
                j = k
                k = xor(k, 1)
        lo2 = r2[i][0][1]
        hi2 = r2[j][-1][2]
        # take the corresponding ranges in yourtext lo0..hi0
        # and in theirtext lo1..hi1.
        #
        #   yourtext     ..L!!!!!!!!!!!!!!!!!!!!!!!!!!!!H...
        #      d2[0]        222    222222222
        #   origtext     ...00!1111!000!!00!111111...
        #      d2[1]          222222   22  2222222
        #  theirtext          ...L!!!!!!!!!!!!!!!!H...
        if r2[0]:
            lo0 = r2[0][0][3] - r2[0][0][1] + lo2
            hi0 = r2[0][-1][4] - r2[0][-1][2] + hi2
        else:
            lo0 = r3[2] - r3[6] + lo2
            hi0 = r3[2] - r3[6] + hi2
        if r2[1]:
            lo1 = r2[1][0][3] - r2[1][0][1] + lo2
            hi1 = r2[1][-1][4] - r2[1][-1][2] + hi2
        else:
            lo1 = r3[4] - r3[6] + lo2
            hi1 = r3[4] - r3[6] + hi2
        # detect type of changes
        if not r2[0]:
            cmd = '1'
        elif not r2[1]:
            cmd = '0'
        elif hi0 - lo0 != hi1 - lo1:
            cmd = 'A'
        else:
            cmd = '2'
            for d in range(0, hi0 - lo0 + 1):
                (i0, i1) = (lo0 + d - 1, lo1 + d - 1)
                ok0 = (0 <= i0 and i0 < len(yourtext))
                ok1 = (0 <= i1 and i1 < len(theirtext))
                if xor(ok0, ok1) or (ok0 and yourtext[i0] != theirtext[i1]):
                    cmd = 'A'
                    break
        d3.append((cmd, lo0, hi0, lo1, hi1, lo2, hi2))
    return d3

# ----------------------------------------------------------------------------
def merge(yourtext, origtext, theirtext):
    res = {'conflict': 0, 'body': []}
    d3 = diff3(yourtext, origtext, theirtext)
    text3 = (yourtext, theirtext, origtext)
    i2 = 1
    for r3 in d3:
        for lineno in range(i2, r3[5]):
            res['body'].append(text3[2][lineno - 1])
        if r3[0] == '0':
            for lineno in range(r3[1], r3[2] + 1):
                res['body'].append(text3[0][lineno - 1])
        elif r3[0] != 'A':
            for lineno in range(r3[3], r3[4] + 1):
                res['body'].append(text3[1][lineno - 1])
        else:
            res = _conflict_range(text3, r3, res)
        i2 = r3[6] + 1
    for lineno in range(i2, len(text3[2]) + 1):
        res['body'].append(text3[2][lineno - 1])
    return res

# ----------------------------------------------------------------------------
def _conflict_range(text3, r3, res):
    text_a = []  # their text
    for i in range(r3[3], r3[4] + 1):
        text_a.append(text3[1][i - 1])
    text_b = []  # your text
    for i in range(r3[1], r3[2] + 1):
        text_b.append(text3[0][i - 1])
    d = diff(text_a, text_b)
    if _assoc_range(d, 'c') and r3[5] <= r3[6]:
        res['conflict'] += 1
        res['body'].append('<<<<<<<\n')
        for lineno in range(r3[1], r3[2] + 1):
            res['body'].append(text3[0][lineno - 1])
        res['body'].append('|||||||\n')
        for lineno in range(r3[5], r3[6] + 1):
            res['body'].append(text3[2][lineno - 1])
        res['body'].append('=======\n')
        for lineno in range(r3[3], r3[4] + 1):
            res['body'].append(text3[1][lineno - 1])
        res['body'].append('>>>>>>>\n')
        return res
    ia = 1
    for r2 in d:
        for lineno in range(ia, r2[1]):
            res['body'].append(text_a[lineno - 1])
        if r2[0] == 'c':
            res['conflict'] += 1
            res['body'].append('<<<<<<<\n')
            for lineno in range(r2[3], r2[4] + 1):
                res['body'].append(text_b[lineno - 1])
            res['body'].append('=======\n')
            for lineno in range(r2[1], r2[2] + 1):
                res['body'].append(text_a[lineno - 1])
            res['body'].append('>>>>>>>\n')
        elif r2[0] == 'a':
            for lineno in range(r2[3], r2[4] + 1):
                res['body'].append(text_b[lineno - 1])
        ia = r2[2] + 1
    for lineno in range(ia, len(text_a)):
        res['body'].append(text_a[lineno - 1])
    return res

# ----------------------------------------------------------------------------
def _assoc_range(diff, diff_type):
    for d in diff:
        if d[0] == diff_type: return d
    return None

# ----------------------------------------------------------------------------
def _diff_heckel(text_a, text_b):
    """Two-way diff based on the algorithm by P. Heckel.

    @param [in] text_a Array of lines of first text.
    @param [in] text_b Array of lines of second text.

    @returns TODO

    """
    d = []
    uniq = [(len(text_a), len(text_b))]
    (freq, ap, bp) = ({}, {}, {})
    for i in range(len(text_a)):
        s = text_a[i]
        freq[s] = freq.get(s,
                           0) + 2
        ap[s] = i
    for i in range(len(text_b)):
        s = text_b[i]
        freq[s] = freq.get(s,
                           0) + 3
        bp[s] = i
    for s, x in freq.items():
        if x == 5: uniq.append((ap[s], bp[s]))
    (freq, ap, bp) = ({}, {}, {})
    uniq.sort(key=lambda x: x[0])
    (a1, b1) = (0, 0)
    while a1 < len(text_a) and b1 < len(text_b):
        if text_a[a1] != text_b[b1]: break
        a1 += 1
        b1 += 1
    for a_uniq, b_uniq in uniq:
        if a_uniq < a1 or b_uniq < b1: continue
        (a0, b0) = (a1, b1)
        (a1, b1) = (a_uniq - 1, b_uniq - 1)
        while a0 <= a1 and b0 <= b1:
            if text_a[a1] != text_b[b1]: break
            a1 -= 1
            b1 -= 1
        if a0 <= a1 and b0 <= b1:
            d.append(('c', a0 + 1, a1 + 1, b0 + 1, b1 + 1))
        elif a0 <= a1:
            d.append(('d', a0 + 1, a1 + 1, b0 + 1, b0))
        elif b0 <= b1:
            d.append(('a', a0 + 1, a0, b0 + 1, b1 + 1))
        (a1, b1) = (a_uniq + 1, b_uniq + 1)
        while a1 < len(text_a) and b1 < len(text_b):
            if text_a[a1] != text_b[b1]: break
            a1 += 1
            b1 += 1
    return d

# ----------------------------------------------------------------------------
diff = _diff_heckel  # default two-way diff function used by diff3()


fact,i=1,2

n=int(input("digite el numero\n"))
if(n==0 or n==1):
    fact=1
else:
    while(i<=n):
        fact=fact*i
        i+=1

print("el factorial de ",n,"es",fact)

repositorio ejemplo unidad 1/repositorio ejemplo unidad 1/2.practica estructura de control/ejercicio17.py


import tensorflow as tf
import numpy as np

xy = np.loadtxt('data-01-test-score.csv', delimiter=',', dtype=np.float32)

print(xy)

x_data = xy[:, 0:-1]
y_data = xy[:, [-1]]

print(x_data.shape, x_data, len(x_data), y_data.shape, y_data)

X = tf.placeholder(tf.float32, shape=[None, 3])
Y = tf.placeholder(tf.float32, shape=[None, 1])

W = tf.Variable(tf.random_normal([3, 1]), name='weight')
b = tf.Variable(tf.random_normal([1]), name='bias')

hypothesis = tf.matmul(X, W) + b

cost = tf.reduce_mean(tf.square(hypothesis - Y))
learning_rate = 0.1

optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-5)
train = optimizer.minimize(cost)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

W_val = []
cost_val = []

for step in range(2001):
    cost_val, hy_val, _ = sess.run([cost, hypothesis, train], feed_dict={X: x_data, Y: y_data})
    #print(step, "Cost: ", cost_val, "Prediction: ", hy_val)

print("Your score will be ", sess.run(hypothesis, feed_dict={X:[[100, 70, 101]]}))
print("Others score will be ", sess.run(hypothesis, feed_dict={X:[[60, 70, 110],[90,100,80]]}))


# -*- coding: utf-8 -*-
"""
    @JackeyGao
    Create at 2018-12-18
"""
import json
import traceback
import os
import jinja2
import arrow
import shutil

from urllib.parse import unquote

from md import get_markdown

loader = jinja2.FileSystemLoader(searchpath="templates")
env = jinja2.Environment(loader=loader)

def log(msg):
    """Log"""
    print('+ %s' % (msg))

class Handler(object):

    def __init__(self, file):
        self.file = file
        self.toc = []

    @property
    def name(self):
        name = unquote(self.file).replace('.json', '')
        return name.split('/')[-1]

    def read_json(self):
        with open(self.file, 'r') as f:
            return json.loads(f.read())

    def render_entry(self, entry):
        if 'photos' in entry:
            markdown = get_markdown(photos=entry["photos"])
        else:
            markdown = get_markdown(photos=[])

        if 'text' in entry:
            content = markdown(entry["text"])
        else:
            content = ''

        t = env.get_template('entry.html')
        create = arrow.get(entry["creationDate"])

        entry["create"] = create

        name = create.format("YYYYMMDDHHmmss")
        log('正在生成%s' % name)

        output = t.render(
            content=content, entry=entry, book=self.name, name=name
        )

        with open('output/entries/%s.html' % name, 'w') as f:
            f.write(output)

        self.toc.append(name)

    def render(self):
        data = self.read_json()

        for entry in data["entries"]:
            self.render_entry(entry)

        with open('output/%s.json' % self.name, 'w') as f:
            f.write(json.dumps(self.toc, indent=2, ensure_ascii=False))

def initialization():
    if os.path.exists('output'):
        shutil.rmtree('output')

    os.mkdir('output')
    os.mkdir('output/entries')

def main():
    try:
        _dir = './dayone'

        # 初始化
        initialization()

        log("初始化;")

        json_files = [ os.path.join(_dir, x) \
            for x in os.listdir(_dir) \
            if x.endswith('.json')
        ]

        if not json_files:
            log("Warning: 在 dayone 目录中没有找到 JSON 文件.")
            log("Warning: 请将dayone导出目录解压到当前目录, 并重命名为dayone。")

        for file in json_files:
            handler = Handler(file)
            handler.render()
    except FileNotFoundError:
        log("Error: 请将dayone导出目录解压到当前目录, 并重命名为dayone。")
    except Exception as e:
        log("Error: 未知错误 \n%s" % traceback.format_exc())

    log("生成HTML完成.")

if __name__ == '__main__':
    main()


def my_function():
    print('t')

print(my_function)
print('Functions are object', isinstance(my_function, object))

# You can use variables to store functions

test = my_function
test()

# You can use variables to store functions

my_list = [ ]
my_list.append(my_function)
print(my_list)

# You can pass functions as parameters

def call_passed_function(incoming):
    print('Calling!')
    incoming()
    print('Called!')

call_passed_function(my_function)

# You can not call uncallable things:

try:
    d = 2
    d()  # but you can try
except TypeError as e:
    print('It is not a function', e)

# You can check if something could be called

print(callable(len), callable(45), callable(callable))

# You can return function from a function

def return_min_function():
    return min

test = return_min_function()
min_value = test(4, 5, -9, 12)
print('Min value is', min_value)

# Local scope

def scoped_function(arg):
    value = arg * 10
    print(value)

scoped_function(2)
print(scoped_function(2))

def return_some(input_value):
    calc = input_value - 7
    return calc

print()
return_some(2)
print(return_some(2))

SOME_VAR = 'value'

def print_var():
    print(SOME_VAR)

print_var()

def modify_var():
    try:
        SOME_VAR += '_extra'
    except UnboundLocalError as e:
        print('Error', e)

modify_var()
print(SOME_VAR)

GLOBAL_LIST = []

def appand_list(item):
    print('Adding', item)
    GLOBAL_LIST.append(item)

appand_list(1)
appand_list(2)
print(GLOBAL_LIST)


import numpy as N
import tables as T
import re
import pymses
from tempfile import mkstemp
from os import listdir
from os.path import basename, dirname
from time import time
from pymses.utils import constants as C
from pymses.sources.ramses.output import RamsesOutput
from pymses.sources.ramses.octree import CameraOctreeDatasource
from pymses.sources.ramses.filename_utils import search_valid_outputs
from pymses.utils.regions import Box
from pymses.analysis import *
from pymses.analysis.visualization import *
from pymses.filters.cell_to_points import *
from pymses.filters.region_filter import *
from .utils import get_appropriate_unit
from ..view.dialogs import *

class RamsesModel:#{{{

	tunit_dict = {'yr': C.year, 'Myr': C.Myr, 'Gyr': C.Gyr}

	def __init__(self):
		self.ramses_dir = None
		self.iout_list = None
		self.selected_iout_index = 0
		self.ro = None
		self.cmap = "jet"
		self.source = None
		self.reload_dset = True
		self.reload_dset_RGBA = True
		self.source_camera = None

	def reset(self):
		self.source = None
		self.reload_dset = True
		self.dset_loaded_RGBA = False
		self.source_camera = None

	def BuildSource(self, cam, fields_to_read=None, ngrid_max=None):
		if fields_to_read!=None:
			# remember fields to read and ngrid_max
			self.fields_to_read = fields_to_read
			self.ngrid_max = ngrid_max

		# CameraOctreeDatasource creation
		source = self.ro.amr_source(self.fields_to_read)
		esize = 0.5**(self.ro.info["levelmin"]+1)
		cod = CameraOctreeDatasource(cam, esize, source, \
				ngrid_max=self.ngrid_max, include_split_cells=True)
		self.source = cod.dset
		self.source_camera = cam
		self.reload_dset = True
		self.dset_loaded_RGBA = False
		# Clear map engine dictionary to force creation of new map engines
		# that take into account this source
		self.map_engine_dict.clear()

	def SearchValidOutputs(self, out_dir):#{{{
		"""
		Search for valid RAMSES outputs in the out_dir directory
		Records the ramses_dir and the sorted iout_list if valid outputs are found and return True
		Return False if none is found
		"""
		if out_dir is None:
			if self.ramses_dir is None:
				return False, 0
			else:
				out_dir = self.ramses_dir
		ilist = search_valid_outputs(out_dir)
		ok = (len(ilist) > 0)
		self.selected_iout_index = 0
		if not ok :
			# try to see if up directory is not already a good directory
			out_up_dir = dirname(out_dir)
			ilist = search_valid_outputs(out_up_dir)
			ok = (len(ilist) > 0)
			if ok:
				# Find output number iout
				outName = basename(out_dir)
				iout_regexp = re.compile("[0-9]{5}")
				iout_parse = iout_regexp.findall(outName)
				if len(iout_parse) > 0:
					iout = int(iout_parse[0])
					self.selected_iout_index = ilist.index(iout)
				self.iout_list = ilist
				self.ramses_dir = out_up_dir
		else:
			self.iout_list = ilist
			self.ramses_dir = out_dir
		return ok, self.selected_iout_index
	#}}}

	def GetvalidOutputsList(self):
		return self.iout_list

	def SetRamsesOutput(self, iout_index=None, iout=None):#{{{
		"""
		If iout is in self.iout_list :
		- Sets the chosen RamsesOutput according to the iout number
		- Init. the region size (boxlen)
		- Return True

		Return False if not.
		"""
		if iout_index is not None:
			if not iout_index in range(len(self.iout_list)):
				return False
			self.selected_iout_index = iout_index
			iout = self.iout_list[iout_index]
		else:
			self.selected_iout_index = self.iout_list.index(iout)
		self.ro = RamsesOutput(self.ramses_dir, iout)
		self.freeTheMemory()
		self.SetRegionSizeUnit(self.ro.info["unit_length"])
		return True
	#}}}

	def GetOutputTime(self):#{{{
		t = self.ro.info["unit_time"] * self.ro.info["time"]
		return get_appropriate_unit(t, RamsesModel.tunit_dict)
	#}}}

	def BuildPreviewCube(self):
		cam = self.get_los_camera(25)
		bb=cam.get_bounding_box()
		source = self.ro.amr_source(["rho"])
		from pymses.analysis import amr2cube
		t0 = time()
		res = cam.get_required_resolution()
		self.preview_cube = amr2cube(source, "rho", bb.min_coords, bb.max_coords, res)
		print("Preview amr2cube time = %.3fs"%(time() - t0), "size =",\
			self.preview_cube.shape, "octree level =", res)

	def FindGalaxyAxis(self, gui):
		cam = self.get_los_camera(256)
		# get the rho map engine :
		# this code comes from model.region_finder.UpdateRegionFinderMaps()
		# TODO : regroup this duplicated code !
		me_key="density"
		if me_key not in self.map_engine_dict:
			self.map_engine_dict[me_key] = map_engine(self,
							me_key, self.ro, self.source)
		me = self.map_engine_dict[me_key]
		# get the map processor :
		if me.mp == None:
			me.mp = fft_projection.MapFFTProcessor(me.source,
				me.ramses_output.info, remember_data=True,
				cache_dset=self.amr_files_cache_dset, pre_flatten=True)
		me.mp.prepare_data(cam, me.field_list) # prepare data with the first camera
		from pymses.analysis import find_galaxy_axis
		cam.los_axis = find_galaxy_axis(me.mp.filtered_source, cam, nbSample=2000)
		self.LoadLosCamera(cam)
		gui.reset()

	def FindCenter(self, gui):
		cam = self.get_los_camera(256)
		# get the rho map engine :
		# this code comes from model.region_finder.UpdateRegionFinderMaps()
		# TODO : regroup this duplicated code !
		me_key="density"
		if me_key not in self.map_engine_dict:
			self.map_engine_dict[me_key] = map_engine(self,
							me_key, self.ro, self.source)
		me = self.map_engine_dict[me_key]
		# get the map processor :
		if me.mp == None:
			me.mp = fft_projection.MapFFTProcessor(me.source,
				me.ramses_output.info, remember_data=True,
				cache_dset=self.amr_files_cache_dset, pre_flatten=True)
		me.mp.prepare_data(cam, me.field_list) # prepare data with the first camera
		from pymses.analysis import find_center_of_mass
		cam.center = find_center_of_mass(me.mp.filtered_source, cam, nbSample=1E5)
		self.LoadLosCamera(cam)
		gui.reset()

	def FindLos(self, gui):
		cam = self.get_los_camera(256)
		# get the rho map engine :
		# this code comes from model.region_finder.UpdateRegionFinderMaps()
		# TODO : regroup this duplicated code !
		me_key="velocity"
		if me_key not in self.map_engine_dict:
			self.map_engine_dict[me_key] = map_engine(self,
							me_key, self.ro, self.source)
		me = self.map_engine_dict[me_key]
		# get the map processor :
		if me.mp == None:
			me.mp = fft_projection.MapFFTProcessor(me.source,
				me.ramses_output.info, remember_data=True,
				cache_dset=self.amr_files_cache_dset, pre_flatten=True)
		me.mp.prepare_data(cam, me.field_list) # prepare data with the first camera
		from pymses.analysis import find_los
		cam.los_axis = find_los(me.mp.filtered_source, cam, nbSample=1E5)
		self.LoadLosCamera(cam)
		gui.reset()
#}}}

class MapEngine(object):#{{{
	def __init__(self, model, field_list, ramses_output, use_stars_particle_source=False,
		     use_dm_particle_source=False, source=None):
		"""
			Turn the multiprocessing option to True to compute the region finder
			maps in parallel only if there is a lot of memory availale on the machine
		"""
		self.model = model
		self.field_list = field_list
		self.ramses_output = ramses_output
		if use_stars_particle_source:
			self.source = self.ramses_output.particle_source(self.field_list, select_dark_matter=False)
		elif use_dm_particle_source:
			self.source = self.ramses_output.particle_source(self.field_list, select_stars=False)
		elif source == None and self.ramses_output != None:
			self.source = self.ramses_output.amr_source(self.field_list)
		else:
			self.source = source
		self.mp = None
		self.use_camera_lvlmax = True
		self.log_sensitive = True
		self.fraction = 0.1

	def MakeMaps(self, cam_dict, cmap, multiprocessing, FFTkernelSizeFactor, random_shift,
			cache_dset, stars_age_instensity_dimming=False):#{{{
		# Map computation
		self.map_h5files={}
		if self.mp == None:
			self.mp = fft_projection.MapFFTProcessor(self.source,
				self.ramses_output.info, remember_data=True,
				cache_dset=cache_dset, use_camera_lvlmax=self.use_camera_lvlmax, pre_flatten=True)
		self.mp.prepare_data(list(cam_dict.values())[0], self.field_list) # prepare data with the first camera
		map_name_list = []
		isStarsParticles = self.getMapName()=="stars_particles_Vlos"
		scal_func = self.getMapOperator(next(iter(cam_dict.values())))
		if not self.log_sensitive:
			for c in list(cam_dict.values()):
				c.log_sensitive = False
		if multiprocessing:
			try:
				from multiprocessing import Process, Pipe, cpu_count
				if cpu_count() == 1:
					raise(Exception) # don't use multiprocessing if there is only one cpu
				print('Multiprocessing Activated')
				p={}
				parent_conn={}
				child_conn={}
				def process_cam(self, axis, cam, conn):
					# Map parameters
					mapname = "wx_AMRViewer_%s_%s"%(self.getMapName(),axis)
					fhandle, fname = mkstemp(prefix=mapname, suffix=".h5")
					mname = basename(fname)[:-3]
					tdir = dirname(fname)
					conn.send(fname)
					mmap = self.mp.process(scal_func, cam, surf_qty=self.IsSurfQuantity(),
						FFTkernelSizeFactor=FFTkernelSizeFactor, random_shift=random_shift,
						data_already_prepared=True,
						stars_age_instensity_dimming=(stars_age_instensity_dimming and isStarsParticles))
					mu = self.getMapUnit()
					au = self.ramses_output.info["unit_length"]
					self.map_h5files[axis] = save_map_HDF5(mmap, cam, unit=mu,
									scale_unit=au, hdf5_path=tdir, map_name=mname)
					conn.send(self.map_h5files[axis])
					conn.close()

				# Start process
				for axis, cam in cam_dict.items():
					parent, child = Pipe()
					parent_conn[axis] = parent
					child_conn[axis] = child
					p[axis] = Process(target=process_cam, args=(self, axis, cam, child_conn[axis]))
					p[axis].start()
				# End Process
				for axis, cam in cam_dict.items():
					map_name_list.append(parent_conn[axis].recv())
					self.map_h5files[axis] = parent_conn[axis].recv()
					p[axis].join()
			except Exception:
				print('WARNING: multiprocessing unavailable')
				multiprocessing = False
		if not multiprocessing:
			for axis, cam in cam_dict.items():
				# Map parameters
				mapname = "wx_AMRViewer_%s_%s"%(self.getMapName(),axis)
				fhandle, fname = mkstemp(prefix=mapname, suffix=".h5")
				mname = basename(fname)[:-3]
				tdir = dirname(fname)
				map_name_list.append(fname)
				mmap = self.mp.process(scal_func, cam, surf_qty=self.IsSurfQuantity(),
					FFTkernelSizeFactor=FFTkernelSizeFactor, random_shift=random_shift,
					data_already_prepared=True,
					stars_age_instensity_dimming=(stars_age_instensity_dimming and isStarsParticles))
				mu = self.getMapUnit()
				au = self.ramses_output.info["unit_length"]
				self.map_h5files[axis] = save_map_HDF5(mmap, cam, unit=mu,
						scale_unit=au, hdf5_path=tdir, map_name=mname)
		self.mp.free_filtered_source()# Free filtered data
		return map_name_list
	#}}}

	def MakeImage(self, map_name_list_or_img_dict, axis_keys, cmap, adaptive_gaussian_blur,\
			ramses_output=None, verbose = True):
		if isinstance(map_name_list_or_img_dict, list):
			def h5f_iter():
				for map_name in map_name_list_or_img_dict:
					yield map_name
			img_iter = save_HDF5_seq_to_img(h5f_iter, cmap=cmap,\
				adaptive_gaussian_blur=adaptive_gaussian_blur, fraction=self.fraction,\
				ramses_output=ramses_output, verbose=verbose,\
				log_sensitive=self.log_sensitive)
			imglist = [img for img in img_iter()]
			img_dict = dict(list(zip(axis_keys, imglist)))
			return img_dict
		else:
			imglist=[]
			for axis in axis_keys:
				imglist.append(map_name_list_or_img_dict[axis])
			img_dict = dict(list(zip(axis_keys, imglist)))
			return img_dict

	def GetMapArrays(self):#{{{
		"""
		Get the numpy.array of the maps contained in each HDF5 file of
		the self.h5files dict.
		The returned maps are maskred and clipped.
		"""
		ma = {}
		for axis, h5fname in self.map_h5files.items():
			h5f = T.openFile(h5fname, 'r')
			cam = Camera.from_HDF5(h5f)
			map = h5f.getNode("/map/map").read()
			try :
				map_mask = h5f.getNode("/map/map_mask").read()
			except Exception:
				map_mask = numpy.ones(map.shape, "int8")
			h5f.close()
			nx, ny = map.shape
#			map = map.transpose()
#			map_mask = map_mask.transpose()
			if cam.log_sensitive and pymses.__revision__ >= '$Revision: 705$':
				map = apply_log_scale(map)
			vmin, vmax = get_map_range(map[(map_mask>0.)], cam.log_sensitive, None, self.fraction)
			map = N.clip(map[:,::-1], vmin, vmax) # map[:,::-1] <-> map.FLIP_LEFT_RIGHT
			if cam.log_sensitive:
				map = 10.**map
			ma[axis] = map
		return ma
	#}}}

	def getMapName(self):
		raise NotImplementedError()

	def getUnitDict(self):
		raise NotImplementedError()

	def getMapUnit(self):
		raise NotImplementedError()

	def getMapOperator(self, cam):
		raise NotImplementedError()

	def IsSurfQuantity(self):
		return False

#}}}

class RayTraceEngine(MapEngine):#{{{
	def __init__(self, model, ramses_output, source, fl=[]):
		self.model = model
		self.ramses_output = ramses_output
		self.source = source
		self.rt = raytracing.RayTracer(ramses_output, fl)
		self.log_sensitive = False
		self.fraction = 0.1

	def MakeMaps(self, cam_dict, cmap, multiprocessing, FFTkernelSizeFactor,
			random_shift, cache_dset, stars_age_instensity_dimming=False):#{{{
		# Map computation
		self.map_h5files={}
		map_name_list = []
		axis, cam = list(cam_dict.keys())[0], list(cam_dict.values())[0]
		# Map parameters
		mapname = "wx_AMRViewer_%s_%s"%(self.getMapName(),axis)
		fhandle, fname = mkstemp(prefix=mapname, suffix=".h5")
		mname = basename(fname)[:-3]
		tdir = dirname(fname)
		map_name_list.append(fname)
		scal_func = self.getMapOperator(cam)
		mmap = self.rt.process(scal_func, cam, surf_qty=self.IsSurfQuantity())
		mu = self.getMapUnit()
		au = self.ramses_output.info["unit_length"]
		self.map_h5files[axis] = save_map_HDF5(mmap, cam, unit=mu,\
			scale_unit=au, hdf5_path=tdir, map_name=mname)
		return map_name_list
	#}}}

	@classmethod
	def is_map_engine_for(cls, map_type):
		return map_type == "levelmax"

	def getMapName(self):
		return "amr_max_ref_level"

	def getMapUnit(self):
		return C.none

	def getUnitDict(self):
		d = {"": C.none}
		return d

	def getMapOperator(self, cam):
		op = MaxLevelOperator()
		return op
#}}}

class RayTraceDensityEngine(RayTraceEngine, MapEngine):#{{{
	def __init__(self, model, ramses_output, source):
		RayTraceEngine.__init__(self, model, ramses_output, source, fl=["rho"])
		self.log_sensitive = True

	def MakeBothMaps(self, cam_dict, me_levelmax):#{{{
		# Map computation
		self.map_h5files={}
		map_name_list = []
		map_name_list_levelmax = []
		axis, cam = list(cam_dict.keys())[0], list(cam_dict.values())[0]
		# Map parameters
		mapname = "wx_AMRViewer_%s_%s"%(self.getMapName(),axis)
		mapname_levelmax = "wx_AMRViewer_%s_%s"%(me_levelmax.getMapName(),axis)
		fhandle, fname = mkstemp(prefix=mapname, suffix=".h5")
		fhandle, fname_levelmax = mkstemp(prefix=mapname_levelmax, suffix=".h5")
		mname = basename(fname)[:-3]
		mname_levelmax = basename(fname_levelmax)[:-3]
		tdir = dirname(fname)
		map_name_list.append(fname)
		map_name_list_levelmax.append(fname_levelmax)
		scal_func = self.getMapOperator(cam)

		rt = raytracing.OctreeRayTracer(self.source)
		mmap, mmap_levelmax = rt.process(scal_func, cam,
			surf_qty=self.IsSurfQuantity(), rgb=False, use_openCL=self.model.use_openCL,
			dataset_already_loaded=not self.model.reload_dset,
			reload_scalar_field=self.model.dset_loaded_RGBA)
		if self.model.use_openCL:
			self.model.reload_dset=False
			self.model.dset_loaded_RGBA = False
		mu = self.getMapUnit()
		au = self.ramses_output.info["unit_length"]
		self.map_h5files[axis] = save_map_HDF5(mmap, cam, unit=mu,\
			scale_unit=au, hdf5_path=tdir, map_name=mname)
		cam.log_sensitive = False
		mu = me_levelmax.getMapUnit()
		me_levelmax.map_h5files={}
		me_levelmax.map_h5files[axis] = save_map_HDF5(mmap_levelmax, cam, unit=mu,\
			scale_unit=au, hdf5_path=tdir, map_name=mname_levelmax)
		return map_name_list, map_name_list_levelmax, mmap_levelmax
	#}}}

	@classmethod
	def is_map_engine_for(cls, map_type):
		return map_type == "densityRT"

	def getMapName(self):
		return "gas_densityRT"

	def getMapUnit(self):
		return self.ramses_output.info["unit_density"]

	def getUnitDict(self):
		d = {"H/cc": C.H_cc}
		return d

	def getMapOperator(self, cam):
		#num_func = lambda dset: (dset["rho"]**2)
		#denom_func = lambda dset: (dset["rho"])
		#op = FractionOperator(num_func, denom_func)
		op = ScalarOperator(lambda dset: (dset["rho"]))
		op.max_alos=True
		return op

class MassWeightedDensityMapEngine(MapEngine):#{{{
	def __init__(self, model, ramses_output, source):
		MapEngine.__init__(self, model, ["rho"], ramses_output, source=source)

	@classmethod
	def is_map_engine_for(cls, map_type):
		return map_type == "density"

	def getMapName(self):
		return "gas_mw_density"

	def getMapUnit(self):
		return self.ramses_output.info["unit_density"]

	def getUnitDict(self):
		d = {"H/cc": C.H_cc}
		return d

	def getMapOperator(self, cam):
		num_func = lambda dset: (dset["rho"]**2 * dset.get_sizes()**3)
		denom_func = lambda dset: (dset["rho"] * dset.get_sizes()**3)
		return FractionOperator(num_func, denom_func)
#}}}

class SurfaceDensityMapEngine(MapEngine):#{{{
	def __init__(self, model, ramses_output, source):
		MapEngine.__init__(self, model, ["rho"], ramses_output, source=source)

	@classmethod
	def is_map_engine_for(cls, map_type):
		return map_type == "Sigma"

	def getMapName(self):
		return "gas_Sigma"

	def getUnitDict(self):
		d = {"Msun/pc^2": C.Msun/C.pc**2}
		return d

	def getMapUnit(self):
		u = self.ramses_output.info["unit_density"] * \
				self.ramses_output.info["unit_length"]
		return u

	def getMapOperator(self, cam):
		f = ScalarOperator(lambda dset: (dset["rho"] * dset.get_sizes()**3))
		return f

	def IsSurfQuantity(self):
		return True
#}}}

class MassWeightedTemperatureMapEngine(MapEngine):#{{{
	def __init__(self, model, ramses_output, source):
		MapEngine.__init__(self, model, ["P", "rho"], ramses_output, source=source)

	@classmethod
	def is_map_engine_for(cls, map_type):
		return map_type == "temperature"

	def getMapName(self):
		return "gas_mw_T"

	def getUnitDict(self):
		d = {"K": C.K}
		return d

	def getMapUnit(self):
		return self.ramses_output.info["unit_temperature"]

	def getMapOperator(self, cam):
		num_func = lambda dset: (dset["P"] * dset.get_sizes()**3)
		denom_func = lambda dset: (dset["rho"] * dset.get_sizes()**3)
		return FractionOperator(num_func, denom_func)
#}}}

# Line-of-sight velocity map engines {{{
class MassWeightedVelocityDispMapEngine(MapEngine):#{{{
	def __init__(self, model, ramses_output, source):
		MapEngine.__init__(self, model, ["vel", "rho"], ramses_output, source=source)
		self.log_sensitive = False

	@classmethod
	def is_map_engine_for(cls, map_type):
		return map_type == "velocity"

	def getMapName(self):
		return "gas_mw_V"

	def getUnitDict(self):
		d = {"km/s": C.km/C.s}
		return d

	def getMapUnit(self):
		return self.ramses_output.info["unit_velocity"]

	def getMapOperator(self, cam):
		num_func = lambda dset: (-N.sum(cam.los_axis[N.newaxis,:] * dset["vel"], axis=1) *\
				dset["rho"] * dset.get_sizes()**3)
		denom_func = lambda dset: (dset["rho"] * dset.get_sizes()**3)
		return FractionOperator(num_func, denom_func)

#}}}

class DmParticleMassMapEngine(MapEngine):#{{{
	def __init__(self, model, ramses_output, source):
		MapEngine.__init__(self, model, ["mass", "level"], ramses_output,\
			use_dm_particle_source=True, source=source)
		self.use_camera_lvlmax = False

	@classmethod
	def is_map_engine_for(cls, map_type):
		return map_type == "dm_particles"

	def getMapName(self):
		return "dm_particles_Vlos"

	def getUnitDict(self):
		d = {"Msun/pc^2": C.Msun/C.pc**2}
		return d

	def getMapUnit(self):
		u = self.ramses_output.info["unit_mass"] / \
				self.ramses_output.info["unit_length"]**2
		return u

	def getMapOperator(self, cam):
		return ScalarOperator(lambda dset: dset["mass"])

	def IsSurfQuantity(self):
		return True
#}}}

class StarsParticleMassMapEngine(MapEngine):#{{{
	def __init__(self, model, ramses_output, source):
		MapEngine.__init__(self, model, ["mass", "level", "epoch"], ramses_output,\
			use_stars_particle_source=True, source=source)
		self.use_camera_lvlmax = False

	@classmethod
	def is_map_engine_for(cls, map_type):
		return map_type == "stars_particles"

	def getMapName(self):
		return "stars_particles_Vlos"

	def getUnitDict(self):
		d = {"Msun/pc^2": C.Msun/C.pc**2}
		return d

	def getMapUnit(self):
		u = self.ramses_output.info["unit_mass"] / \
				self.ramses_output.info["unit_length"]**2
		return u

	def getMapOperator(self, cam):
		return ScalarOperator(lambda dset: dset["mass"])

	def IsSurfQuantity(self):
		return True
#}}}

class TransferRayTraceEngine(MapEngine):#{{{
	def __init__(self, model, ramses_output, source):
		self.model = model
		self.ramses_output = ramses_output
		self.source = source
		self.log_sensitive = False
		self.fraction = 0.1

	def MakeMaps(self, cam_dict, cmap, multiprocessing, FFTkernelSizeFactor,
		     random_shift, cache_dset, stars_age_instensity_dimming=False):#{{{
		# Map computation
		img_dict={}
		self.map_array = {}
		if self.source != None:
			rt = raytracing.OctreeRayTracer(self.source)
		else:
			rt = raytracing.OctreeRayTracer(self.ramses_output, ["rho"])
		for axis, cam in cam_dict.items():
			cltf = ColorLinesTransferFunction( (-5.0, 2.0) )
			cltf.add_line(-2.0, 0.1)
			cltf.add_line(.0, 0.1)
			cltf.add_line(2., 0.1)
			cam.set_color_transfer_function(cltf)
			# We add 1e-8 to avoid NaN and -Inf log result
			# problems with approximative null values
			op = ScalarOperator(lambda dset: N.log10(dset["rho"]+1e-8))
			img_dict[axis] = rt.process(op, cam, use_openCL=self.model.use_openCL,
						dataset_already_loaded=not self.model.reload_dset,
						reload_scalar_field=not self.model.dset_loaded_RGBA).convert("RGBA")
			if self.model.use_openCL:
				self.model.reload_dset = False
				self.model.dset_loaded_RGBA = True
			self.map_array[axis] =  N.zeros(cam.get_map_size())
		return img_dict
	#}}}

	def GetMapArrays(self):#{{{
		return self.map_array

	@classmethod
	def is_map_engine_for(cls, map_type):
		return map_type == "transfer_function"

	def getMapName(self):
		return "transfer_function_map"

	def getMapUnit(self):
		return C.none

	def getUnitDict(self):
		d = {"": C.none}
		return d
#}}}

# Line-of-sight velocity map engines {{{
class CustomMapEngine(MapEngine):#{{{
	def __init__(self, model, ramses_output, source):
		dlg = FieldsToLoadFileDialog(self)
		dlg.ShowModal()
		s = dlg.fieldTextCtrl.GetValue()
		exec(s)
		MapEngine.__init__(self, model, field_to_load, ramses_output, source=source)

	@classmethod
	def is_map_engine_for(cls, map_type):
		return map_type == "custom"

	def getMapName(self):
		return "custom_map"

	def getMapUnit(self):
		return C.none

	def getUnitDict(self):
		return {"(?)": C.none}

	def getMapOperator(self, cam):
		dlg = customFileDialog(self)
		dlg.ShowModal()
		#self.log_sensitive = dlg.logCheckBox.GetValue()
		return dlg.op

#}}}

class hdf5ViewerEngine(MapEngine):#{{{
	def __init__(self, model, ramses_output, source):
		self.model = model
		self.ramses_output = ramses_output
		self.log_sensitive = False
		self.fraction = 0.1

	def GetMapArrays(self):#{{{
		return self.map_array

	@classmethod
	def is_map_engine_for(cls, map_type):
		return map_type == "hdf5"

	def getMapName(self):
		return "hdf5_map"
#}}}

def map_engine(model, map_type, ramses_output, source=None):#{{{
	for cls in MapEngine.__subclasses__():
		if cls.is_map_engine_for(map_type):
			return cls(model, ramses_output, source)
	raise ValueError("No MapEngine available for map type '%s'"%map_type)
#}}}


from time import time
from Crypto.Hash import SHA256
import json
import requests

class Blockchain(object):
    current_difficulty = 5
    def __init__(self):
        self.current_transactions = []
        self.chain = []
        self.peers = []
        self.peer_chains = []
        self.transaction_pool = []
        #Build genesis block
        self.new_block()

    @classmethod
    def hash(cls, data):
        return SHA256.new(data).hexdigest()

    @classmethod
    def validate_block(cls,block,difficulty):
        if difficulty == 0: return True
        target = ""
        for index in range(0,difficulty):
            target = target + "0"

        hash = Blockchain.hash(json.dumps(block).encode())
        return hash[:difficulty] == target

    @classmethod
    def proof_of_work(cls,block,difficulty):
        nonce = 0
        while True:
            block['nonce'] = nonce
            if Blockchain.validate_block(block,difficulty) == True : break
            nonce = nonce + 1
        return nonce

    def new_block(self):
        if len(self.chain) > 0 :
            prev_hash = Blockchain.hash(json.dumps(self.chain[-1]).encode())
        else:
            prev_hash = 1
        block = {
                'index' : len(self.chain),
                'timestamp' : time(),
                'transactions' : self.current_transactions,
                'prev_hash' : prev_hash,
                }

        # ================== Proof of Work ==========================
        # Do proof of work to get the proper nonce
        nonce = Blockchain.proof_of_work(block,Blockchain.current_difficulty)
        # Add nonce to the new block
        block['nonce'] = nonce
        # ===========================================================
        self.chain.append(block)
        self.current_transactions = []
        return block

    @classmethod
    def validate_chain_timesequence(cls,prev,curr):
        return prev['timestamp'] < curr['timestamp']

    @classmethod
    def validate_chain_hash(cls,prev,curr):
        calc_hash = Blockchain.hash(json.dumps(prev).encode())
        target_hash = curr['prev_hash']
        return calc_hash == target_hash

    @classmethod
    def validate_chain(cls,chain):
        chain_length = len(chain)
        for index in range(1,chain_length):
            test = {}
            prev = chain[index-1]
            curr = chain[index]
            test['timestamp'] = Blockchain.validate_chain_timesequence(prev,curr)
            test['hash'] = Blockchain.validate_chain_hash(prev,curr)
            test['block'] = Blockchain.validate_block(curr,Blockchain.current_difficulty)
            test['result'] = (test['timestamp'] == True and test['hash'] == True and test['block'] == True)
            if test['result'] != True:
                test['curr'] = curr
                return test

        test = {}
        test['result'] = True
        return test
    def new_transaction(self, amount):
        self.current_transactions.append({
            'amount' : amount
            })
    def add_peer(self,peer):
        self.peers.append(peer)

    def collect(self):
        self.peer_chains = []
        newChain = False
        for peer in self.peers:
            peer_url =  "http://" + str(peer) + "/block/list"
            response = requests.get(peer_url)

        if response.status_code == 200:
            length = response.json()['length']
            chain = response.json()['list']
            validity = response.json()['validity']['result']
            if validity == True:
                self.peer_chains.append(chain)
                newChain = True
        return newChain

    def consensus(self):
        candidate_chain = self.chain
        for chain in self.peer_chains:
            if len(candidate_chain) < len(chain):
                candidate_chain = chain
        self.chain = candidate_chain
        self.peer_chains = []
        return self.chain


# coding: utf-8
"""
Launch StaSh in a more flexible and reliable way.
"""
import sys
import argparse

module_names = (
    'stash',
    'system.shcommon',
    'system.shstreams',
    'system.shscreens',
    'system.shui',
    'system.shui.base',
    'system.shio',
    'system.shiowrapper',
    'system.shparsers',
    'system.shruntime',
    'system.shthreads',
    'system.shuseractionproxy',
    'system.shhistory',
)

# Attempt to reload modules when startup, does not seem to work
if 'stash.stash' in sys.modules:
    for name in module_names:
        sys.modules.pop('stash.' + name)
from stash import stash

ap = argparse.ArgumentParser()
ap.add_argument('--no-cfgfile', action='store_true', help='do not load external config files')
ap.add_argument('--no-rcfile', action='store_true', help='do not load external resource file')
ap.add_argument('--no-historyfile', action='store_true', help='do not load history file from last session')
ap.add_argument(
    '--log-level',
    choices=['DEBUG',
             'INFO',
             'WARN',
             'ERROR',
             'CRITICAL'],
    default='INFO',
    help='the logging level'
)
ap.add_argument('--log-file', help='the file to send logging messages')
ap.add_argument('--debug-switch', default='', help='a comma separate list to turn on debug switch for components')
ap.add_argument('-c', '--command', default=None, dest='command', help='command to run')
ap.add_argument('args',  # the editor shortcuts may pass additional arguments
                nargs='*',
                help='additional arguments (ignored)')
ns = ap.parse_args()

log_setting = {
    'level': ns.log_level,
    'file': ns.log_file,
}

if ns.debug_switch == '':
    debug = (
        # stash._DEBUG_STREAM,
        # stash._DEBUG_RENDERER,
        # stash._DEBUG_MAIN_SCREEN,
        # stash._DEBUG_MINI_BUFFER,
        # stash._DEBUG_IO,
        # stash._DEBUG_UI,
        # stash._DEBUG_TERMINAL,
        # stash._DEBUG_TV_DELEGATE,
        # stash._DEBUG_RUNTIME,
        # stash._DEBUG_PARSER,
        # stash._DEBUG_EXPANDER,
        # stash._DEBUG_COMPLETER,
    )
elif ns.debug_switch == "all":
    debug = []
    for key in dir(stash):
        if key.startswith("_DEBUG_"):
            value = getattr(stash, key, None)
            if value is not None:
                debug.append(value)
else:
    debug = []
    for ds in ns.debug_switch.split(','):
        ds = getattr(stash, '_DEBUG_{}'.format(ds.upper()), None)
        if ds is not None:
            debug.append(ds)

if ns.command:
    # tell StaSh not to run any command if command is passed
    # (we will call the command manually later)
    ctp = False
else:
    # tell StaSh to run the default command (totd.py)
    ctp = None

_stash = stash.StaSh(
    debug=debug,
    log_setting=log_setting,
    no_cfgfile=ns.no_cfgfile,
    no_rcfile=ns.no_rcfile,
    no_historyfile=ns.no_historyfile,
    command=ctp,
)

_stash.launch(ns.command)
if ns.command is not None:
    # TODO: _stash.launch() may block, which prevents this from being executed
    _stash(ns.command, add_to_history=False, persistent_level=0)


import os, shutil, subprocess, sys, re

import libcalamares

from libcalamares.utils import check_target_env_call, target_env_call, debug
from os.path import join

class OperationTracker:
	def __init__(self):
		self._downloaded = 0
		self._installed = 0
		self._total = 0
		self._progress = float(0)

	@property
	def downloaded(self):
		return self._downloaded

	@downloaded.setter
	def downloaded(self, value):
		self._downloaded = value

	@property
	def installed(self):
		return self._installed

	@installed.setter
	def installed(self, value):
		self._installed = value

	@property
	def total(self):
		return self._total

	@total.setter
	def total(self, value):
		self._total = value

	@property
	def progress(self):
		return self._progress

	@progress.setter
	def progress(self, value):
		self._progress = value

	def send_progress(self, counter, phase):
		for p in range(phase):
			if self.total == 0:
				continue
			step = 0.05
			step += 0.95 * (counter / float(self.total))
			self.progress += step / self.total

			debug("Progress: {}".format(self.progress))

		libcalamares.job.setprogress(self.progress)

ON_POSIX = 'posix' in sys.builtin_module_names

class PacmanController:
	def __init__(self, root):
		self.__root = root
		self.__operations = libcalamares.globalstorage.value("packageOperations")
		self.__tracker = OperationTracker()
		self.__keyrings = libcalamares.job.configuration.get('keyrings', [])

	@property
	def tracker(self):
		return self.__tracker

	@property
	def root(self):
		return self.__root

	@property
	def operations(self):
		return self.__operations

	@property
	def keyrings(self):
		return self.__keyrings

	def init_keyring(self):
		target_env_call(["pacman-key", "--init"])

	def populate_keyring(self):
		target_env_call(["pacman-key", "--populate"] + self.keyrings)

	def rank_mirrors(self):
		check_target_env_call(["pacman-mirrors", "-g", "-m", "rank"])

	def parse_output(self, cmd):
		cal_env = os.environ
		cal_env["LC_ALL"] = "C"
		last = []
		phase = 0

		process = subprocess.Popen(cmd, env=cal_env, bufsize=1, stdout=subprocess.PIPE, close_fds=ON_POSIX)

		for line in iter(process.stdout.readline, b''):
			pkgs = re.findall(r'\((\d+)\)', line.decode())
			dl = re.findall(r'downloading\s+(.*).pkg.tar.xz', line.decode())
			inst = re.findall(r'installing(.*)\.\.\.', line.decode())

			if pkgs:
				self.tracker.total = (int(pkgs[0]))
				debug("Number of packages: {}".format(self.tracker.total))

			if dl:
				if dl != last:
					self.tracker.downloaded += 1
					phase = 1
					debug("Downloading: {}".format(dl[0]))
					debug("Downloaded packages: {}".format(self.tracker.downloaded))
					self.tracker.send_progress(self.tracker.downloaded, phase)

				last = dl
			elif inst:
				self.tracker.installed += 1
				phase = 2
				debug("Installing: {}".format(inst[0]))
				debug("Installed packages: {}".format(self.tracker.installed))
				self.tracker.send_progress(self.tracker.installed, phase)

		if process.returncode != 0:
			return process.kill()

		return None

	def install(self, local=False):
		cachedir = join(self.root, "var/cache/pacman/pkg")
		dbdir = join(self.root, "var/lib/pacman")
		args = ["pacman", "--noconfirm"]
		if local:
			args.extend(["-U"])
		else:
			args.extend(["-Sy"])

		args.extend(["--cachedir", cachedir, "--root", self.root, "--dbpath", dbdir])
		cmd =  args + self.operations["install"]
		self.parse_output(cmd)

	def remove(self):
		args = ["chroot", self.root, "pacman", "-Rs", "--noconfirm"]
		cmd = args + self.operations["remove"]
		check_target_env_call(cmd)

	def run(self, rank=False):
		for op in self.operations.keys():
			if op == "install":
				self.install()
			elif op == "localInstall":
				self.install(local=True)
			elif op == "remove":
				self.tracker.total(len(self.operations["remove"]))
				self.remove()

		self.init_keyring()
		self.populate_keyring()
		if rank:
			self.rank_mirrors()

		return None

class ChrootController:
	def __init__(self):
		self.__root = libcalamares.globalstorage.value('rootMountPoint')
		self.__requirements = libcalamares.job.configuration.get('requirements', [])

	@property
	def root(self):
		return self.__root

	@property
	def requirements(self):
		return self.__requirements

	def make_dirs(self):
		for target in self.requirements:
			dest = self.root + target["name"]
			if not os.path.exists(dest):
				debug("Create: {}".format(dest))
				mod = int(target["mode"],8)
				debug("Mode: {}".format(oct(mod)))
				os.makedirs(dest, mode=mod)

	def copy_file(self, file):
		if os.path.exists(os.path.join("/",file)):
			shutil.copy2(os.path.join("/",file), os.path.join(self.root, file))

	def prepare(self):
		cal_umask = os.umask(0)
		self.make_dirs()
		path = join(self.root, "run")
		#debug("Fix permissions: {}".format(path))
		os.chmod(path, 0o755)
		os.umask(cal_umask)
		self.copy_file('etc/pacman-mirrors.conf')
		self.copy_file('etc/resolv.conf')

	def run(self):
		self.prepare()
		pacman = PacmanController(self.root)

		return pacman.run(rank=False)

def run():
	""" Create chroot dirs and install pacman, kernel and netinstall selection """

	targetRoot = ChrootController()

	return targetRoot.run()


#!/usr/bin/python

# Second drive test using Blue Dot joystick
# This time using the piroverlib module
# Used as an initial test for this new module

# Import modules
from bluedot import BlueDot
from signal import pause

# Enable importing from parent directory
import os, sys
currentdir = os.path.dirname(os.path.realpath(__file__))
parentdir = os.path.dirname(currentdir)
sys.path.append(parentdir)

from piroverlib import piRover

# Define pin numbers [A, B]
leftPins=[18,12]
rightPins=[13,19]

print("Starting driving test 3")
pirover=piRover(left=leftPins, right=rightPins)

# Establish blue dot
print("Starting bluedot connection")
bd = BlueDot(cols=2,rows=3)
# Top row, joystick, invisible
bd[1,0].visible=False
# Middle row, gap
bd[0,1].visible=False
bd[1,1].visible=False
# Bottom row, ACW, CW
bd[0,2].color="red"
bd[1,2].color="red"

while True:
    if bd.is_connected:
        break
print("Connected")

# Define functions
def jsMap(i):
    # Takes a value -1 to 1 and maps it to -100 to 100
    j=int(i*100)
    return j

def moveBot(pos):
	# Change colour
    bdJS.color = (255,128,0)
    xin,yin=pos.x, pos.y
    x=jsMap(xin)
    y=jsMap(yin)
    # Send joystick values
    pirover.js(x,y)

def acwTurn(pos):
	bdACW.color = (255,200,0)
	d=pos.distance
	p=jsMap(d)
	# Send negative value
	pirover.spin(-p)

def cwTurn(pos):
	bdCW.color = (255,200,0)
	d=pos.distance
	p=jsMap(d)
	# Send positive value
	pirover.spin(p)

def stop():
	pirover.stop()
	# Restore colours
	bdJS.color = "blue"
	bdCW.color = "red"
	bdACW.color = "red"

# Name the components
bdJS=bd[0,0]    # Joystick
bdACW=bd[0,2]   # Anti-clockwise button
bdCW=bd[1,2]    # clockwise button
bdJS.when_pressed = moveBot
bdJS.when_moved = moveBot

bdACW.when_pressed = acwTurn
bdACW.when_moved = acwTurn

bdCW.when_pressed = cwTurn
bdCW.when_moved = cwTurn

bd.when_released = stop # All buttons stop

pause()
exit(0)