eld from generate_values(state, a, c, m, masked_bits, output_modulus)

""" Provides a general interface fore predicting the output of
Linear Congruential Generators (LCG).

An LCG outputs values with the following recurrence relation:

        state_(n+1) = a * state_n + c (mod m)
        value_n = state_n >> masked_bits

Such generators are widely used as platform default random
number generators.

"""

from math import log, ceil
from foresight.utils import check_enough_values

__all__ = [
    "from_seed",
    "from_outputs"
]

def next_state(state, a, c, m, masked_bits):
    '''
    Determine the next value of a linear congruential generator

    @param state: The current state of the LCG
    @return: The next state, with 'masked_bits' lower order bits removed
    '''
    return ((a * state + c) % m) >> masked_bits

def verify_candidate(possible_state, values, a, c, m, masked_bits,
                     operation=None):
    for value in values:
        if operation is not None:
            if operation(next_state(possible_state, a, c, m, masked_bits)) == value:
                possible_state = next_state(possible_state, a, c, m, masked_bits=0)
            else:
                break
        else:
            if next_state(possible_state, a, c, m, masked_bits) == value:
                possible_state = next_state(possible_state, a, c, m, masked_bits=0)
            else:
                break
    else:
        return possible_state

def predict_state(values, a, c, m, masked_bits, output_modulus=None):
    '''
    Given a list of values from a LCG, predict the internal state

    @param values: A list of consecutive values output from the LCG
    @return: A list of possible internal state values for the LCG
    '''
    if check_enough_values(len(values), log(m, 2) - masked_bits, log(m, 2),
                           output_modulus) is False:
        print("WARNING: Not enough outputs for unique answer. Result may be incorrect.")

    if output_modulus is not None:
        for i in range(ceil(log(m, 2) - masked_bits - log(output_modulus, 2))+1):
            initial = values[0] + i * output_modulus
            for lower_bits in range(2 ** masked_bits):
                possible_state = (initial << masked_bits) + lower_bits
                checked_state = verify_candidate(possible_state,
                                                 values[1:],
                                                 a, c, m, masked_bits,
                                                 lambda x: x % output_modulus)
                if checked_state:
                    return checked_state

    else:
        for lower_bits in range(2 ** masked_bits):
            possible_state = (values[0] << masked_bits) + lower_bits
            checked_state = verify_candidate(possible_state,
                                             values[1:],
                                             a, c, m, masked_bits,
                                             output_modulus)
            if checked_state:
                return checked_state

def generate_values(state, a, c, m, masked_bits, output_modulus=None):
    '''
    Generate a list of values from a linear congruential algorithm.

    @param state: An initial state for the RNG
    @param a: The multiplier
    @param c: The increment
    @param m: The modulus value
    @param masked_bits: The number of lower order bits to drop
    '''

    while(True):
        state = next_state(state, a, c, m, masked_bits=0)
        if output_modulus:
            yield (state >> masked_bits) % output_modulus
        else:
            yield state >> masked_bits

def from_seed(seed, a, c, m, masked_bits, output_modulus=None):
    '''
    Create a continuation that yields random values from an LCG with the given parameters,
    using 'seed' as the initial seed.
    '''
    yield from generate_values(seed, a, c, m, masked_bits, output_modulus)

def from_outputs(prev_values, a, c, m, masked_bits,
                 output_modulus=None, noexcept=False):
    '''
    Create a continuation that yields random values from an LCG with the given parameters,
    recovering the state from the given list of values. Defaults to MSVC constants.
    '''
    state = predict_state(prev_values, a, c, m, masked_bits, output_modulus)

    if state is None:
        if noexcept:
            yield None
        else:
            raise RuntimeError("No viable candidate found. Some values may not be consecutive.")
    yi


yield from generate_values(seed, a, c, m, masked_bits, output_modulus)

""" Provides a general interface fore predicting the output of
Linear Congruential Generators (LCG).

An LCG outputs values with the following recurrence relation:

        state_(n+1) = a * state_n + c (mod m)
        value_n = state_n >> masked_bits

Such generators are widely used as platform default random
number generators.

"""

from math import log, ceil
from foresight.utils import check_enough_values

__all__ = [
    "from_seed",
    "from_outputs"
]

def next_state(state, a, c, m, masked_bits):
    '''
    Determine the next value of a linear congruential generator

    @param state: The current state of the LCG
    @return: The next state, with 'masked_bits' lower order bits removed
    '''
    return ((a * state + c) % m) >> masked_bits

def verify_candidate(possible_state, values, a, c, m, masked_bits,
                     operation=None):
    for value in values:
        if operation is not None:
            if operation(next_state(possible_state, a, c, m, masked_bits)) == value:
                possible_state = next_state(possible_state, a, c, m, masked_bits=0)
            else:
                break
        else:
            if next_state(possible_state, a, c, m, masked_bits) == value:
                possible_state = next_state(possible_state, a, c, m, masked_bits=0)
            else:
                break
    else:
        return possible_state

def predict_state(values, a, c, m, masked_bits, output_modulus=None):
    '''
    Given a list of values from a LCG, predict the internal state

    @param values: A list of consecutive values output from the LCG
    @return: A list of possible internal state values for the LCG
    '''
    if check_enough_values(len(values), log(m, 2) - masked_bits, log(m, 2),
                           output_modulus) is False:
        print("WARNING: Not enough outputs for unique answer. Result may be incorrect.")

    if output_modulus is not None:
        for i in range(ceil(log(m, 2) - masked_bits - log(output_modulus, 2))+1):
            initial = values[0] + i * output_modulus
            for lower_bits in range(2 ** masked_bits):
                possible_state = (initial << masked_bits) + lower_bits
                checked_state = verify_candidate(possible_state,
                                                 values[1:],
                                                 a, c, m, masked_bits,
                                                 lambda x: x % output_modulus)
                if checked_state:
                    return checked_state

    else:
        for lower_bits in range(2 ** masked_bits):
            possible_state = (values[0] << masked_bits) + lower_bits
            checked_state = verify_candidate(possible_state,
                                             values[1:],
                                             a, c, m, masked_bits,
                                             output_modulus)
            if checked_state:
                return checked_state

def generate_values(state, a, c, m, masked_bits, output_modulus=None):
    '''
    Generate a list of values from a linear congruential algorithm.

    @param state: An initial state for the RNG
    @param a: The multiplier
    @param c: The increment
    @param m: The modulus value
    @param masked_bits: The number of lower order bits to drop
    '''

    while(True):
        state = next_state(state, a, c, m, masked_bits=0)
        if output_modulus:
            yield (state >> masked_bits) % output_modulus
        else:
            yield state >> masked_bits

def from_seed(seed, a, c, m, masked_bits, output_modulus=None):
    '''
    Create a continuation that yields random values from an LCG with the given parameters,
    using 'seed' as the initial seed.
    '''

def from_outputs(prev_values, a, c, m, masked_bits,
                 output_modulus=None, noexcept=False):
    '''
    Create a continuation that yields random values from an LCG with the given parameters,
    recovering the state from the given list of values. Defaults to MSVC constants.
    '''
    state = predict_state(prev_values, a, c, m, masked_bits, output_modulus)

    if state is None:
        if noexcept:
            yield None
        else:
            raise RuntimeError("No viable candidate found. Some values may not be consecutive.")
    yield from generate_values(state, a, c, m, masked_bits, output_modulus)


if output_modulus:
            yield (state >> masked_bits) % output_modulus
        else:
            yield state >> masked_bits

""" Provides a general interface fore predicting the output of
Linear Congruential Generators (LCG).

An LCG outputs values with the following recurrence relation:

        state_(n+1) = a * state_n + c (mod m)
        value_n = state_n >> masked_bits

Such generators are widely used as platform default random
number generators.

"""

from math import log, ceil
from foresight.utils import check_enough_values

__all__ = [
    "from_seed",
    "from_outputs"
]

def next_state(state, a, c, m, masked_bits):
    '''
    Determine the next value of a linear congruential generator

    @param state: The current state of the LCG
    @return: The next state, with 'masked_bits' lower order bits removed
    '''
    return ((a * state + c) % m) >> masked_bits

def verify_candidate(possible_state, values, a, c, m, masked_bits,
                     operation=None):
    for value in values:
        if operation is not None:
            if operation(next_state(possible_state, a, c, m, masked_bits)) == value:
                possible_state = next_state(possible_state, a, c, m, masked_bits=0)
            else:
                break
        else:
            if next_state(possible_state, a, c, m, masked_bits) == value:
                possible_state = next_state(possible_state, a, c, m, masked_bits=0)
            else:
                break
    else:
        return possible_state

def predict_state(values, a, c, m, masked_bits, output_modulus=None):
    '''
    Given a list of values from a LCG, predict the internal state

    @param values: A list of consecutive values output from the LCG
    @return: A list of possible internal state values for the LCG
    '''
    if check_enough_values(len(values), log(m, 2) - masked_bits, log(m, 2),
                           output_modulus) is False:
        print("WARNING: Not enough outputs for unique answer. Result may be incorrect.")

    if output_modulus is not None:
        for i in range(ceil(log(m, 2) - masked_bits - log(output_modulus, 2))+1):
            initial = values[0] + i * output_modulus
            for lower_bits in range(2 ** masked_bits):
                possible_state = (initial << masked_bits) + lower_bits
                checked_state = verify_candidate(possible_state,
                                                 values[1:],
                                                 a, c, m, masked_bits,
                                                 lambda x: x % output_modulus)
                if checked_state:
                    return checked_state

    else:
        for lower_bits in range(2 ** masked_bits):
            possible_state = (values[0] << masked_bits) + lower_bits
            checked_state = verify_candidate(possible_state,
                                             values[1:],
                                             a, c, m, masked_bits,
                                             output_modulus)
            if checked_state:
                return checked_state

def generate_values(state, a, c, m, masked_bits, output_modulus=None):
    '''
    Generate a list of values from a linear congruential algorithm.

    @param state: An initial state for the RNG
    @param a: The multiplier
    @param c: The increment
    @param m: The modulus value
    @param masked_bits: The number of lower order bits to drop
    '''

    while(True):
        state = next_state(state, a, c, m, masked_bits=0)

def from_seed(seed, a, c, m, masked_bits, output_modulus=None):
    '''
    Create a continuation that yields random values from an LCG with the given parameters,
    using 'seed' as the initial seed.
    '''
    yield from generate_values(seed, a, c, m, masked_bits, output_modulus)

def from_outputs(prev_values, a, c, m, masked_bits,
                 output_modulus=None, noexcept=False):
    '''
    Create a continuation that yields random values from an LCG with the given parameters,
    recovering the state from the given list of values. Defaults to MSVC constants.
    '''
    state = predict_state(prev_values, a, c, m, masked_bits, output_modulus)

    if state is None:
        if noexcept:
            yield None
        else:
            raise RuntimeError("No viable candidate found. Some values may not be consecutive.")
    yield from generate_values(state, a, c, m, masked_bits, output_modulus)


for lower_bits in range(2 ** masked_bits):
            possible_state = (values[0] << masked_bits) + lower_bits
            checked_state = verify_candidate(possible_state,
                                             values[1:],
                                             a, c, m, masked_bits,
                                             output_modulus)
            if checked_state:
                return checked_state

""" Provides a general interface fore predicting the output of
Linear Congruential Generators (LCG).

An LCG outputs values with the following recurrence relation:

        state_(n+1) = a * state_n + c (mod m)
        value_n = state_n >> masked_bits

Such generators are widely used as platform default random
number generators.

"""

from math import log, ceil
from foresight.utils import check_enough_values

__all__ = [
    "from_seed",
    "from_outputs"
]

def next_state(state, a, c, m, masked_bits):
    '''
    Determine the next value of a linear congruential generator

    @param state: The current state of the LCG
    @return: The next state, with 'masked_bits' lower order bits removed
    '''
    return ((a * state + c) % m) >> masked_bits

def verify_candidate(possible_state, values, a, c, m, masked_bits,
                     operation=None):
    for value in values:
        if operation is not None:
            if operation(next_state(possible_state, a, c, m, masked_bits)) == value:
                possible_state = next_state(possible_state, a, c, m, masked_bits=0)
            else:
                break
        else:
            if next_state(possible_state, a, c, m, masked_bits) == value:
                possible_state = next_state(possible_state, a, c, m, masked_bits=0)
            else:
                break
    else:
        return possible_state

def predict_state(values, a, c, m, masked_bits, output_modulus=None):
    '''
    Given a list of values from a LCG, predict the internal state

    @param values: A list of consecutive values output from the LCG
    @return: A list of possible internal state values for the LCG
    '''
    if check_enough_values(len(values), log(m, 2) - masked_bits, log(m, 2),
                           output_modulus) is False:
        print("WARNING: Not enough outputs for unique answer. Result may be incorrect.")

    if output_modulus is not None:
        for i in range(ceil(log(m, 2) - masked_bits - log(output_modulus, 2))+1):
            initial = values[0] + i * output_modulus
            for lower_bits in range(2 ** masked_bits):
                possible_state = (initial << masked_bits) + lower_bits
                checked_state = verify_candidate(possible_state,
                                                 values[1:],
                                                 a, c, m, masked_bits,
                                                 lambda x: x % output_modulus)
                if checked_state:
                    return checked_state

    else:

def generate_values(state, a, c, m, masked_bits, output_modulus=None):
    '''
    Generate a list of values from a linear congruential algorithm.

    @param state: An initial state for the RNG
    @param a: The multiplier
    @param c: The increment
    @param m: The modulus value
    @param masked_bits: The number of lower order bits to drop
    '''

    while(True):
        state = next_state(state, a, c, m, masked_bits=0)
        if output_modulus:
            yield (state >> masked_bits) % output_modulus
        else:
            yield state >> masked_bits

def from_seed(seed, a, c, m, masked_bits, output_modulus=None):
    '''
    Create a continuation that yields random values from an LCG with the given parameters,
    using 'seed' as the initial seed.
    '''
    yield from generate_values(seed, a, c, m, masked_bits, output_modulus)

def from_outputs(prev_values, a, c, m, masked_bits,
                 output_modulus=None, noexcept=False):
    '''
    Create a continuation that yields random values from an LCG with the given parameters,
    recovering the state from the given list of values. Defaults to MSVC constants.
    '''
    state = predict_state(prev_values, a, c, m, masked_bits, output_modulus)

    if state is None:
        if noexcept:
            yield None
        else:
            raise RuntimeError("No viable candidate found. Some values may not be consecutive.")
    yield from generate_values(state, a, c, m, masked_bits, output_modulus)


while(True):
        state = next_state(state, a, c, m, masked_bits=0)
        if output_modulus:
            yield (state >> masked_bits) % output_modulus
        else:
            yield state >> masked_bits

""" Provides a general interface fore predicting the output of
Linear Congruential Generators (LCG).

An LCG outputs values with the following recurrence relation:

        state_(n+1) = a * state_n + c (mod m)
        value_n = state_n >> masked_bits

Such generators are widely used as platform default random
number generators.

"""

from math import log, ceil
from foresight.utils import check_enough_values

__all__ = [
    "from_seed",
    "from_outputs"
]

def next_state(state, a, c, m, masked_bits):
    '''
    Determine the next value of a linear congruential generator

    @param state: The current state of the LCG
    @return: The next state, with 'masked_bits' lower order bits removed
    '''
    return ((a * state + c) % m) >> masked_bits

def verify_candidate(possible_state, values, a, c, m, masked_bits,
                     operation=None):
    for value in values:
        if operation is not None:
            if operation(next_state(possible_state, a, c, m, masked_bits)) == value:
                possible_state = next_state(possible_state, a, c, m, masked_bits=0)
            else:
                break
        else:
            if next_state(possible_state, a, c, m, masked_bits) == value:
                possible_state = next_state(possible_state, a, c, m, masked_bits=0)
            else:
                break
    else:
        return possible_state

def predict_state(values, a, c, m, masked_bits, output_modulus=None):
    '''
    Given a list of values from a LCG, predict the internal state

    @param values: A list of consecutive values output from the LCG
    @return: A list of possible internal state values for the LCG
    '''
    if check_enough_values(len(values), log(m, 2) - masked_bits, log(m, 2),
                           output_modulus) is False:
        print("WARNING: Not enough outputs for unique answer. Result may be incorrect.")

    if output_modulus is not None:
        for i in range(ceil(log(m, 2) - masked_bits - log(output_modulus, 2))+1):
            initial = values[0] + i * output_modulus
            for lower_bits in range(2 ** masked_bits):
                possible_state = (initial << masked_bits) + lower_bits
                checked_state = verify_candidate(possible_state,
                                                 values[1:],
                                                 a, c, m, masked_bits,
                                                 lambda x: x % output_modulus)
                if checked_state:
                    return checked_state

    else:
        for lower_bits in range(2 ** masked_bits):
            possible_state = (values[0] << masked_bits) + lower_bits
            checked_state = verify_candidate(possible_state,
                                             values[1:],
                                             a, c, m, masked_bits,
                                             output_modulus)
            if checked_state:
                return checked_state

def generate_values(state, a, c, m, masked_bits, output_modulus=None):
    '''
    Generate a list of values from a linear congruential algorithm.

    @param state: An initial state for the RNG
    @param a: The multiplier
    @param c: The increment
    @param m: The modulus value
    @param masked_bits: The number of lower order bits to drop
    '''


""" Provides a general interface fore predicting the output of
Linear Congruential Generators (LCG).

An LCG outputs values with the following recurrence relation:

        state_(n+1) = a * state_n + c (mod m)
        value_n = state_n >> masked_bits

Such generators are widely used as platform default random
number generators.

"""

from math import log, ceil
from foresight.utils import check_enough_values

__all__ = [
    "from_seed",
    "from_outputs"
]

def next_state(state, a, c, m, masked_bits):
    '''
    Determine the next value of a linear congruential generator

    @param state: The current state of the LCG
    @return: The next state, with 'masked_bits' lower order bits removed
    '''
    return ((a * state + c) % m) >> masked_bits

def verify_candidate(possible_state, values, a, c, m, masked_bits,
                     operation=None):
    for value in values:
        if operation is not None:
            if operation(next_state(possible_state, a, c, m, masked_bits)) == value:
                possible_state = next_state(possible_state, a, c, m, masked_bits=0)
            else:
                break
        else:
            if next_state(possible_state, a, c, m, masked_bits) == value:
                possible_state = next_state(possible_state, a, c, m, masked_bits=0)
            else:
                break
    else:
        return possible_state

def predict_state(values, a, c, m, masked_bits, output_modulus=None):
    '''
    Given a

list of values from a LCG, predict the internal state

    @param values: A list of consecutive values output from the LCG
    @return: A list of possible internal state values for the LCG
    '''
    if check_enough_values(len(values), log(m, 2) - masked_bits, log(m, 2),
                           output_modulus) is False:
        print("WARNING: Not enough outputs for unique answer. Result may be incorrect.")

    if output_modulus is not None:
        for i in range(ceil(log(m, 2) - masked_bits - log(output_modulus, 2))+1):
            initial = values[0] + i * output_modulus
            for lower_bits in range(2 ** masked_bits):
                possible_state = (initial << masked_bits) + lower_bits
                checked_state = verify_candidate(possible_state,
                                                 values[1:],
                                                 a, c, m, masked_bits,
                                                 lambda x: x % output_modulus)
                if checked_state:
                    return checked_state

    else:
        for lower_bits in range(2 ** masked_bits):
            possible_state = (values[0] << masked_bits) + lower_bits
            checked_state = verify_candidate(possible_state,
                                             values[1:],
                                             a, c, m, masked_bits,
                                             output_modulus)
            if checked_state:
                return checked_state

def generate_values(state, a, c, m, masked_bits, output_modulus=None):
    '''
    Generate a list of values from a linear congruential algorithm.

    @param state: An initial state for the RNG
    @param a: The multiplier
    @param c: The increment
    @param m: The modulus value
    @param masked_bits: The number of lower order bits to drop
    '''

    while(True):
        state = next_state(state, a, c, m, masked_bits=0)
        if output_modulus:
            yield (state >> masked_bits) % output_modulus
        else:
            yield state >> masked_bits

def from_seed(seed, a, c, m, masked_bits, output_modulus=None):
    '''
    Create a continuation that yields random values from an LCG with the given parameters,
    using 'seed' as the initial seed.
    '''
    yield from generate_values(seed, a, c, m, masked_bits, output_modulus)

def from_outputs(prev_values, a, c, m, masked_bits,
                 output_modulus=None, noexcept=False):
    '''
    Create a continuation that yields random values from an LCG with the given parameters,
    recovering the state from the given list of values. Defaults to MSVC constants.
    '''
    state = predict_state(prev_values, a, c, m, masked_bits, output_modulus)

    if state is None:
        if noexcept:
            yield None
        else:
            raise RuntimeError("No viable candidate found. Some values may not be consecutive.")
    yield from generate_values(state, a, c, m, masked_bits, output_modulus)


from pyspark.sql.types import Row
from sourced.ml.cmd import repos2bow_template, repos2bow_index_template
from sourced.ml.transformers import Transformer

from apollo import cassandra_utils

class BagsSaver(Transformer):
    def __init__(self, keyspace, table, **kwargs):
        super().__init__(**kwargs)
        self.keyspace = keyspace
        self.table = table

    def __call__(self, head):
        rows = head.map(lambda row: Row(sha1=row.document,
                                        item=row.token,
                                        value=float(row.value)))
        if self.explained:
            self._log.info("toDebugString():\n%s", rows.toDebugString().decode())
        rows.toDF() \
            .write \
            .format("org.apache.spark.sql.cassandra") \
            .mode("append") \
            .options(table=self.table, keyspace=self.keyspace) \
            .save()
        return head

class MetadataSaver(Transformer):
    def __init__(self, keyspace, table, **kwargs):
        super().__init__(**kwargs)
        self.keyspace = keyspace
        self.table = table

    def __call__(self, head):
        rows = head.map(lambda x: Row(
            sha1=x.blob_id, repo=x.repository_id, commit=x.commit_hash, path=x.path))
        if self.explained:
            self._log.info("toDebugString():\n%s", rows.toDebugString().decode())
        rows.toDF() \
            .write \
            .format("org.apache.spark.sql.cassandra") \
            .mode("append") \
            .options(table=self.table, keyspace=self.keyspace) \
            .save()

def preprocess(args):
    return repos2bow_index_template(args)

cassandra_utils.configure(args)
    return repos2bow_template(
        args,
        cache_hook=lambda: MetadataSaver(args.keyspace, args.tables["meta"]),
        save_hook=lambda: BagsSaver(args.keyspace, args.tables["bags"]))


from pyspark.sql.types import Row
from sourced.ml.cmd import repos2bow_template, repos2bow_index_template
from sourced.ml.transformers import Transformer

from apollo import cassandra_utils

class BagsSaver(Transformer):
    def __init__(self, keyspace, table, **kwargs):

    def __call__(self, head):
        rows = head.map(lambda row: Row(sha1=row.document,
                                        item=row.token,
                                        value=float(row.value)))
        if self.explained:
            self._log.info("toDebugString():\n%s", rows.toDebugString().decode())
        rows.toDF() \
            .write \
            .format("org.apache.spark.sql.cassandra") \
            .mode("append") \
            .options(table=self.table, keyspace=self.keyspace) \
            .save()
        return head

class MetadataSaver(Transformer):
    def __init__(self, keyspace, table, **kwargs):
        super().__init__(**kwargs)
        self.keyspace = keyspace
        self.table = table

    def __call__(self, head):
        rows = head.map(lambda x: Row(
            sha1=x.blob_id, repo=x.repository_id, commit=x.commit_hash, path=x.path))
        if self.explained:
            self._log.info("toDebugString():\n%s", rows.toDebugString().decode())
        rows.toDF() \
            .write \
            .format("org.apache.spark.sql.cassandra") \
            .mode("append") \
            .options(table=self.table, keyspace=self.keyspace) \
            .save()

def preprocess(args):
    return repos2bow_index_template(args)

def source2bags(args):
    cassandra_utils.configure(args)
    return repos2bow_template(
        args,
        cache_hook=lambda: MetadataSaver(args.keyspace, args.tables["meta"]),
        save_hook=lambda: BagsSaver(args.keyspace, args.tables["bags"]))


rows = head.map(lambda x: Row(
            sha1=x.blob_id, repo=x.repository_id, commit=x.commit_hash, path=x.path))

from pyspark.sql.types import Row
from sourced.ml.cmd import repos2bow_template, repos2bow_index_template
from sourced.ml.transformers import Transformer

from apollo import cassandra_utils

class BagsSaver(Transformer):
    def __init__(self, keyspace, table, **kwargs):
        super().__init__(**kwargs)
        self.keyspace = keyspace
        self.table = table

    def __call__(self, head):
        rows = head.map(lambda row: Row(sha1=row.document,
                                        item=row.token,
                                        value=float(row.value)))
        if self.explained:
            self._log.info("toDebugString():\n%s", rows.toDebugString().decode())
        rows.toDF() \
            .write \
            .format("org.apache.spark.sql.cassandra") \
            .mode("append") \
            .options(table=self.table, keyspace=self.keyspace) \
            .save()
        return head

class MetadataSaver(Transformer):
    def __init__(self, keyspace, table, **kwargs):
        super().__init__(**kwargs)
        self.keyspace = keyspace
        self.table = table

    def __call__(self, head):

        if self.explained:
            self._log.info("toDebugString():\n%s", rows.toDebugString().decode())
        rows.toDF() \
            .write \
            .format("org.apache.spark.sql.cassandra") \
            .mode("append") \
            .options(table=self.table, keyspace=self.keyspace) \
            .save()

def preprocess(args):
    return repos2bow_index_template(args)

def source2bags(args):
    cassandra_utils.configure(args)
    return repos2bow_template(
        args,
        cache_hook=lambda: MetadataSaver(args.keyspace, args.tables["meta"]),
        save_hook=lambda: BagsSaver(args.keyspace, args.tables["bags"]))


from pyspark.sql.types import Row
from sourced.ml.cmd import repos2bow_template, repos2bow_index_template
from sourced.ml.transformers import Transformer

from apollo import cassandra_utils

class BagsSaver(Transformer):
    def __init__(self, keyspace, table, **kwargs):
        super().__init__(**kwargs)
        self.keyspace = keyspace
        self.table = table

    def __call__(self, head):
        rows = head.map(lambda row: Row(sha1=row.document,
                                        item=row.token,
                                        value=float(row.value)))
        if self.explained:
            self._log.info("toDebugString():\n%s", rows.toDebugString().decode())
        rows.toDF() \
            .write \
            .format("org.apache.spark.sql.cassandra") \
            .mode("append") \
            .options(table=self.table, keyspace=self.keyspace) \
            .save()
        return head

class MetadataSaver(Transformer):
    def __init__(self, keyspace, table, **kwargs):
        super().__init__(**kwargs)
        self.keyspace = keyspace
        self.table = table

    def __call__(self, head):
        rows = head.map(lambda x: Row(
            sha1=x.blob_id, repo=x.repository_id, commit=x.commit_hash, path=x.path))

        rows.toDF() \
            .write \
            .format("org.apache.spark.sql.cassandra") \
            .mode("append") \
            .options(table=self.table, keyspace=self.keyspace) \
            .save()

def preprocess(args):
    return repos2bow_index_template(args)

def source2bags(args):
    cassandra_utils.configure(args)
    return repos2bow_template(
        args,
        cache_hook=lambda: MetadataSaver(args.keyspace, args.tables["meta"]),
        save_hook=lambda: BagsSaver(args.keyspace, args.tables["bags"]))


from pyspark.sql.types import Row
from sourced.ml.cmd import repos2bow_template, repos2bow_index_template
from sourced.ml.transformers import Transformer

from apollo import cassandra_utils

class BagsSaver(Transformer):
    def __init__(self, keyspace, table, **kwargs):
        super().__init__(**kwargs)
        self.keyspace = keyspace
        self.table = table

    def __call__(self, head):
        rows = head.map(lambda row: Row(sha1=row.document,
                                        item=row.token,
                                        value=float(row.value)))
        if self.explained:
            self._log.info("toDebugString():\n%s", rows.toDebugString().decode())
        rows.toDF() \
            .write \
            .format("org.apache.spark.sql.cassandra") \
            .mode("append") \
            .options(table=self.table, keyspace=self.keyspace) \
            .save()
        return head

class MetadataSaver(Transformer):
    def __init__(self, keyspace, table, **kwargs):
        super().__init__(**kwargs)
        self.keyspace = keyspace
        self.table = table

    def __call__(self, head):
        rows = head.map(lambda x: Row(
            sha1=x.blob_id, repo=x.repository_id, commit=x.commit_hash, path=x.path))
        if self.explained:
            self._log.info("toDebugString():\n%s", rows.toDebugString().decode())

def preprocess(args):
    return repos2bow_index_template(args)

def source2bags(args):
    cassandra_utils.configure(args)
    return repos2bow_template(
        args,
        cache_hook=lambda: MetadataSaver(args.keyspace, args.tables["meta"]),
        save_hook=lambda: BagsSaver(args.keyspace, args.tables["bags"]))


from pyspark.sql.types import Row
from sourced.ml.cmd import repos2bow_template, repos2bow_index_template
from sourced.ml.transformers import Transformer

from apollo import cassandra_utils

class BagsSaver(Transformer):
    def __init__(self, keyspace, table, **kwargs):
        super().__init_

        self.keyspace = keyspace
        self.table = table

    def __call__(self, head):
        rows = head.map(lambda row: Row(sha1=row.document,
                                        item=row.token,
                                        value=float(row.value)))
        if self.explained:
            self._log.info("toDebugString():\n%s", rows.toDebugString().decode())
        rows.toDF() \
            .write \
            .format("org.apache.spark.sql.cassandra") \
            .mode("append") \
            .options(table=self.table, keyspace=self.keyspace) \
            .save()
        return head

class MetadataSaver(Transformer):
    def __init__(self, keyspace, table, **kwargs):
        super().__init__(**kwargs)
        self.keyspace = keyspace
        self.table = table

    def __call__(self, head):
        rows = head.map(lambda x: Row(
            sha1=x.blob_id, repo=x.repository_id, commit=x.commit_hash, path=x.path))
        if self.explained:
            self._log.info("toDebugString():\n%s", rows.toDebugString().decode())
        rows.toDF() \
            .write \
            .format("org.apache.spark.sql.cassandra") \
            .mode("append") \
            .options(table=self.table, keyspace=self.keyspace) \
            .save()

def preprocess(args):
    return repos2bow_index_template(args)

def source2bags(args):
    cassandra_utils.configure(args)
    return repos2bow_template(
        args,
        cache_hook=lambda: MetadataSaver(args.keyspace, args.tables["meta"]),
        save_hook=lambda: BagsSaver(args.keyspace, args.tables["bags"]))


from pyspark.sql.types import Row
from sourced.ml.cmd import repos2bow_template, repos2bow_index_template
from sourced.ml.transformers import Transformer

from apollo import cassandra_utils

class BagsSaver(Transformer):
    def __init__(self, keyspace, table, **kwargs):
        super().__init__(**kwargs)
        self.keyspace = keyspace
        self.table = table

    def __call__(self, head):
        rows = head.map(lambda row: Row(sha1=row.document,
                                        item=row.token,
                                        value=float(row.value)))
        if self.explained:
            self._log.info("toDebugString():\n%s", rows.toDebugString().decode())
        rows.toDF() \
            .write \
            .format("org.apache.spark.sql.cassandra") \
            .mode("append") \
            .options(table=self.table, keyspace=self.keyspace) \
            .save()
        return head

class MetadataSaver(Transformer):
    def __init__(self, keyspace, table, **kwargs):
        super().__init__(**kwargs)
        self.keyspace = keyspace
        self.table = table

    def __call__(self, head):
        rows = head.map(lambda x: Row(
            sha1=x.blob_id, repo=x.repository_id, commit=x.commit_hash, path=x.path))
        if self.explained:
            self._log.info("toDebugString():\n%s", rows.toDebugString().decode())
        rows.toDF() \
            .write \
            .format("org.apache.spark.sql.cassandra") \
            .mode("append") \
            .options(table=self.table, keyspace=self.keyspace) \
            .save()

def preprocess(args):
    return repos2bow_index_template(args)

def source2bags(args):
    cassandra_utils.configure(args)
    return repos2bow_template(
        args,

 cache_hook=lambda: MetadataSaver(args.keyspace, args.tables["meta"]),
        save_hook=lambda: BagsSaver(args.keyspace, args.tables["bags"]))


import aeropy.xfoil_module as xf
from aeropy.geometry.airfoil import CST, create_x
from aeropy.morphing.camber_2D import *
from aeropy.aero_module import air_properties, Reynolds, LLT_calculator
from scipy.interpolate import griddata, RegularGridInterpolator

import numpy as np
import matplotlib.pyplot as plt
import pandas
from sklearn.cluster import KMeans
from sklearn.metrics import pairwise_distances_argmin_min
import scipy

def aircraft_range_varying_V(f_L, f_LD, AOA):
    def to_integrate(weight):
        def calculate_velocity(AOA):

CL = f_L([V, AOA])[0]
                span = 11
                chord_root = span/16.2
                return abs(V - math.sqrt(weight/(.5*density*(span*chord_root))))

            res = scipy.optimize.minimize(residual, 30, bounds = [[20, 65],])#, options={'ftol':1e-9})
            return res.x[0]

        velocity = calculate_velocity(AOA)

        lift_to_drag = f_LD([velocity, AOA])

        span = 10.9728
        RPM = 1800
        a = 0.3089  # (lb/hr)/BTU
        b = 0.008*RPM+19.607  # lb/hr

        lbhr_to_kgs = 0.000125998
        BHP_to_watt = 745.7

        eta = 0.85

        thrust = weight/lift_to_drag

        power_SI = thrust*velocity/eta
        power_BHP = power_SI/BHP_to_watt
        mass_flow = (a*power_BHP + b)
        mass_flow_SI = mass_flow*lbhr_to_kgs

        SFC = mass_flow_SI/thrust
        dR = velocity/g/SFC*lift_to_drag/weight
        return dR*0.001  # *0.0005399

    AOA_list = []
    g = 9.81  # kg/ms
    fuel = 56*6.01*0.4535*g
    initial_weight = 1111*g
    final_weight = initial_weight-fuel
    x = np.linspace(final_weight, initial_weight, 100)
    y = []
    for x_i in x:
        y.append(to_integrate(x_i)[0])
    range = scipy.integrate.simps(y, x)
    return range

# Inputs
altitude = 10000  # ft
air_props = air_properties(altitude, unit='feet')
density = air_props['Density']

import pickle
state = 'morphed'
concepts = ['NACA0012', 'NACA4415', 'NACA641212', 'glider']

range_data = {}
plt.figure()
for concept in concepts:
    data = np.loadtxt('./'+state + '_' + concept + '.txt')
    aoa = np.unique(data[:,0])
    velocity = np.unique(data[:,1])
    cl = data[:,2].reshape([200,200])
    LD_ratio = data[:,3].reshape([200,200])

    f_LD = RegularGridInterpolator((velocity, aoa), LD_ratio, fill_value = 0, bounds_error = False)
    f_L = RegularGridInterpolator((velocity, aoa), cl, fill_value = 0, bounds_error = False)

    ranges = []
    for i in range(len(aoa)):
        range_i = aircraft_range_varying_V(f_L, f_LD, aoa[i])
        print(i, aoa[i], range_i)
        ranges.append(range_i)
    range_data[concept] = ranges
    plt.plot(aoa, ranges, lw=2, label=concept)
f = open('ranges_aoa.p', 'wb')
pickle.dump(range_data, f)
f.close()

plt.xlabel('Angle of Attack')
plt.ylabel('Range (km)')
plt.legend()
plt.show()


CL = f_L([V, AOA])[0]
                span = 11
                chord_root = span/16.2
                return abs(V - math.sqrt(weight/(.5*density*(span*chord_root))))

import aeropy.xfoil_module as xf
from aeropy.geometry.airfoil import CST, create_x
from aeropy.morphing.camber_2D import *
from aeropy.aero_module import air_properties, Reynolds, LLT_calculator
from scipy.interpolate import griddata, RegularGridInterpolator

import numpy as np
import matplotlib.pyplot as plt
import pandas
from sklearn.cluster import KMeans
from sklearn.metrics import pairwise_distances_argmin_min
import scipy

def aircraft_range_varying_V(f_L, f_LD, AOA):
    def to_integrate(weight):
        def calculate_velocity(AOA):
            def residual(V):

            res = scipy.optimize.minimize(residual, 30, bounds = [[20, 65],])#, options={'ftol':1e-9})
            return res.x[0]

        velocity = calculate_velocity(AOA)

        lift_to_drag = f_LD([velocity, AOA])

        span = 10.9728
        RPM = 1800
        a = 0.3089  # (lb/hr)/BTU
        b = 0.008*RPM+19.607  # lb/hr

        lbhr_to_kgs = 0.000125998
        BHP_to_watt = 745.7

        eta = 0.85

        thrust = weight/lift_to_drag

        power_SI = thrust*velocity/eta
        power_BHP = power_SI/BHP_to_watt
        mass_flow = (a*power_BHP + b)
        mass_flow_SI = mass_flow*lbhr_to_kgs

        SFC = mass_flow_SI/thrust
        dR = velocity/g/SFC*lift_to_drag/weight
        return dR*0.001  # *0.0005399

    AOA_list = []
    g = 9.81  # kg/ms
    fuel = 56*6.01*0.4535*g
    initial_weight = 1111*g
    final_weight = initial_weight-fuel
    x = np.linspace(final_weight, initial_weight, 100)
    y = []
    for x_i in x:
        y.append(to_integrate(x_i)[0])
    range = scipy.integrate.simps(y, x)
    return range

# Inputs
altitude = 10000  # ft
air_props = air_properties(altitude, unit='feet')
density = air_props['Density']

import pickle
state = 'morphed'
concepts = ['NACA0012', 'NACA4415', 'NACA641212', 'glider']

range_data = {}
plt.figure()
for concept in concepts:
    data = np.loadtxt('./'+state + '_' + concept + '.txt')
    aoa = np.unique(data[:,0])
    velocity = np.unique(data[:,1])
    cl = data[:,2].reshape([200,200])
    LD_ratio = data[:,3].reshape([200,200])

    f_LD = RegularGridInterpolator((velocity, aoa), LD_ratio, fill_value = 0, bounds_error = False)
    f_L = RegularGridInterpolator((velocity, aoa), cl, fill_value = 0, bounds_error = False)

    ranges = []
    for i in range(len(aoa)):
        range_i = aircraft_range_varying_V(f_L, f_LD, aoa[i])
        print(i, aoa[i], range_i)
        ranges.append(range_i)
    range_data[concept] = ranges
    plt.plot(aoa, ranges, lw=2, label=concept)
f = open('ranges_aoa.p', 'wb')
pickle.dump(range_data, f)
f.close()

plt.xlabel('Angle of Attack')
plt.ylabel('Range (km)')
plt.legend()
plt.show()


def residual(V):
                CL = f_L([V, AOA])[0]
                span = 11
                chord_root = span/16.2
                return abs(V - math.sqrt(weight/(.5*density*(span*chord_root))))

            res = scipy.optimize.minimize(residual, 30, bounds = [[20, 65],])

#, options={'ftol':1e-9})
            return res.x[0]

        velocity = calculate_velocity(AOA)

        lift_to_drag = f_LD([velocity, AOA])

        span = 10.9728
        RPM = 1800
        a = 0.3089  # (lb/hr)/BTU
        b = 0.008*RPM+19.607  # lb/hr

        lbhr_to_kgs = 0.000125998
        BHP_to_watt = 745.7

        eta = 0.85

        thrust = weight/lift_to_drag

        power_SI = thrust*velocity/eta
        power_BHP = power_SI/BHP_to_watt
        mass_flow = (a*power_BHP + b)
        mass_flow_SI = mass_flow*lbhr_to_kgs

        SFC = mass_flow_SI/thrust
        dR = velocity/g/SFC*lift_to_drag/weight
        return dR*0.001  # *0.0005399

    AOA_list = []
    g = 9.81  # kg/ms
    fuel = 56*6.01*0.4535*g
    initial_weight = 1111*g
    final_weight = initial_weight-fuel
    x = np.linspace(final_weight, initial_weight, 100)
    y = []
    for x_i in x:
        y.append(to_integrate(x_i)[0])
    range = scipy.integrate.simps(y, x)
    return range

# Inputs
altitude = 10000  # ft
air_props = air_properties(altitude, unit='feet')
density = air_props['Density']

import pickle
state = 'morphed'
concepts = ['NACA0012', 'NACA4415', 'NACA641212', 'glider']

range_data = {}
plt.figure()
for concept in concepts:
    data = np.loadtxt('./'+state + '_' + concept + '.txt')
    aoa = np.unique(data[:,0])
    velocity = np.unique(data[:,1])
    cl = data[:,2].reshape([200,200])
    LD_ratio = data[:,3].reshape([200,200])

    f_LD = RegularGridInterpolator((velocity, aoa), LD_ratio, fill_value = 0, bounds_error = False)
    f_L = RegularGridInterpolator((velocity, aoa), cl, fill_value = 0, bounds_error = False)

    ranges = []
    for i in range(len(aoa)):
        range_i = aircraft_range_varying_V(f_L, f_LD, aoa[i])
        print(i, aoa[i], range_i)
        ranges.append(range_i)
    range_data[concept] = ranges
    plt.plot(aoa, ranges, lw=2, label=concept)
f = open('ranges_aoa.p', 'wb')
pickle.dump(range_data, f)
f.close()

plt.xlabel('Angle of Attack')
plt.ylabel('Range (km)')
plt.legend()
plt.show()


import aeropy.xfoil_module as xf
from aeropy.geometry.airfoil import CST, create_x
from aeropy.morphing.camber_2D import *
from aeropy.aero_module import air_properties, Reynolds, LLT_calculator
from scipy.interpolate import griddata, RegularGridInterpolator

import numpy as np
import matplotlib.pyplot as plt
import pandas
from sklearn.cluster import KMeans
from sklearn.metrics import pairwise_distances_argmin_min
import scipy

def aircraft_range_varying_V(f_L, f_LD, AOA):
    def to_integrate(weight):
        def calculate_velocity(AOA):
            def residual(V):
                CL = f_L([V, AOA])[0]
                span = 11
                chord_root = span/16.2
                return abs(V - math.sqrt(weight/(.5*density*(span*chord_root))))

            res = scipy.optimize.minimize(residual, 30, bounds = [[20, 65],])

            return res.x[0]

        velocity = calculate_velocity(AOA)

        lift_to_drag = f_LD([velocity, AOA])

        span = 10.9728
        RPM = 1800
        a = 0.3089  # (lb/hr)/BTU
        b = 0.008*RPM+19.607  # lb/hr

        lbhr_to_kgs = 0.000125998
        BHP_to_watt = 745.7

        eta = 0.85

        thrust = weight/lift_to_drag

        power_SI = thrust*velocity/eta
        power_BHP = power_SI/BHP_to_watt
        mass_flow = (a*power_BHP + b)
        mass_flow_SI = mass_flow*lbhr_to_kgs

        SFC = mass_flow_SI/thrust
        dR = velocity/g/SFC*lift_to_drag/weight
        return dR*0.001  # *0.0005399

    AOA_list = []
    g = 9.81  # kg/ms
    fuel = 56*6.01*0.4535*g
    initial_weight = 1111*g
    final_weight = initial_weight-fuel
    x = np.linspace(final_weight, initial_weight, 100)
    y = []
    for x_i in x:
        y.append(to_integrate(x_i)[0])
    range = scipy.integrate.simps(y, x)
    return range

# Inputs
altitude = 10000  # ft
air_props = air_properties(altitude, unit='feet')
density = air_props['Density']

import pickle
state = 'morphed'
concepts = ['NACA0012', 'NACA4415', 'NACA641212', 'glider']

range_data = {}
plt.figure()
for concept in concepts:
    data = np.loadtxt('./'+state + '_' + concept + '.txt')
    aoa = np.unique(data[:,0])
    velocity = np.unique(data[:,1])
    cl = data[:,2].reshape([200,200])
    LD_ratio = data[:,3].reshape([200,200])

    f_LD = RegularGridInterpolator((velocity, aoa), LD_ratio, fill_value = 0, bounds_error = False)
    f_L = RegularGridInterpolator((velocity, aoa), cl, fill_value = 0, bounds_error = False)

    ranges = []
    for i in range(len(aoa)):
        range_i = aircraft_range_varying_V(f_L, f_LD, aoa[i])
        print(i, aoa[i], range_i)
        ranges.append(range_i)
    range_data[concept] = ranges
    plt.plot(aoa, ranges, lw=2, label=concept)
f = open('ranges_aoa.p', 'wb')
pickle.dump(range_data, f)
f.close()

plt.xlabel('Angle of Attack')
plt.ylabel('Range (km)')
plt.legend()
plt.show()


import aeropy.xfoil_module as xf
from aeropy.geometry.airfoil import CST, create_x
from aeropy.morphing.camber_2D import *
from aeropy.aero_module import air_properties, Reynolds, LLT_calculator
from scipy.interpolate import griddata, RegularGridInterpolator

import numpy as np
import matplotlib.pyplot as plt
import pandas
from sklearn.cluster import KMeans
from sklearn.metrics import pairwise_distances_argmin_min
import scipy

def aircraft_range_varying_V(f_L, f_LD, AOA):
    def to_integrate(weight):
        def calculate_velocity(AOA):
            def residual(V):
                CL = f_L([V, AOA])[0]
                span = 11
                chord_root = span/16.2
                return abs(V - math.sqrt(weight/(.5*density*(span*chord_root))))

            res = scipy.optimize.minimize(residual, 30, bounds = [[20, 65],])#, options={'ftol':1e-9})

        velocity = calculate_velocity(AOA)

        lift_to_drag = f_LD([velocity, AOA])

        span = 10.9728
        RPM = 1800
        a = 0.3089  # (lb/hr)/BTU
        b = 0.008*RPM+19.607  # lb/hr

        lbhr_to_kgs = 0.000125998
        BHP_to_watt = 745.7

        eta = 0.85

        thrust = weight/lift_to_drag

        power_SI = thrust*velocity/eta
        power_BHP = power_SI/BHP_to_watt
        mass_flow = (a*power_BHP + b)
        mass_flow_SI = mass_flow*lbhr_to_kgs

        SFC = mass_flow_SI/thrust
        dR = velocity/g/SFC*lift_to_drag/weight
        return dR*0.001  # *0.0005399

    AOA_list = []
    g = 9.81  # kg/ms
    fuel = 56*6.01*0.4535*g
    initial_weight = 1111*g
    final_weight = initial_weight-fuel
    x = np.linspace(final_weight, initial_weight, 100)
    y = []
    for x_i in x:
        y.append(to_integrate(x_i)[0])
    range = scipy.integrate.simps(y, x)
    return range

# Inputs
altitude = 10000  # ft
air_props = air_properties(altitude, unit='feet')
density = air_props['Density']

import pickle
state = 'morphed'
concepts = ['NACA0012', 'NACA4415', 'NACA641212', 'glider']

range_data = {}
plt.figure()
for concept in concepts:
    data = np.loadtxt('./'+state + '_' + concept + '.txt')
    aoa = np.unique(data[:,0])
    velocity = np.unique(data[:,1])
    cl = data[:,2].reshape([200,200])
    LD_ratio = data[:,3].reshape([200,200])

    f_LD = RegularGridInterpolator((velocity, aoa), LD_ratio, fill_value = 0, bounds_error = False)
    f_L = RegularGridInterpolator((velocity, aoa), cl, fill_value = 0, bounds_error = False)

    ranges = []
    for i in range(len(aoa)):
        range_i = aircraft_range_varying_V(f_L, f_LD, aoa[i])
        print(i, aoa[i], range_i)
        ranges.append(range_i)
    range_data[concept] = ranges
    plt.plot(aoa, ranges, lw=2, label=concept)
f = open('ranges_aoa.p', 'wb')
pickle.dump(range_data, f)
f.close()

plt.xlabel('Angle of Attack')
plt.ylabel('Range (km)')
plt.legend()
plt.show()


import aeropy.xfoil_module as xf
from aeropy.geometry.airfoil import CST, create_x
from aeropy.morphing.camber_2D import *
from aeropy.aero_module import air_properties, Reynolds, LLT_calculator
from scipy.interpolate import griddata, RegularGridInterpolator

import numpy as np
import matplotlib.pyplot as plt
import pandas
from sklearn.cluster import KMeans
from sklearn.metrics import pairwise_distances_argmin_min
import scipy

def aircraft_range_varying_V(f_L, f_LD, AOA):
    def to_integrate(weight):
        def calculate_velocity(AOA):
            def residual(V):
                CL = f_L([V, AOA])[0]
                span = 11
                chord_root = span/16.2
                return abs(V - math.sqrt(weight/(.5*density*(span*chord_root))))

            res = scipy.optimize.minimize(residual, 30, bounds = [[20, 65],])#, options={'ftol':1e-9})
            return res.x[0]

        velocity = calculate_velocity(AOA)

        lift_to_drag = f_LD([velocity, AOA])

        span = 10.9728
        RPM = 1800
        a = 0.3089  # (lb/hr)/BTU
        b = 0.008*RPM+19.607  # lb/hr

        lbhr_to_kgs = 0.000125998
        BHP_to_watt = 745.7

        eta = 0.85

        thrust = weight/lift_to_drag

        power_SI = thrust*velocity/eta
        power_BHP = power_SI/BHP_to_watt
        mass_flow = (a*power_BHP + b)
        mass_flow_SI = mass_flow*lbhr_to_kgs

        SFC = mass_flow_SI/thrust
        dR = velocity/g/SFC*lift_to_drag/weight
        return dR*0.001  # *0.0005399

    AOA_list = []
    g = 9.81  # kg/ms
    fuel = 56*6.01*0.4535*g
    initial_weight = 1111*g
    final_weight = initial_weight-fuel
    x = np.linspace(final_weight, initial_weight, 100)
    y = []
    for x_i in x:
        y.append(to_integrate(x_i)[0])
    range = scipy.integrate.simps(y, x)
    return

# Inputs
altitude = 10000  # ft
air_props = air_properties(altitude, unit='feet')
density = air_props['Density']

import pickle
state = 'morphed'
concepts = ['NACA0012', 'NACA4415', 'NACA641212', 'glider']

range_data = {}
plt.figure()
for concept in concepts:
    data = np.loadtxt('./'+state + '_' + concept + '.txt')
    aoa = np.unique(data[:,0])
    velocity = np.unique(data[:,1])
    cl = data[:,2].reshape([200,200])
    LD_ratio = data[:,3].reshape([200,200])

    f_LD = RegularGridInterpolator((velocity, aoa), LD_ratio, fill_value = 0, bounds_error = False)
    f_L = RegularGridInterpolator((velocity, aoa), cl, fill_value = 0, bounds_error = False)

    ranges = []
    for i in range(len(aoa)):
        range_i = aircraft_range_varying_V(f_L, f_LD, aoa[i])
        print(i, aoa[i], range_i)
        ranges.append(range_i)
    range_data[concept] = ranges
    plt.plot(aoa, ranges, lw=2, label=concept)
f = open('ranges_aoa.p', 'wb')
pickle.dump(range_data, f)
f.close()

plt.xlabel('Angle of Attack')
plt.ylabel('Range (km)')
plt.legend()
plt.show()


for i in range(len(aoa)):
        range_i = aircraft_range_varying_V(f_L, f_LD, aoa[i])
        print(i, aoa[i], range_i)
        ranges.append(range_i)

import aeropy.xfoil_module as xf
from aeropy.geometry.airfoil import CST, create_x
from aeropy.morphing.camber_2D import *
from aeropy.aero_module import air_properties, Reynolds, LLT_calculator
from scipy.interpolate import griddata, RegularGridInterpolator

import numpy as np
import matplotlib.pyplot as plt
import pandas
from sklearn.cluster import KMeans
from sklearn.metrics import pairwise_distances_argmin_min
import scipy

def aircraft_range_varying_V(f_L, f_LD, AOA):
    def to_integrate(weight):
        def calculate_velocity(AOA):
            def residual(V):
                CL = f_L([V, AOA])[0]
                span = 11
                chord_root = span/16.2
                return abs(V - math.sqrt(weight/(.5*density*(span*chord_root))))

            res = scipy.optimize.minimize(residual, 30, bounds = [[20, 65],])#, options={'ftol':1e-9})
            return res.x[0]

        velocity = calculate_velocity(AOA)

        lift_to_drag = f_LD([velocity, AOA])

        span = 10.9728
        RPM = 1800
        a = 0.3089  # (lb/hr)/BTU
        b = 0.008*RPM+19.607  # lb/hr

        lbhr_to_kgs = 0.000125998
        BHP_to_watt = 745.7

        eta = 0.85

        thrust = weight/lift_to_drag

        power_SI = thrust*velocity/eta
        power_BHP = power_SI/BHP_to_watt
        mass_flow = (a*power_BHP + b)
        mass_flow_SI = mass_flow*lbhr_to_kgs

        SFC = mass_flow_SI/thrust
        dR = velocity/g/SFC*lift_to_drag/weight
        return dR*0.001  # *0.0005399

    AOA_list = []
    g = 9.81  # kg/ms
    fuel = 56*6.01*0.4535*g
    initial_weight = 1111*g
    final_weight = initial_weight-fuel
    x = np.linspace(final_weight, initial_weight, 100)
    y = []
    for x_i in x:
        y.append(to_integrate(x_i)[0])
    range = scipy.integrate.simps(y, x)
    return range

# Inputs
altitude = 10000  # ft
air_props = air_properties(altitude, unit='feet')
density = air_props['Density']

import pickle
state = 'morphed'
concepts = ['NACA0012', 'NACA4415', 'NACA641212', 'glider']

range_data = {}
plt.figure()
for concept in concepts:
    data = np.loadtxt('./'+state + '_' + concept + '.txt')
    aoa = np.unique(data[:,0])
    velocity = np.unique(data[:,1])
    cl = data[:,2].reshape([200,200])
    LD_ratio = data[:,3].reshape([200,200])

    f_LD = RegularGridInterpolator((velocity, aoa), LD_ratio, fill_value = 0, bounds_error = False)
    f_L = RegularGridInterpolator((velocity, aoa), cl, fill_value = 0, bounds_error = False)

    ranges = []

    range_data[concept] = ranges
    plt.plot(aoa, ranges, lw=2, label=concept)
f = open('ranges_aoa.p', 'wb')
pickle.dump(range_data, f)
f.close()

plt.xlabel('Angle of Attack')
plt.ylabel('Range (km)')
plt.legend()
plt.show()


import aeropy.xfoil_module as xf
from aeropy.geometry.airfoil import CST, create_x
from aeropy.morphing.camber_2D import *
from aeropy.aero_module import air_properties, Reynolds, LLT_calculator
from scipy.interpolate import griddata, RegularGridInterpolator

import numpy as np
import matplotlib.pyplot as plt
import pandas
from sklearn.cluster import KMeans
from sklearn.metrics import pairwise_distances_argmin_min
import scipy

def aircraft_range_varying_V(f_L, f_LD, AOA):
    def to_integrate(weight):
        def calculate_velocity(AOA):
            def resid

ual(V):
                CL = f_L([V, AOA])[0]
                span = 11
                chord_root = span/16.2
                return abs(V - math.sqrt(weight/(.5*density*(span*chord_root))))

            res = scipy.optimize.minimize(residual, 30, bounds = [[20, 65],])#, options={'ftol':1e-9})
            return res.x[0]

        velocity = calculate_velocity(AOA)

        lift_to_drag = f_LD([velocity, AOA])

        span = 10.9728
        RPM = 1800
        a = 0.3089  # (lb/hr)/BTU
        b = 0.008*RPM+19.607  # lb/hr

        lbhr_to_kgs = 0.000125998
        BHP_to_watt = 745.7

        eta = 0.85

        thrust = weight/lift_to_drag

        power_SI = thrust*velocity/eta
        power_BHP = power_SI/BHP_to_watt
        mass_flow = (a*power_BHP + b)
        mass_flow_SI = mass_flow*lbhr_to_kgs

        SFC = mass_flow_SI/thrust
        dR = velocity/g/SFC*lift_to_drag/weight
        return dR*0.001  # *0.0005399

    AOA_list = []
    g = 9.81  # kg/ms
    fuel = 56*6.01*0.4535*g
    initial_weight = 1111*g
    final_weight = initial_weight-fuel
    x = np.linspace(final_weight, initial_weight, 100)
    y = []
    for x_i in x:
        y.append(to_integrate(x_i)[0])
    range = scipy.integrate.simps(y, x)
    return range

# Inputs
altitude = 10000  # ft
air_props = air_properties(altitude, unit='feet')
density = air_props['Density']

import pickle
state = 'morphed'
concepts = ['NACA0012', 'NACA4415', 'NACA641212', 'glider']

range_data = {}
plt.figure()
for concept in concepts:
    data = np.loadtxt('./'+state + '_' + concept + '.txt')
    aoa = np.unique(data[:,0])
    velocity = np.unique(data[:,1])
    cl = data[:,2].reshape([200,200])
    LD_ratio = data[:,3].reshape([200,200])

    f_LD = RegularGridInterpolator((velocity, aoa), LD_ratio, fill_value = 0, bounds_error = False)
    f_L = RegularGridInterpolator((velocity, aoa), cl, fill_value = 0, bounds_error = False)

    ranges = []
    for i in range(len(aoa)):
        range_i = aircraft_range_varying_V(f_L, f_LD, aoa[i])
        print(i, aoa[i], range_i)
        ranges.append(range_i)
    range_data[concept] = ranges
    plt.plot(aoa, ranges, lw=2, label=concept)
f = open('ranges_aoa.p', 'wb')
pickle.dump(range_data, f)
f.close()

plt.xlabel('Angle of Attack')
plt.ylabel('Range (km)')
plt.legend()
plt.show()


import os
import commands
import unittest
import tempfile
import shutil

from lazyscripts import utils
from lazyscripts import env

class EnvTestCase(unittest.TestCase):

    def setUp(self):
        pass

pass

    def test_storagedenv(self):
        tfile = os.path.join(tempfile.gettempdir(), 'lzs_testenv')
        utils.create_executablefile(tfile,
                        ['#!/bin/bash',
                        'source /tmp/lzs_storagedenv',
                        'echo $REAL_USER $REAL_HOME'])

        filename = env.storageenv(tempfile.gettempdir())
        self.assertEquals("%s %s" % (os.getenv('USER'), os.getenv('HOME')),
                                 commands.getoutput(tfile))

    def test_resource_name(self):
        mywps = os.path.join(tempfile.gettempdir(), '.lazyscripts')
        env.register_workspace(mywps)
        self.assertEquals(mywps, env.resource_name())
        self.assertEquals(
            os.path.join(mywps, 'config'),
            env.resource_name('config'))
        shutil.rmtree(mywps)
pass

def suite():
    return unittest.makeSuite(EnvTestCase, 'test')

if __name__ == '__main__':
    unittest.main(defaultTest='suite')


mywps = os.path.join(tempfile.gettempdir(), '.lazyscripts')
        env.register_workspace(mywps)
        self.assertEquals(mywps, env.resource_name())
        self.assertEquals(
            os.path.join(mywps, 'config'),
            env.resource_name('config'))
        shutil.rmtree(mywps)

import os
import commands
import unittest
import tempfile
import shutil

from lazyscripts import utils
from lazyscripts import env

class EnvTestCase(unittest.TestCase):

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_storagedenv(self):
        tfile = os.path.join(tempfile.gettempdir(), 'lzs_testenv')
        utils.create_executablefile(tfile,
                        ['#!/bin/bash',
                        'source /tmp/lzs_storagedenv',
                        'echo $REAL_USER $REAL_HOME'])

        filename = env.storageenv(tempfile.gettempdir())
        self.assertEquals("%s %s" % (os.getenv('USER'), os.getenv('HOME')),
                                 commands.getoutput(tfile))

    def test_resource_name(self):

pass

def suite():
    return unittest.makeSuite(EnvTestCase, 'test')

if __name__ == '__main__':
    unittest.main(defaultTest='suite')


tfile = os.path.join(tempfile.gettempdir(), 'lzs_testenv')
        utils.create_executablefile(tfile,
                        ['#!/bin/bash',
                        'source /tmp/lzs_storagedenv',
                        'echo $REAL_USER $REAL_HOME'])

import os
import commands
import unittest
import tempfile
import shutil

from lazyscripts import utils
from lazyscripts import env

class EnvTestCase(unittest.TestCase):

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_storagedenv(self):

        filename = env.storageenv(tempfile.gettempdir())
        self.assertEquals("%s %s" % (os.getenv('USER'), os.getenv('HOME')),
                                 commands.getoutput(tfile))

    def test_resource_name(self):
        mywps = os.path.join(tempfile.gettempdir(), '.lazyscripts')
        env.register_workspace(mywps)
        self.assertEquals(mywps, env.resource_name())
        self.assertEquals(
            os.path.join(mywps, 'config'),
            env.resource_name('config'))
        shutil.rmtree(mywps)
pass

def suite():
    return unittest.makeSuite(EnvTestCase, 'test')

if __name__ == '__main__':
    unittest.main(defaultTest='suite')


import os
import commands
import unittest
import tempfile
import shutil

from lazyscripts import utils
from lazyscripts import env

class EnvTestCase(unittest.TestCase):

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_storagedenv(self):
        tfile = os.path.join(tempfile.gettempdir(), 'lzs_testenv')
        utils.create_executablefile(tfile,
                        ['#!/bin/bash',
                        'source /tmp/lzs_storagedenv',
                        'echo $REAL_USER $REAL_HOME'])

        self.assertEquals("%s %s" % (os.getenv('USER'), os.getenv('HOME')),
                                 commands.getoutput(tfile))

    def test_resource_name(self):
        mywps = os.path.join(tempfile.gettempdir(), '.lazyscripts')
        env.register_workspace(mywps)
        self.assertEquals(mywps, env.resource_name())
        self.assertEquals(
            os.path.join(mywps, 'config'),
            env.resource_name('config'))
        shutil.rmtree(mywps)
pass

def suite():
    return unittest.makeSuite(EnvTestCase, 'test')

if __name__ == '__main__':
    unittest.main(defaultTest='suite')


self.assertEquals("%s %s" % (os.getenv('USER'), os.getenv('HOME')),
                                 commands.getoutput(tfile))

import os
import commands
import unittest
import tempfile
import shutil

from lazyscripts import utils
from lazyscripts import env

class EnvTestCase(unittest.TestCase):

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_storagedenv(self):
        tfile = os.path.join(tempfile.gettempdir(), 'lzs_testenv')
        utils.create_executablefile(tfile,
                        ['#!/bin/bash',
                        'source /tmp/lzs_storagedenv',
                        'echo $REAL_USER $REAL_HOME'])

        filename = env.storageenv(tempfile.gettempdir())

    def test_resource_name(self):
        mywps = os.path.join(tempfile.gettempdir(), '.lazyscripts')
        env.register_workspace(mywps)
        self.assertEquals(mywps, env.resource_name())
        self.assertEquals(
            os.path.join(mywps, 'config'),
            env.resource_name('config'))
        shutil.rmtree(mywps)
pass

def suite():
    return unittest.makeSuite(EnvTestCase, 'test')

if __name__ == '__main__':
    unittest.main(defaultTest='suite')


import os
import commands
import unittest
import tempfile
import shutil

from lazyscripts import utils
from lazyscripts import env

class EnvTestCase(unittest.TestCase):

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_storagedenv(self):
        tfile = os.path.joi

        utils.create_executablefile(tfile,
                        ['#!/bin/bash',
                        'source /tmp/lzs_storagedenv',
                        'echo $REAL_USER $REAL_HOME'])

        filename = env.storageenv(tempfile.gettempdir())
        self.assertEquals("%s %s" % (os.getenv('USER'), os.getenv('HOME')),
                                 commands.getoutput(tfile))

    def test_resource_name(self):
        mywps = os.path.join(tempfile.gettempdir(), '.lazyscripts')
        env.register_workspace(mywps)
        self.assertEquals(mywps, env.resource_name())
        self.assertEquals(
            os.path.join(mywps, 'config'),
            env.resource_name('config'))
        shutil.rmtree(mywps)
pass

def suite():
    return unittest.makeSuite(EnvTestCase, 'test')

if __name__ == '__main__':
    unittest.main(defaultTest='suite')


if __name__ == '__main__':
    unittest.main(defaultTest='suite')

import os
import commands
import unittest
import tempfile
import shutil

from lazyscripts import utils
from lazyscripts import env

class EnvTestCase(unittest.TestCase):

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_storagedenv(self):
        tfile = os.path.join(tempfile.gettempdir(), 'lzs_testenv')
        utils.create_executablefile(tfile,
                        ['#!/bin/bash',
                        'source /tmp/lzs_storagedenv',
                        'echo $REAL_USER $REAL_HOME'])

        filename = env.storageenv(tempfile.gettempdir())
        self.assertEquals("%s %s" % (os.getenv('USER'), os.getenv('HOME')),
                                 commands.getoutput(tfile))

    def test_resource_name(self):
        mywps = os.path.join(tempfile.gettempdir(), '.lazyscripts')
        env.register_workspace(mywps)
        self.assertEquals(mywps, env.resource_name())
        self.assertEquals(
            os.path.join(mywps, 'config'),
            env.resource_name('config'))
        shutil.rmtree(mywps)
pass

def suite():
    return unittest.makeSuite(EnvTestCase, 'test')


import os
import commands
import unittest
import tempfile
import shutil

from lazyscripts import utils
from lazyscripts import env

class EnvTestCase(unittest.TestCase):

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_storagedenv(self):
        tfile = os.path.join(tempfile.gettempdir(), 'lzs_testenv')
        utils.create_executablefile(tfile,
                        ['#!/bin/bash',
                        'source /tmp/lzs_

storagedenv',
                        'echo $REAL_USER $REAL_HOME'])

        filename = env.storageenv(tempfile.gettempdir())
        self.assertEquals("%s %s" % (os.getenv('USER'), os.getenv('HOME')),
                                 commands.getoutput(tfile))

    def test_resource_name(self):
        mywps = os.path.join(tempfile.gettempdir(), '.lazyscripts')
        env.register_workspace(mywps)
        self.assertEquals(mywps, env.resource_name())
        self.assertEquals(
            os.path.join(mywps, 'config'),
            env.resource_name('config'))
        shutil.rmtree(mywps)
pass

def suite():
    return unittest.makeSuite(EnvTestCase, 'test')

if __name__ == '__main__':
    unittest.main(defaultTest='suite')


from rapid_response_kit.utils.clients import twilio
from rapid_response_kit.utils.helpers import (
    parse_numbers,
    echo_twimlet,
    twilio_numbers,
    check_is_valid_url
)

from flask import render_template, request, flash, redirect

def install(app):
    app.config.apps.register('broadcast', 'Broadcast', '/broadcast')

    @app.route('/broadcast', methods=['GET'])

numbers = twilio_numbers('phone_number')
        return render_template("broadcast.html", numbers=numbers)

    @app.route('/broadcast', methods=['POST'])
    def do_broadcast():
        numbers = parse_numbers(request.form.get('numbers', ''))
        twiml = "<Response><Say>{}</Say></Response>"
        url = echo_twimlet(twiml.format(request.form.get('message', '')))
        media = check_is_valid_url(request.form.get('media', ''))

        client = twilio()

        for number in numbers:
            try:
                if request.form['method'] == 'sms':
                    client.messages.create(
                        to=number,
                        from_=request.form.get('twilio_number', None),
                        body=request.form.get('message', ''),
                        media_url=media,
                    )
                else:
                    client.calls.create(
                        url=url,
                        to=number,
                        from_=request.form['twilio_number']
                    )
                flash("Sent {} the message".format(number), 'success')
            except Exception:
                flash("Failed to send to {}".format(number), 'danger')

        return redirect('/broadcast')


numbers = twilio_numbers('phone_number')
        return render_template("broadcast.html", numbers=numbers)

from rapid_response_kit.utils.clients import twilio
from rapid_response_kit.utils.helpers import (
    parse_numbers,
    echo_twimlet,
    twilio_numbers,
    check_is_valid_url
)

from flask import render_template, request, flash, redirect

def install(app):
    app.config.apps.register('broadcast', 'Broadcast', '/broadcast')

    @app.route('/broadcast', methods=['GET'])
    def show_broadcast():

    @app.route('/broadcast', methods=['POST'])
    def do_broadcast():
        numbers = parse_numbers(request.form.get('numbers', ''))
        twiml = "<Response><Say>{}</Say></Response>"
        url = echo_twimlet(twiml.format(request.form.get('message', '')))
        media = check_is_valid_url(request.form.get('media', ''))

        client = twilio()

        for number in numbers:
            try:
                if request.form['method'] == 'sms':
                    client.messages.create(
                        to=number,
                        from_=request.form.get('twilio_number', None),
                        body=request.form.get('message', ''),
                        media_url=media,
                    )
                else:
                    client.calls.create(
                        url=url,
                        to=number,
                        from_=request.form['twilio_number']
                    )
                flash("Sent {} the message".format(number), 'success')
            except Exception:
                flash("Failed to send to {}".format(number), 'danger')

        return redirect('/broadcast')


numbers = parse_numbers(request.form.get('numbers', ''))
        twiml = "<Response><Say>{}</Say></Response>"
        url = echo_twimlet(twiml.format(request.form.get('message', '')))

from rapid_response_kit.utils.clients import twilio
from rapid_response_kit.utils.helpers import (
    parse_numbers,
    echo_twimlet,
    twilio_numbers,
    check_is_valid_url
)

from flask import render_template, request, flash, redirect

def install(app):
    app.config.apps.register('broadcast', 'Broadcast', '/broadcast')

    @app.route('/broadcast', methods=['GET'])
    def show_broadcast():
        numbers = twilio_numbers('phone_number')
        return render_template("broadcast.html", numbers=numbers)

    @app.route('/broadcast', methods=['POST'])
    def do_broadcast():

        media = check_is_valid_url(request.form.get('media', ''))

        client = twilio()

        for number in numbers:
            try:
                if request.form['method'] == 'sms':
                    client.messages.create(
                        to=number,
                        from_=request.form.get('twilio_number', None),
                        body=request.form.get('message', ''),
                        media_url=media,
                    )
                else:
                    client.calls.create(
                        url=url,
                        to=number,
                        from_=request.form['twilio_number']
                    )
                flash("Sent {} the message".format(number), 'success')
            except Exception:
                flash("Failed to send to {}".format(number), 'danger')

        return redirect('/broadcast')


media = check_is_valid_url(request.form.get('media', ''))

        client = twilio()

from rapid_response_kit.utils.clients import twilio
from rapid_response_kit.utils.helpers import (
    parse_numbers,
    echo_twimlet,
    twilio_numbers,
    check_is_valid_url
)

from flask import render_template, request, flash, redirect

def install(app):
    app.config.apps.register('broadcast', 'Broadcast', '/broadcast')

    @app.route('/broadcast', methods=['GET'])
    def show_broadcast():
        numbers = twilio_numbers('phone_number')
        return render_template("broadcast.html", numbers=numbers)

    @app.route('/broadcast', methods=['POST'])
    def do_broadcast():
        numbers = parse_numbers(request.form.get('numbers', ''))
        twiml = "<Response><Say>{}</Say></Response>"
        url = echo_twimlet(twiml.format(request.form.get('message', '')))

        for number in numbers:
            try:
                if request.form['method'] == 'sms':
                    client.messages.create(
                        to=number,
                        from_=request.form.get('twilio_number', None),
                        body=request.form.get('message', ''),
                        media_url=media,
                    )
                else:
                    client.calls.create(
                        url=url,
                        to=number,
                        from_=request.form['twilio_number']
                    )
                flash("Sent {} the message".format(number), 'success')
            except Exception:
                flash("Failed to send to {}".format(number), 'danger')

        return redirect('/broadcast')


for number in numbers:
            try:
                if request.form['method'] == 'sms':
                    client.messages.create(
                        to=number,
                        from_=request.form.get('twilio_number', None),
                        body=request.form.get('message', ''),
                        media_url=media,
                    )
                else:
                    client.calls.create(
                        url=url,
                        to=number,
                        from_=request.form['twilio_number']
                    )
                flash("Sent {} the message".format(number), 'success')
            except Exception:
                flash("Failed to send to {}".format(number), 'danger')

        return redirect('/broadcast')

from rapid_response_kit.utils.clients import twilio
from rapid_response_kit.utils.helpers import (
    parse_numbers,
    echo_twimlet,
    twilio_numbers,
    check_is_valid_url
)

from flask import render_template, request, flash, redirect

def install(app):
    app.config.apps.register('broadcast', 'Broadcast', '/broadcast')

    @app.route('/broadcast', methods=['GET'])
    def show_broadcast():
        numbers = twilio_numbers('phone_number')
        return render_template("broadcast.html", numbers=numbers)

    @app.route('/broadcast', methods=['POST'])
    def do_broadcast():
        numbers = parse_numbers(request.form.get('numbers', ''))
        twiml = "<Response><Say>{}</Say></Response>"
        url = echo_twimlet(twiml.format(request.form.get('message', '')))
        media = check_is_valid_url(request.form.get('media', ''))

        client = twilio()


from rapid_response_kit.utils.clients import twilio
from rapid_response_kit.utils.helpers import (
    parse_numbers,
    echo_twimlet,
    twilio_numbers,
    check_is_valid_url
)

from flask import render_template, request, flash, redirect

def install(app):
    app.config.apps.register('broadcast', 'Broadcast', '/broadcast')

    @app.route('/broadcast', methods=['GET'])
    def show_broadcast():
        numbers = twilio_numbers('phone_number')
        return render_template("broadcast.html", numbers=numbers)

    @app.route('/broadcast', methods=['POST'])
    def do_broadcast():
        numbers = parse_numbers(request.form.get('numbers', ''))
        twiml = "<Response><Say>{}</Say></Response>"
        url = echo_twimlet(twiml.format(request.form.get('message', '')))
        media = check_is_valid_url(request.form.get('media', ''))

        client = twilio()

        for number in numbers:
            try:
                if request.form['method'] == 'sms':
                    client.messages.create(
                        to=number,
                        from_=request.form.get('twilio_number', None),
                        body=request.form.get('message', ''),
                        media_url=media,
                    )
                else:
                    client.calls.create(
                        url=url,
                        to=number,
                        from_=request.form['twilio_number']
                    )
                flash("Sent {} the message".format(number), 'success')
            except Exception:
                flash("Failed to send to {}".format(number), 'danger')

        return redir


from rapid_response_kit.utils.clients import twilio
from rapid_response_kit.utils.helpers import (
    parse_numbers,

   echo_twimlet,
    twilio_numbers,
    check_is_valid_url
)

from flask import render_template, request, flash, redirect

def install(app):
    app.config.apps.register('broadcast', 'Broadcast', '/broadcast')

    @app.route('/broadcast', methods=['GET'])
    def show_broadcast():
        numbers = twilio_numbers('phone_number')
        return render_template("broadcast.html", numbers=numbers)

    @app.route('/broadcast', methods=['POST'])
    def do_broadcast():
        numbers = parse_numbers(request.form.get('numbers', ''))
        twiml = "<Response><Say>{}</Say></Response>"
        url = echo_twimlet(twiml.format(request.form.get('message', '')))
        media = check_is_valid_url(request.form.get('media', ''))

        client = twilio()

        for number in numbers:
            try:
                if request.form['method'] == 'sms':
                    client.messages.create(
                        to=number,
                        from_=request.form.get('twilio_number', None),
                        body=request.form.get('message', ''),
                        media_url=media,
                    )
                else:
                    client.calls.create(
                        url=url,
                        to=number,
                        from_=request.form['twilio_number']
                    )
                flash("Sent {} the message".format(number), 'success')
            except Exception:
                flash("Failed to send to {}".format(number), 'danger')

        return redirect('/broadcast')


def create_passwd(passwd):
    # 创建md5对象

"""
@Author         :  Huguodong
@Version        :
------------------------------------
@File           :  test.py
@Description    :
@CreateTime     :  2020/3/12 21:41
------------------------------------
@ModifyTime     :
"""
import hashlib
import os
import random
import time
from datetime import datetime

m = hashlib.md5()
    b = passwd.encode(encoding='utf-8')
    m.update(b)
    str_md5 = m.hexdigest()
    return str_md5

print(create_passwd("admins"))


m = hashlib.md5()
    b = passwd.encode(encoding='utf-8')
    m.update(b)
    str_md5 = m.hexdigest()
    return str_md5

"""
@Author         :  Huguodong
@Version        :
------------------------------------
@File           :  test.py
@Description    :
@CreateTime     :  2020/3/12 21:41
------------------------------------
@ModifyTime     :
"""
import hashlib
import os
import random
import time
from datetime import datetime

def create_passwd(passwd):
    # 创建md5对象


"""
@Author         :  Huguodong
@Version        :
------------------------------------
@File           :  test.py
@Description    :
@CreateTime     :  2020/3/12 21:41
------------------------------------
@ModifyTime     :
"""
import hashlib
import os
import random
import time
from datetime import datetime

def create_passwd(passwd):
    # 创建md5对象
    m = hashlib.md5()
    b = passwd.encode(encoding='ut

    m.update(b)
    str_md5 = m.hexdigest()
    return str_md5

print(create_passwd("admins"))


"""
@Author         :  Huguodong
@Version

    :
------------------------------------
@File           :  test.py
@Description    :
@CreateTime     :  2020/3/12 21:41
------------------------------------
@ModifyTime     :
"""
import hashlib
import os
import random
import time
from datetime import datetime

def create_passwd(passwd):
    # 创建md5对象
    m = hashlib.md5()
    b = passwd.encode(encoding='utf-8')
    m.update(b)
    str_md5 = m.hexdigest()
    return str_md5

print(create_passwd("admins"))


import json
import sys
import unittest
from functools import reduce
from http import HTTPStatus
from unittest.mock import patch

import cloudfoundry_client.main.main as main
from abstract_test_case import AbstractTestCase

class TestServicePlanVisibilities(unittest.TestCase, AbstractTestCase):
    @classmethod
    def setUpClass(cls):
        cls.mock_client_class()

    def setUp(self):
        self.build_client()

    def test_list(self):
        self.client.get.return_value = self.mock_response(
            "/v2/service_plan_visibilities?q=space_guid%3Aspace_guid",
            HTTPStatus.OK,
            None,
            "v2",
            "service_plan_visibilities",
            "GET_response.json",
        )
        cpt = reduce(
            lambda increment, _: increment + 1, self.client.v2.service_plan_visibilities.list(space_guid="space_guid"), 0
        )
        self.client.get.assert_called_with(self.client.get.return_value.url)
        self.assertEqual(cpt, 1)

    def test_get(self):
        self.client.get.return_value = self.mock_response(
            "/v2/service_plan_visibilities/guid", HTTPStatus.OK, None, "v2", "service_plan_visibilities", "GET_{id}_response.json"
        )
        result = self.client.v2.service_plan_visibilities.get("guid")
        self.client.get.assert_called_with(self.client.get.return_value.url)
        self.assertIsNotNone(result)

    def test_create(self):
        self.client.post.return_value = self.mock_response(
            "/v2/service_plan_visibilities", HTTPStatus.CREATED, None, "v2", "service_plan_visibilities", "POST_response.json"
        )
        service_plan_visibilities = self.client.v2.service_plan_visibilities.create("service_plan_guid", "organization_guid")
        self.client.post.assert_called_with(
            self.client.post.return_value.url,
            json=dict(service_plan_guid="service_plan_guid", organization_guid="organization_guid"),
        )
        self.assertIsNotNone(service_plan_visibilities)

    def test_update(self):
        self.client.put.return_value = self.mock_response(
            "/v2/service_plan_visibilities/guid", HTTPStatus.OK, None, "v2", "service_plan_visibilities", "PUT_{id}_response.json"
        )
        service_plan_visibilities = self.client.v2.service_plan_visibilities.update(
            "guid", service_plan_guid="service_plan_guid", organization_guid="organization_guid"
        )
        self.client.put.assert_called_with(
            self.client.put.return_value.url,
            json=dict(service_plan_guid="service_plan_guid", organization_guid="organization_guid"),
        )
        self.assertIsNotNone(service_plan_visibilities)

    def test_delete(self):
        self.client.delete.return_value = self.mock_response("/v2/service_plan_visibilities/guid", HTTPStatus.NO_CONTENT, None)
        self.client.v2.service_plan_visibilities.remove("guid")
        self.client.delete.assert_called_with(self.client.delete.return_value.url)

    @patch.object(
        sys,
        "argv",
        [
            "main",
            "create_service_plan_visibility",
            json.dumps(dict(service_plan_guid="service-plan-id", organization_guid="organization-id")),
        ],
    )
    def test_main_create_service_plan_visibility(self):
        with patch("cloudfoundry_client.main.main.build_client_from_configuration", new=lambda: self.client):
            self.client.post.return_value = self.mock_response(
                "/v2/service_plan_visibilities", HTTPStatus.CREATED, None, "v2", "service_plan_visibilities", "POST_response.json"
            )
            main.main()
            self.client.post.assert_called_with(
                self.client.post.return_value.url,
                json=dict(service_plan_guid="service-plan-id", organization_guid="organization-id"),
            )

    @patch.object(sys, "argv", ["main", "list_service_plan_visibilities"])
    def test_main_list_service_plan_visibilities(self):
        with patch("cloudfoundry_client.main.main.build_client_from_configuration", new=lambda: self.client):
            self.client.get.return_value = self.mock_response(
                "/v2/service_plan_visibilities", HTTPStatus.OK, None, "v2", "service_plan_visibilities", "GET_response.json"
            )
            main.main()
            self.client.get.assert_called_with(self.client.get.return_value.url)

    @patch.object(sys, "argv", ["main", "get_service_plan_visibility", "a353104b-1290-418c-bc03-0e647afd0853"])
    def test_main_get_service_plan_visibility(self):
        with patch("cloudfoundry_client.main.main.build_client_from_configuration", new=lambda: self.client):
            self.client.get.return_value = self.mock_response(
                "/v2/service_plan_visibilities/a353104b-1290-418c-bc03-0e647afd0853",
                HTTPStatus.OK,
                None,
                "v2",
                "service_plan_visibilities",
                "GET_{id}_response.json",
            )
            main.main()
            self.client.get.assert_called_with(self.client.get.return_value.url)

    @patch.object(sys, "argv", ["main", "delete_service_plan_visibility", "906775ea-622e-4bc7-af5d-9aab3b652f81"])

with patch("cloudfoundry_client.main.main.build_client_from_configuration", new=lambda: self.client):
            self.client.delete.return_value = self.mock_response(
                "/v2/service_plan_visibilities/906775ea-622e-4bc7-af5d-9aab3b652f81", HTTPStatus.NO_CONTENT, None
            )
            main.main()
            self.client.delete.assert_called_with(self.client.delete.return_value.url)


import json
import sys
import unittest
from functools import reduce
from http import HTTPStatus
from unittest.mock import patch

import cloudfoundry_client.main.main as main
from abstract_test_case import AbstractTestCase

class TestServicePlanVisibilities(unittest.TestCase, AbstractTestCase):
    @classmethod
    def setUpClass(cls):
        cls.mock_client_class()

    def setUp(self):

    def test_list(self):
        self.client.get.return_value = self.mock_response(
            "/v2/service_plan_visibilities?q=space_guid%3Aspace_guid",
            HTTPStatus.OK,
            None,
            "v2",
            "service_plan_visibilities",
            "GET_response.json",
        )
        cpt = reduce(
            lambda increment, _: increment + 1, self.client.v2.service_plan_visibilities.list(space_guid="space_guid"), 0
        )
        self.client.get.assert_called_with(self.client.get.return_value.url)
        self.assertEqual(cpt, 1)

    def test_get(self):
        self.client.get.return_value = self.mock_response(
            "/v2/service_plan_visibilities/guid", HTTPStatus.OK, None, "v2", "service_plan_visibilities", "GET_{id}_response.json"
        )
        result = self.client.v2.service_plan_visibilities.get("guid")
        self.client.get.assert_called_with(self.client.get.return_value.url)
        self.assertIsNotNone(result)

    def test_create(self):
        self.client.post.return_value = self.mock_response(
            "/v2/service_plan_visibilities", HTTPStatus.CREATED, None, "v2", "service_plan_visibilities", "POST_response.json"
        )
        service_plan_visibilities = self.client.v2.service_plan_visibilities.create("service_plan_guid", "organization_guid")
        self.client.post.assert_called_with(
            self.client.post.return_value.url,
            json=dict(service_plan_guid="service_plan_guid", organization_guid="organization_guid"),
        )
        self.assertIsNotNone(service_plan_visibilities)

    def test_update(self):
        self.client.put.return_value = self.mock_response(
            "/v2/service_plan_visibilities/guid", HTTPStatus.OK, None, "v2", "service_plan_visibilities", "PUT_{id}_response.json"
        )
        service_plan_visibilities = self.client.v2.service_plan_visibilities.update(
            "guid", service_plan_guid="service_plan_guid", organization_guid="organization_guid"
        )
        self.client.put.assert_called_with(
            self.client.put.return_value.url,
            json=dict(service_plan_guid="service_plan_guid", organization_guid="organization_guid"),
        )
        self.assertIsNotNone(service_plan_visibilities)

    def test_delete(self):
        self.client.delete.return_value = self.mock_response("/v2/service_plan_visibilities/guid", HTTPStatus.NO_CONTENT, None)
        self.client.v2.service_plan_visibilities.remove("guid")
        self.client.delete.assert_called_with(self.client.delete.return_value.url)

    @patch.object(
        sys,
        "argv",
        [
            "main",
            "create_service_plan_visibility",
            json.dumps(dict(service_plan_guid="service-plan-id", organization_guid="organization-id")),
        ],
    )
    def test_main_create_service_plan_visibility(self):
        with patch("cloudfoundry_client.main.main.build_client_from_configuration", new=lambda: self.client):
            self.client.post.return_value = self.mock_response(
                "/v2/service_plan_visibilities", HTTPStatus.CREATED, None, "v2", "service_plan_visibilities", "POST_response.json"
            )
            main.main()
            self.client.post.assert_called_with(
                self.client.post.return_value.url,
                json=dict(service_plan_guid="service-plan-id", organization_guid="organization-id"),
            )

    @patch.object(sys, "argv", ["main", "list_service_plan_visibilities"])
    def test_main_list_service_plan_visibilities(self):
        with patch("cloudfoundry_client.main.main.build_client_from_configuration", new=lambda: self.client):
            self.client.get.return_value = self.mock_response(
                "/v2/service_plan_visibilities", HTTPStatus.OK, None, "v2", "service_plan_visibilities", "GET_response.json"
            )
            main.main()
            self.client.get.assert_called_with(self.client.get.return_value.url)

    @patch.object(sys, "argv", ["main", "get_service_plan_visibility", "a353104b-1290-418c-bc03-0e647afd0853"])
    def test_main_get_service_plan_visibility(self):
        with patch("cloudfoundry_client.main.main.build_client_from_configuration", new=lambda: self.client):
            self.client.get.return_value = self.mock_response(
                "/v2/service_plan_visibilities/a353104b-1290-418c-bc03-0e647afd0853",
                HTTPStatus.OK,
                None,
                "v2",
                "service_plan_visibilities",
                "GET_{id}_response.json",
            )
            main.main()
            self.client.get.assert_called_with(self.client.get.return_value.url)

    @patch.object(sys, "argv", ["main", "delete_service_plan_visibility", "906775ea-622e-4bc7-af5d-9aab3b652f81"])
    def test_main_delete_service_plan_visibility(self):
        with patch("cloudfoundry_client.main.main.build_client_from_configuration", new=lambda: self.client):
            self.client.delete.return_value = self.mock_response(
                "/v2/service_plan_visibilities/906775ea-622e-4bc7-af5d-9aab3b652f81", HTTPStatus.NO_CONTENT, None
            )
            main.main()
            self.client.delete.assert_called_with(self.client.delete.return_value.url)