<commit_before>"""
An storage service for use by a Jenca Cloud authentication service.
"""

import os

from flask import Flask, json, jsonify, request, make_response

from flask.ext.sqlalchemy import SQLAlchemy
from flask_jsonschema import JsonSchema, ValidationError
from flask_negotiate import consumes

from requests import codes

db = SQLAlchemy()

class User(db.Model):
    """
    A user has an email and password.
    """
    email = db.Column(db.String, primary_key=True)
    password_hash = db.Column(db.String)

def create_app(database_uri):
    """
    Create an application with a database in a given location.

    :param database_uri: The location of the database for the application.
    :type database_uri: string
    :return: An application instance.
    :rtype: ``Flask``
    """
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = database_uri
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
    db.init_app(app)

    with app.app_context():
        db.create_all()

    return app

SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI',
                                         'sqlite:///:memory:')
app = create_app(database_uri=SQLALCHEMY_DATABASE_URI)

# Inputs can be validated using JSON schema.
# Schemas are in app.config['JSONSCHEMA_DIR'].
# See https://github.com/mattupstate/flask-jsonschema for details.
app.config['JSONSCHEMA_DIR'] = os.path.join(app.root_path, 'schemas')
jsonschema = JsonSchema(app)

def load_user_from_id(user_id):
    """
    :param user_id: The ID of the user Flask is trying to load.
    :type user_id: string
    :return: The user which has the email address ``user_id`` or ``None`` if
        there is no such user.
    :rtype: ``User`` or ``None``.
    """
    return User.query.filter_by(email=user_id).first()

@app.errorhandler(ValidationError)
def on_validation_error(error):
    """
    :resjson string title: An explanation that there was a validation error.
    :resjson string message: The precise validation error.
    :status 400:
    """
    return jsonify(
        title='There was an error validating the given arguments.',
        # By default on Python 2 errors will look like:
        # "u'password' is a required property".
        # This removes all "u'"s, and so could be dangerous.
        detail=error.message.replace("u'", "'"),
    ), codes.BAD_REQUEST

@app.route('/users/<email>', methods=['GET'])
@consumes('application/json')
def get_user(email):
    """
    Get information about particular user.

    :reqheader Content-Type: application/json
    :resheader Content-Type: application/json
    :resjson string email: The email address of the new user.
    :resjson string password_hash: The password of the new user.
    :status 200: The requested user's information is returned.
    :status 404: There is no user with the given ``email``.
    """
    user = load_user_from_id(email)

    if user is None:
        return jsonify(
            title='The requested user does not exist.',
            detail='No user exists with the email "{email}"'.format(
                email=email),
        ), codes.NOT_FOUND

    return_data = jsonify(email=user.email, password_hash=user.password_hash)
    return return_data, codes.OK

@jsonschema.validate('users', 'create')
def create_user():
    """
    Create a new user. See ``users_route`` for details.
    """
    email = request.json['email']
    password_hash = request.json['password_hash']

    if load_user_from_id(email) is not None:
        return jsonify(
            title='There is already a user with the given email address.',
            detail='A user already exists with the email "{email}"'.format(
                email=email),
        ), codes.CONFLICT

    user = User(email=email, password_hash=password_hash)
    db.session.add(user)
    db.session.commit()

    return jsonify(email=email, password_hash=password_hash), codes.CREATED

@app.route('/users', methods=['GET', 'POST'])
@consumes('application/json')
def users_route():
    """
    **POST**:

    Create a new user.

    :param email: The email address of the new user.
    :type email: string
    :param password_hash: A password hash to associate with the given ``email``
        address.
    :type password_hash: string
    :reqheader Content-Type: application/json
    :resheader Content-Type: application/json
    :resjson string email: The email address of the new user.
    :resjson string password_hash: The password hash of the new user.
    :status 200: A user with the given ``email`` and ``password_hash`` has been
        created.
    :status 409: There already exists a user with the given ``email``.

    **GET**:

    Get information about all users.

    :reqheader Content-Type: application/json
    :resheader Content-Type: application/json
    :resjsonarr string email: The email address of a user.
    :resjsonarr string password_hash: The password hash of a user.
    :status 200: Information about all users is returned.
    """

    if request.method == 'POST':
        return create_user()
    elif request.method == 'GET':
        details = [
            {'email': user.email, 'password_hash': user.password_hash} for user
            in User.query.all()]

        return make_response(
            json.dumps(details),
            codes.OK,
            {'Content-Type': 'application/json'})

if __name__ == '__main__':   # pragma: no cover
    # Specifying 0.0.0.0 as the host tells the operating system to listen on
    # all public IPs. This makes the server visible externally.
    # See http://flask.pocoo.org/docs/0.10/quickstart/#a-minimal-application
    app.run(host='0.0.0.0', port=5001)
<commit_msg>Typo in docstring<commit_after>"""
A storage service for use by a Jenca Cloud authentication service.
"""

import os

from flask import Flask, json, jsonify, request, make_response

from flask.ext.sqlalchemy import SQLAlchemy
from flask_jsonschema import JsonSchema, ValidationError
from flask_negotiate import consumes

from requests import codes

db = SQLAlchemy()

class User(db.Model):
    """
    A user has an email and password.
    """
    email = db.Column(db.String, primary_key=True)
    password_hash = db.Column(db.String)

def create_app(database_uri):
    """
    Create an application with a database in a given location.

    :param database_uri: The location of the database for the application.
    :type database_uri: string
    :return: An application instance.
    :rtype: ``Flask``
    """
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = database_uri
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
    db.init_app(app)

    with app.app_context():
        db.create_all()

    return app

SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI',
                                         'sqlite:///:memory:')
app = create_app(database_uri=SQLALCHEMY_DATABASE_URI)

# Inputs can be validated using JSON schema.
# Schemas are in app.config['JSONSCHEMA_DIR'].
# See https://github.com/mattupstate/flask-jsonschema for details.
app.config['JSONSCHEMA_DIR'] = os.path.join(app.root_path, 'schemas')
jsonschema = JsonSchema(app)

def load_user_from_id(user_id):
    """
    :param user_id: The ID of the user Flask is trying to load.
    :type user_id: string
    :return: The user which has the email address ``user_id`` or ``None`` if
        there is no such user.
    :rtype: ``User`` or ``None``.
    """
    return User.query.filter_by(email=user_id).first()

@app.errorhandler(ValidationError)
def on_validation_error(error):
    """
    :resjson string title: An explanation that there was a validation error.
    :resjson string message: The precise validation error.
    :status 400:
    """
    return jsonify(
        title='There was an error validating the given arguments.',
        # By default on Python 2 errors will look like:
        # "u'password' is a required property".
        # This removes all "u'"s, and so could be dangerous.
        detail=error.message.replace("u'", "'"),
    ), codes.BAD_REQUEST

@app.route('/users/<email>', methods=['GET'])
@consumes('application/json')
def get_user(email):
    """
    Get information about particular user.

    :reqheader Content-Type: application/json
    :resheader Content-Type: application/json
    :resjson string email: The email address of the new user.
    :resjson string password_hash: The password of the new user.
    :status 200: The requested user's information is returned.
    :status 404: There is no user with the given ``email``.
    """
    user = load_user_from_id(email)

    if user is None:
        return jsonify(
            title='The requested user does not exist.',
            detail='No user exists with the email "{email}"'.format(
                email=email),
        ), codes.NOT_FOUND

    return_data = jsonify(email=user.email, password_hash=user.password_hash)
    return return_data, codes.OK

@jsonschema.validate('users', 'create')
def create_user():
    """
    Create a new user. See ``users_route`` for details.
    """
    email = request.json['email']
    password_hash = request.json['password_hash']

    if load_user_from_id(email) is not None:
        return jsonify(
            title='There is already a user with the given email address.',
            detail='A user already exists with the email "{email}"'.format(
                email=email),
        ), codes.CONFLICT

    user = User(email=email, password_hash=password_hash)
    db.session.add(user)
    db.session.commit()

    return jsonify(email=email, password_hash=password_hash), codes.CREATED

@app.route('/users', methods=['GET', 'POST'])
@consumes('application/json')
def users_route():
    """
    **POST**:

    Create a new user.

    :param email: The email address of the new user.
    :type email: string
    :param password_hash: A password hash to associate with the given ``email``
        address.
    :type password_hash: string
    :reqheader Content-Type: application/json
    :resheader Content-Type: application/json
    :resjson string email: The email address of the new user.
    :resjson string password_hash: The password hash of the new user.
    :status 200: A user with the given ``email`` and ``password_hash`` has been
        created.
    :status 409: There already exists a user with the given ``email``.

    **GET**:

    Get information about all users.

    :reqheader Content-Type: application/json
    :resheader Content-Type: application/json
    :resjsonarr string email: The email address of a user.
    :resjsonarr string password_hash: The password hash of a user.
    :status 200: Information about all users is returned.
    """

    if request.method == 'POST':
        return create_user()
    elif request.method == 'GET':
        details = [
            {'email': user.email, 'password_hash': user.password_hash} for user
            in User.query.all()]

        return make_response(
            json.dumps(details),
            codes.OK,
            {'Content-Type': 'application/json'})

if __name__ == '__main__':   # pragma: no cover
    # Specifying 0.0.0.0 as the host tells the operating system to listen on
    # all public IPs. This makes the server visible externally.
    # See http://flask.pocoo.org/docs/0.10/quickstart/#a-minimal-application
    app.run(host='0.0.0.0', port=5001)
<|endoftext|>


<commit_before>from flask import request
import requests, json, datetime
from app import app
from twilio import twiml
import random

@app.route('/get_numbers')
def get_numbers():
    numbers = []
    auth = (app.config['TWILIO_ACCOUNT_SID'], app.config['TWILIO_AUTH_TOKEN'])
    params = {
        "Status" : "completed",
        "StartTime" : str(datetime.date.today())
    }
    r = requests.get("http://api.twilio.com/2010-04-01/Accounts/"+app.config['TWILIO_ACCOUNT_SID']+"/Calls.json", params=params, auth=auth)
    r = r.json()
    for call in r["calls"]:
        if call["from_formatted"] not in numbers:
            numbers.append(call["from_formatted"])
    return json.dumps(numbers)

@app.route('/send_sms/<phone_number>/<message>')
def send_sms(phone_number, message):
	msg_dict = {}
	msg_dict['To'] = phone_number
	msg_dict['From'] = app.config['TWILIO_NUMBER']
	msg_dict['Body'] = message
	twilio_endpoint = "https://api.twilio.com/2010-04-01/Accounts/%s/SMS/Messages.json" % (app.config['TWILIO_ACCOUNT_SID'])
	r = requests.post("%s" %(twilio_endpoint), data = msg_dict, auth=(app.config['TWILIO_ACCOUNT_SID'], app.config['TWILIO_AUTH_TOKEN']))
	return json.dumps(r.json())

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

    # Setup headers for Parse
    headers = {
        "X-Parse-Application-Id" : app.config['X_PARSE_APPLICATION_ID'],
        "X-Parse-REST-API-Key" : app.config['X_PARSE_REST_API_KEY']
    }

    # Get response messages
    r = requests.get("https://api.parse.com/1/classes/DeathTexts", headers=headers)
    r = r.json()
    r = r['results']

    # Choose random response message
    random_message = random.choice(r)
    random_message = random_message['text']

    # Send random response message as TwiML
    resp = twiml.Response()
    resp.sms(random_message)
    return str(resp)

@app.route('/incoming_call', methods=['GET'])
def incoming_call():
    resp = twiml.Response()
    # Get audiomessagestate
    # If true, play recorded audio
    # If false, play robolady
    # Setup headers for Parse
    headers = {
        "X-Parse-Application-Id" : app.config['X_PARSE_APPLICATION_ID'],
        "X-Parse-REST-API-Key" : app.config['X_PARSE_REST_API_KEY']
    }
    r = requests.get("https://api.parse.com/1/classes/AudioMessageSwitch", headers=headers)
    r = r.json()
    state = r['results'][0]['state']
    if state:
        # Play mp3
        resp.play("https://s3-us-west-1.amazonaws.com/after-the-tone/i-have-died.mp3")
    else:
        # Say
        resp.say("Now record your own message.", voice="woman")
    resp.record(maxLength="10", action="/handle_recording")
    return str(resp)

@app.route('/handle_recording', methods=['GET', 'POST'])
def handle_recording():
    """Play back the caller's recording."""

    recording_url = request.values.get("RecordingUrl", None)

    resp = twiml.Response()
    resp.say("That was beautiful.", voice="woman")
    return str(resp)

@app.route('/get_recordings', methods=['GET'])
def get_recordings():
    auth = (app.config['TWILIO_ACCOUNT_SID'], app.config['TWILIO_AUTH_TOKEN'])
    params = {
        "DateCreated" : str(datetime.date.today())
    }
    r = requests.get("http://api.twilio.com/2010-04-01/Accounts/"+app.config['TWILIO_ACCOUNT_SID']+"/Recordings.json", params=params, auth=auth)
    r = r.json()
    recordings = r['recordings']
    return json.dumps(recordings)<commit_msg>Changed outgoing message.<commit_after>from flask import request
import requests, json, datetime
from app import app
from twilio import twiml
import random

@app.route('/get_numbers')
def get_numbers():
    numbers = []
    auth = (app.config['TWILIO_ACCOUNT_SID'], app.config['TWILIO_AUTH_TOKEN'])
    params = {
        "Status" : "completed",
        "StartTime" : str(datetime.date.today())
    }
    r = requests.get("http://api.twilio.com/2010-04-01/Accounts/"+app.config['TWILIO_ACCOUNT_SID']+"/Calls.json", params=params, auth=auth)
    r = r.json()
    for call in r["calls"]:
        if call["from_formatted"] not in numbers:
            numbers.append(call["from_formatted"])
    return json.dumps(numbers)

@app.route('/send_sms/<phone_number>/<message>')
def send_sms(phone_number, message):
	msg_dict = {}
	msg_dict['To'] = phone_number
	msg_dict['From'] = app.config['TWILIO_NUMBER']
	msg_dict['Body'] = message
	twilio_endpoint = "https://api.twilio.com/2010-04-01/Accounts/%s/SMS/Messages.json" % (app.config['TWILIO_ACCOUNT_SID'])
	r = requests.post("%s" %(twilio_endpoint), data = msg_dict, auth=(app.config['TWILIO_ACCOUNT_SID'], app.config['TWILIO_AUTH_TOKEN']))
	return json.dumps(r.json())

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

    # Setup headers for Parse
    headers = {
        "X-Parse-Application-Id" : app.config['X_PARSE_APPLICATION_ID'],
        "X-Parse-REST-API-Key" : app.config['X_PARSE_REST_API_KEY']
    }

    # Get response messages
    r = requests.get("https://api.parse.com/1/classes/DeathTexts", headers=headers)
    r = r.json()
    r = r['results']

    # Choose random response message
    random_message = random.choice(r)
    random_message = random_message['text']

    # Send random response message as TwiML
    resp = twiml.Response()
    resp.sms(random_message)
    return str(resp)

@app.route('/incoming_call', methods=['GET'])
def incoming_call():
    resp = twiml.Response()
    # Get audiomessagestate
    # If true, play recorded audio
    # If false, play robolady
    # Setup headers for Parse
    headers = {
        "X-Parse-Application-Id" : app.config['X_PARSE_APPLICATION_ID'],
        "X-Parse-REST-API-Key" : app.config['X_PARSE_REST_API_KEY']
    }
    r = requests.get("https://api.parse.com/1/classes/AudioMessageSwitch", headers=headers)
    r = r.json()
    state = r['results'][0]['state']
    if state:
        # Play mp3
        resp.play("https://s3-us-west-1.amazonaws.com/after-the-tone/Memo.mp3")
    else:
        # Say
        resp.say("Now record your own message.", voice="woman")
    resp.record(maxLength="10", action="/handle_recording")
    return str(resp)

@app.route('/handle_recording', methods=['GET', 'POST'])
def handle_recording():
    """Play back the caller's recording."""

    recording_url = request.values.get("RecordingUrl", None)

    resp = twiml.Response()
    resp.say("That was beautiful.", voice="woman")
    return str(resp)

@app.route('/get_recordings', methods=['GET'])
def get_recordings():
    auth = (app.config['TWILIO_ACCOUNT_SID'], app.config['TWILIO_AUTH_TOKEN'])
    params = {
        "DateCreated" : str(datetime.date.today())
    }
    r = requests.get("http://api.twilio.com/2010-04-01/Accounts/"+app.config['TWILIO_ACCOUNT_SID']+"/Recordings.json", params=params, auth=auth)
    r = r.json()
    recordings = r['recordings']
    return json.dumps(recordings)<|endoftext|>


<commit_before>"""sympify -- convert objects Diofant internal format"""

from inspect import getmro

from .compatibility import iterable
from .evaluate import global_evaluate

class SympifyError(ValueError):
    def __init__(self, expr, base_exc=None):
        self.expr = expr
        self.base_exc = base_exc

    def __str__(self):
        if self.base_exc is None:
            return "SympifyError: %r" % self.expr,

        try:
            s = str(self.expr)
        except TypeError:
            s = repr(self.expr)

        return ("Sympify of expression '%s' failed, because of exception being "
                "raised:\n%s: %s" % (s, self.base_exc.__class__.__name__,
                                     str(self.base_exc)))

converter = {}  # See sympify docstring.

class CantSympify:
    """
    Mix in this trait to a class to disallow sympification of its instances.

    Examples
    ========

    >>> class Something(dict):
    ...     pass
    ...
    >>> sympify(Something())
    {}

    >>> class Something(dict, CantSympify):
    ...     pass
    ...
    >>> sympify(Something())
    Traceback (most recent call last):
    ...
    SympifyError: SympifyError: {}

    """

    pass

def sympify(a, locals=None, convert_xor=True, strict=False, rational=False,
            evaluate=None):
    """Converts an arbitrary expression to a type that can be used inside Diofant.

    For example, it will convert Python ints into instance of diofant.Rational,
    floats into instances of diofant.Float, etc. It is also able to coerce symbolic
    expressions which inherit from Basic. This can be useful in cooperation
    with SAGE.

    It currently accepts as arguments:
       - any object defined in diofant
       - standard numeric python types: int, long, float, Decimal
       - strings (like "0.09" or "2e-19")
       - booleans, including ``None`` (will leave ``None`` unchanged)
       - lists, sets or tuples containing any of the above

    If the argument is already a type that Diofant understands, it will do
    nothing but return that value. This can be used at the beginning of a
    function to ensure you are working with the correct type.

    >>> sympify(2).is_integer
    True
    >>> sympify(2).is_real
    True

    >>> sympify(2.0).is_real
    True
    >>> sympify("2.0").is_real
    True
    >>> sympify("2e-45").is_real
    True

    If the expression could not be converted, a SympifyError is raised.

    >>> sympify("x***2")
    Traceback (most recent call last):
    ...
    SympifyError: SympifyError: "could not parse u'x***2'"

    *Locals*

    The sympification happens with access to everything that is loaded
    by ``from diofant import *``; anything used in a string that is not
    defined by that import will be converted to a symbol. In the following,
    the ``bitcount`` function is treated as a symbol and the ``O`` is
    interpreted as the Order object (used with series) and it raises
    an error when used improperly:

    >>> s = 'bitcount(42)'
    >>> sympify(s)
    bitcount(42)
    >>> sympify("O(x)")
    O(x)
    >>> sympify("O + 1")
    Traceback (most recent call last):
    ...
    TypeError: unbound method...

    In order to have ``bitcount`` be recognized it can be imported into a
    namespace dictionary and passed as locals:

    >>> ns = {}
    >>> exec('from diofant.core.evalf import bitcount', ns)
    >>> sympify(s, locals=ns)
    6

    In order to have the ``O`` interpreted as a Symbol, identify it as such
    in the namespace dictionary. This can be done in a variety of ways; all
    three of the following are possibilities:

    >>> ns["O"] = Symbol("O")  # method 1
    >>> exec('from diofant.abc import O', ns)  # method 2
    >>> ns.update(dict(O=Symbol("O")))  # method 3
    >>> sympify("O + 1", locals=ns)
    O + 1

    If you want *all* single-letter and Greek-letter variables to be symbols
    then you can use the clashing-symbols dictionaries that have been defined
    there as private variables: _clash1 (single-letter variables), _clash2
    (the multi-letter Greek names) or _clash (both single and multi-letter
    names that are defined in abc).

    >>> from diofant.abc import _clash1
    >>> _clash1
    {'E': E, 'I': I, 'N': N, 'O': O, 'S': S}
    >>> sympify('E & O', _clash1)
    E & O

    *Strict*

    If the option ``strict`` is set to ``True``, only the types for which an
    explicit conversion has been defined are converted. In the other
    cases, a SympifyError is raised.

    >>> print(sympify(None))
    None
    >>> sympify(None, strict=True)
    Traceback (most recent call last):
    ...
    SympifyError: SympifyError: None

    *Evaluation*

    If the option ``evaluate`` is set to ``False``, then arithmetic and
    operators will be converted into their Diofant equivalents and the
    ``evaluate=False`` option will be added. Nested ``Add`` or ``Mul`` will
    be denested first. This is done via an AST transformation that replaces
    operators with their Diofant equivalents, so if an operand redefines any
    of those operations, the redefined operators will not be used.

    >>> sympify('2**2 / 3 + 5')
    19/3
    >>> sympify('2**2 / 3 + 5', evaluate=False)
    2**2/3 + 5

    Sometimes autosimplification during sympification results in expressions
    that are very different in structure than what was entered.  Below you
    can see how an expression reduces to -1 by autosimplification, but does
    not do so when ``evaluate`` option is used.

    >>> -2*(-(-x + 1/x)/(x*(x - 1/x)**2) - 1/(x*(x - 1/x))) - 1
    -1
    >>> s = '-2*(-(-x + 1/x)/(x*(x - 1/x)**2) - 1/(x*(x - 1/x))) - 1'
    >>> sympify(s)
    -1
    >>> sympify(s, evaluate=False)
    -2*((x - 1/x)/(x*(x - 1/x)**2) - 1/(x*(x - 1/x))) - 1

    *Extending*

    To extend ``sympify`` to convert custom objects (not derived from ``Basic``),
    just define a ``_diofant_`` method to your class. You can do that even to
    classes that you do not own by subclassing or adding the method at runtime.

    >>> class MyList1:
    ...     def __iter__(self):
    ...         yield 1
    ...         yield 2
    ...         return
    ...     def __getitem__(self, i): return list(self)[i]
    ...     def _diofant_(self): return Matrix(self)
    >>> sympify(MyList1())
    Matrix([
    [1],
    [2]])

    If you do not have control over the class definition you could also use the
    ``converter`` global dictionary. The key is the class and the value is a
    function that takes a single argument and returns the desired Diofant
    object, e.g. ``converter[MyList] = lambda x: Matrix(x)``.

    >>> class MyList2:   # XXX Do not do this if you control the class!
    ...     def __iter__(self):  #     Use _diofant_!
    ...         yield 1
    ...         yield 2
    ...         return
    ...     def __getitem__(self, i): return list(self)[i]
    >>> converter[MyList2] = lambda x: Matrix(x)
    >>> sympify(MyList2())
    Matrix([
    [1],
    [2]])

    """
    from .basic import Basic

    if evaluate is None:
        evaluate = global_evaluate[0]
    try:
        if issubclass(a, Basic):
            return a
    except TypeError:  # Type of a is unhashable
        pass
    cls = a.__class__
    if issubclass(cls, Basic):
        return a
    if issubclass(cls, type(None)):
        if strict:
            raise SympifyError(a)
        else:
            return a

    try:
        return converter[cls](a)
    except KeyError:
        for superclass in getmro(cls):
            try:
                return converter[superclass](a)
            except KeyError:
                continue

    if isinstance(a, CantSympify):
        raise SympifyError(a)

    try:
        return a._diofant_()
    except AttributeError:
        pass

    if not isinstance(a, str):
        for coerce in (float, int):
            try:
                return sympify(coerce(a))
            except (TypeError, ValueError, AttributeError, SympifyError):
                continue

    if strict:
        raise SympifyError(a)

    if iterable(a):
        return type(a)([sympify(x, locals=locals, convert_xor=convert_xor,
                                rational=rational) for x in a])
    if isinstance(a, dict):
        return type(a)([sympify(x, locals=locals, convert_xor=convert_xor,
                                rational=rational) for x in a.items()])

    # At this point we were given an arbitrary expression
    # which does not inherit from Basic and doesn't implement
    # _diofant_ (which is a canonical and robust way to convert
    # anything to Diofant expression).
    #
    # As a last chance, we try to take "a"'s normal form via str()
    # and try to parse it. If it fails, then we have no luck and
    # return an exception
    try:
        a = str(a)
    except Exception as exc:
        raise SympifyError(a, exc)

    from ..parsing.sympy_parser import (parse_expr, TokenError,
                                        standard_transformations)
    from ..parsing.sympy_parser import convert_xor as t_convert_xor
    from ..parsing.sympy_parser import rationalize as t_rationalize

    transformations = standard_transformations

    if rational:
        transformations += t_rationalize,
    if convert_xor:
        transformations += t_convert_xor,

    try:
        a = a.replace('\n', '')
        expr = parse_expr(a, local_dict=locals, transformations=transformations, evaluate=evaluate)
    except (TokenError, SyntaxError) as exc:
        raise SympifyError('could not parse %r' % a, exc)

    return expr
<commit_msg>Amend f365647f18<commit_after>"""sympify -- convert objects Diofant internal format"""

from inspect import getmro

from .compatibility import iterable
from .evaluate import global_evaluate

class SympifyError(ValueError):
    def __init__(self, expr, base_exc=None):
        self.expr = expr
        self.base_exc = base_exc

    def __str__(self):
        try:
            s = str(self.expr)
        except TypeError:
            s = repr(self.expr)

        return ("Sympify of expression '%s' failed, because of exception being "
                "raised:\n%s: %s" % (s, self.base_exc.__class__.__name__,
                                     str(self.base_exc)))

converter = {}  # See sympify docstring.

class CantSympify:
    """
    Mix in this trait to a class to disallow sympification of its instances.

    Examples
    ========

    >>> class Something(dict):
    ...     pass
    ...
    >>> sympify(Something())
    {}

    >>> class Something(dict, CantSympify):
    ...     pass
    ...
    >>> sympify(Something())
    Traceback (most recent call last):
    ...
    SympifyError: SympifyError: {}

    """

    pass

def sympify(a, locals=None, convert_xor=True, strict=False, rational=False,
            evaluate=None):
    """Converts an arbitrary expression to a type that can be used inside Diofant.

    For example, it will convert Python ints into instance of diofant.Rational,
    floats into instances of diofant.Float, etc. It is also able to coerce symbolic
    expressions which inherit from Basic. This can be useful in cooperation
    with SAGE.

    It currently accepts as arguments:
       - any object defined in diofant
       - standard numeric python types: int, long, float, Decimal
       - strings (like "0.09" or "2e-19")
       - booleans, including ``None`` (will leave ``None`` unchanged)
       - lists, sets or tuples containing any of the above

    If the argument is already a type that Diofant understands, it will do
    nothing but return that value. This can be used at the beginning of a
    function to ensure you are working with the correct type.

    >>> sympify(2).is_integer
    True
    >>> sympify(2).is_real
    True

    >>> sympify(2.0).is_real
    True
    >>> sympify("2.0").is_real
    True
    >>> sympify("2e-45").is_real
    True

    If the expression could not be converted, a SympifyError is raised.

    >>> sympify("x***2")
    Traceback (most recent call last):
    ...
    SympifyError: SympifyError: "could not parse u'x***2'"

    *Locals*

    The sympification happens with access to everything that is loaded
    by ``from diofant import *``; anything used in a string that is not
    defined by that import will be converted to a symbol. In the following,
    the ``bitcount`` function is treated as a symbol and the ``O`` is
    interpreted as the Order object (used with series) and it raises
    an error when used improperly:

    >>> s = 'bitcount(42)'
    >>> sympify(s)
    bitcount(42)
    >>> sympify("O(x)")
    O(x)
    >>> sympify("O + 1")
    Traceback (most recent call last):
    ...
    TypeError: unbound method...

    In order to have ``bitcount`` be recognized it can be imported into a
    namespace dictionary and passed as locals:

    >>> ns = {}
    >>> exec('from diofant.core.evalf import bitcount', ns)
    >>> sympify(s, locals=ns)
    6

    In order to have the ``O`` interpreted as a Symbol, identify it as such
    in the namespace dictionary. This can be done in a variety of ways; all
    three of the following are possibilities:

    >>> ns["O"] = Symbol("O")  # method 1
    >>> exec('from diofant.abc import O', ns)  # method 2
    >>> ns.update(dict(O=Symbol("O")))  # method 3
    >>> sympify("O + 1", locals=ns)
    O + 1

    If you want *all* single-letter and Greek-letter variables to be symbols
    then you can use the clashing-symbols dictionaries that have been defined
    there as private variables: _clash1 (single-letter variables), _clash2
    (the multi-letter Greek names) or _clash (both single and multi-letter
    names that are defined in abc).

    >>> from diofant.abc import _clash1
    >>> _clash1
    {'E': E, 'I': I, 'N': N, 'O': O, 'S': S}
    >>> sympify('E & O', _clash1)
    E & O

    *Strict*

    If the option ``strict`` is set to ``True``, only the types for which an
    explicit conversion has been defined are converted. In the other
    cases, a SympifyError is raised.

    >>> print(sympify(None))
    None
    >>> sympify(None, strict=True)
    Traceback (most recent call last):
    ...
    SympifyError: SympifyError: None

    *Evaluation*

    If the option ``evaluate`` is set to ``False``, then arithmetic and
    operators will be converted into their Diofant equivalents and the
    ``evaluate=False`` option will be added. Nested ``Add`` or ``Mul`` will
    be denested first. This is done via an AST transformation that replaces
    operators with their Diofant equivalents, so if an operand redefines any
    of those operations, the redefined operators will not be used.

    >>> sympify('2**2 / 3 + 5')
    19/3
    >>> sympify('2**2 / 3 + 5', evaluate=False)
    2**2/3 + 5

    Sometimes autosimplification during sympification results in expressions
    that are very different in structure than what was entered.  Below you
    can see how an expression reduces to -1 by autosimplification, but does
    not do so when ``evaluate`` option is used.

    >>> -2*(-(-x + 1/x)/(x*(x - 1/x)**2) - 1/(x*(x - 1/x))) - 1
    -1
    >>> s = '-2*(-(-x + 1/x)/(x*(x - 1/x)**2) - 1/(x*(x - 1/x))) - 1'
    >>> sympify(s)
    -1
    >>> sympify(s, evaluate=False)
    -2*((x - 1/x)/(x*(x - 1/x)**2) - 1/(x*(x - 1/x))) - 1

    *Extending*

    To extend ``sympify`` to convert custom objects (not derived from ``Basic``),
    just define a ``_diofant_`` method to your class. You can do that even to
    classes that you do not own by subclassing or adding the method at runtime.

    >>> class MyList1:
    ...     def __iter__(self):
    ...         yield 1
    ...         yield 2
    ...         return
    ...     def __getitem__(self, i): return list(self)[i]
    ...     def _diofant_(self): return Matrix(self)
    >>> sympify(MyList1())
    Matrix([
    [1],
    [2]])

    If you do not have control over the class definition you could also use the
    ``converter`` global dictionary. The key is the class and the value is a
    function that takes a single argument and returns the desired Diofant
    object, e.g. ``converter[MyList] = lambda x: Matrix(x)``.

    >>> class MyList2:   # XXX Do not do this if you control the class!
    ...     def __iter__(self):  #     Use _diofant_!
    ...         yield 1
    ...         yield 2
    ...         return
    ...     def __getitem__(self, i): return list(self)[i]
    >>> converter[MyList2] = lambda x: Matrix(x)
    >>> sympify(MyList2())
    Matrix([
    [1],
    [2]])

    """
    from .basic import Basic

    if evaluate is None:
        evaluate = global_evaluate[0]
    try:
        if issubclass(a, Basic):
            return a
    except TypeError:  # Type of a is unhashable
        pass
    cls = a.__class__
    if issubclass(cls, Basic):
        return a
    if issubclass(cls, type(None)):
        if strict:
            raise SympifyError(a)
        else:
            return a

    try:
        return converter[cls](a)
    except KeyError:
        for superclass in getmro(cls):
            try:
                return converter[superclass](a)
            except KeyError:
                continue

    if isinstance(a, CantSympify):
        raise SympifyError(a)

    try:
        return a._diofant_()
    except AttributeError:
        pass

    if not isinstance(a, str):
        for coerce in (float, int):
            try:
                return sympify(coerce(a))
            except (TypeError, ValueError, AttributeError, SympifyError):
                continue

    if strict:
        raise SympifyError(a)

    if iterable(a):
        return type(a)([sympify(x, locals=locals, convert_xor=convert_xor,
                                rational=rational) for x in a])
    if isinstance(a, dict):
        return type(a)([sympify(x, locals=locals, convert_xor=convert_xor,
                                rational=rational) for x in a.items()])

    # At this point we were given an arbitrary expression
    # which does not inherit from Basic and doesn't implement
    # _diofant_ (which is a canonical and robust way to convert
    # anything to Diofant expression).
    #
    # As a last chance, we try to take "a"'s normal form via str()
    # and try to parse it. If it fails, then we have no luck and
    # return an exception
    try:
        a = str(a)
    except Exception as exc:
        raise SympifyError(a, exc)

    from ..parsing.sympy_parser import (parse_expr, TokenError,
                                        standard_transformations)
    from ..parsing.sympy_parser import convert_xor as t_convert_xor
    from ..parsing.sympy_parser import rationalize as t_rationalize

    transformations = standard_transformations

    if rational:
        transformations += t_rationalize,
    if convert_xor:
        transformations += t_convert_xor,

    try:
        a = a.replace('\n', '')
        expr = parse_expr(a, local_dict=locals, transformations=transformations, evaluate=evaluate)
    except (TokenError, SyntaxError) as exc:
        raise SympifyError('could not parse %r' % a, exc)

    return expr
<|endoftext|>


<commit_before>#
# Copyright (c) 2019 -2021 MINRES Technolgies GmbH
#
# SPDX-License-Identifier: Apache-2.0
#

import os.path
import logging
import cppyy
from cppyy import gbl as cpp
import pysysc

logger = logging.getLogger(__name__)

def load_lib(project_dir):
    """
    Find and load SCC libs in PySysC.
    :param project_dir: Toplevel project directory and root of the search tree.
    """
    logging.debug("Loading SC-Components lib")
    pysysc.add_include_path(os.path.join(project_dir, 'scc/src/common'))
    pysysc.add_library('scc_util.h', 'libscc-util.so', project_dir)
    pysysc.add_include_path(os.path.join(project_dir, 'scc/third_party'))
    pysysc.add_include_path(os.path.join(project_dir, 'scc/third_party/scv-tr/src'))
    pysysc.add_library('scv-tr.h', 'libscv-tr.so', project_dir)
    pysysc.add_include_path(os.path.join(project_dir, 'scc/src/sysc'))
    pysysc.add_library('scc_sysc.h', 'libscc-sysc.so', project_dir)
    pysysc.add_include_path(os.path.join(project_dir, 'scc/src/components'))
    cppyy.include('scc_components.h')

def setup(log_level = logging.WARNING):
    try:
        if log_level >= logging.FATAL:
            cpp.scc.init_logging(cpp.logging.FATAL, False)
        elif log_level >= logging.ERROR:
            cpp.scc.init_logging(cpp.logging.ERROR, False)
        elif log_level >= logging.WARNING:
            cpp.scc.init_logging(cpp.logging.WARNING, False)
        elif log_level >= logging.INFO:
            cpp.scc.init_logging(cpp.logging.INFO, False)
        elif log_level >= logging.DEBUG:
            cpp.scc.init_logging(cpp.logging.DEBUG, False)
        else:
            cpp.scc.init_logging(cpp.logging.TRACE, False)
    except Exception: # fall back: use basic SystemC logging setup
        verb_lut={
            logging.FATAL:100, #SC_LOW
            logging.ERROR: 200, #SC_MEDIUM
            logging.WARNING: 300, #SC_HIGH
            logging.INFO: 400, #SC_FULL
            logging.DEBUG: 500 #SC_DEBUG
            }
        cpp.sc_core.sc_report_handler.set_verbosity_level(verb_lut[log_level]);
    cpp.sc_core.sc_report_handler.set_actions(cpp.sc_core.SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, cpp.sc_core.SC_DO_NOTHING);

def configure(name="", enable_vcd=False):
    if len(name) and os.path.isfile(name):
        Simulation.cfg = cpp.scc.configurer(cpp.std.string(name));
        if enable_vcd:
            trace_name = os.path.basename(name)
            Simulation.trace = cpp.scc.configurable_tracer(trace_name, 1, True, True)
            Simulation.trace.add_control()
    else:
        if enable_vcd:
            Simulation.trace = cpp.scc.tracer('vcd_trace', 1, True)
<commit_msg>fix tracer and configurer setup in pysysc<commit_after>#
# Copyright (c) 2019 -2021 MINRES Technolgies GmbH
#
# SPDX-License-Identifier: Apache-2.0
#

import os.path
import logging
import cppyy
from cppyy import gbl as cpp
import pysysc

logger = logging.getLogger(__name__)
traces = []
cfgs = []

def load_lib(project_dir):
    """
    Find and load SCC libs in PySysC.
    :param project_dir: Toplevel project directory and root of the search tree.
    """
    logging.debug("Loading SC-Components lib")
    pysysc.add_include_path(os.path.join(project_dir, 'scc/src/common'))
    pysysc.add_library('scc_util.h', 'libscc-util.so', project_dir)
    pysysc.add_include_path(os.path.join(project_dir, 'scc/third_party'))
    pysysc.add_include_path(os.path.join(project_dir, 'scc/third_party/scv-tr/src'))
    pysysc.add_library('scv-tr.h', 'libscv-tr.so', project_dir)
    pysysc.add_include_path(os.path.join(project_dir, 'scc/src/sysc'))
    pysysc.add_library('scc_sysc.h', 'libscc-sysc.so', project_dir)
    pysysc.add_include_path(os.path.join(project_dir, 'scc/src/components'))
    cppyy.include('scc_components.h')

def setup(log_level = logging.WARNING):
    try:
        if log_level >= logging.FATAL:
            cpp.scc.init_logging(cpp.logging.FATAL, False)
        elif log_level >= logging.ERROR:
            cpp.scc.init_logging(cpp.logging.ERROR, False)
        elif log_level >= logging.WARNING:
            cpp.scc.init_logging(cpp.logging.WARNING, False)
        elif log_level >= logging.INFO:
            cpp.scc.init_logging(cpp.logging.INFO, False)
        elif log_level >= logging.DEBUG:
            cpp.scc.init_logging(cpp.logging.DEBUG, False)
        else:
            cpp.scc.init_logging(cpp.logging.TRACE, False)
    except Exception: # fall back: use basic SystemC logging setup
        verb_lut={
            logging.FATAL:100, #SC_LOW
            logging.ERROR: 200, #SC_MEDIUM
            logging.WARNING: 300, #SC_HIGH
            logging.INFO: 400, #SC_FULL
            logging.DEBUG: 500 #SC_DEBUG
            }
        cpp.sc_core.sc_report_handler.set_verbosity_level(verb_lut[log_level]);
    cpp.sc_core.sc_report_handler.set_actions(cpp.sc_core.SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, cpp.sc_core.SC_DO_NOTHING);

def configure(name="", enable_vcd=False):
    if len(name) and os.path.isfile(name):
        cfgs.append(cpp.scc.configurer(cpp.std.string(name)));
        if enable_vcd:
            trace_name = os.path.basename(name)
            trace = cpp.scc.configurable_tracer(trace_name, 1, True, True)
            trace.add_control()
            traces.append(trace)
    else:
        if enable_vcd:
            trace = cpp.scc.tracer('vcd_trace', 1, True)
            traces.append(trace)

<|endoftext|>


<commit_before># Copyright 2020 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
# Usage: python configure.py
#

import os
import pathlib
import platform
import logging

import tensorflow as tf

_TFA_BAZELRC = ".bazelrc"

# Writes variables to bazelrc file
def write(line):
    with open(_TFA_BAZELRC, "a") as f:
        f.write(line + "\n")

def write_action_env(var_name, var):
    write('build --action_env {}="{}"'.format(var_name, var))

def is_macos():
    return platform.system() == "Darwin"

def is_windows():
    return platform.system() == "Windows"

def is_linux():
    return platform.system() == "Linux"

def is_raspi_arm():
    return os.uname()[4] == "armv7l"

def get_tf_header_dir():
    import tensorflow as tf

    tf_header_dir = tf.sysconfig.get_compile_flags()[0][2:]
    if is_windows():
        tf_header_dir = tf_header_dir.replace("\\", "/")
    return tf_header_dir

def get_tf_shared_lib_dir():
    import tensorflow as tf

    # OS Specific parsing
    if is_windows():
        tf_shared_lib_dir = tf.sysconfig.get_compile_flags()[0][2:-7] + "python"
        return tf_shared_lib_dir.replace("\\", "/")
    elif is_raspi_arm():
        return tf.sysconfig.get_compile_flags()[0][2:-7] + "python"
    else:
        return tf.sysconfig.get_link_flags()[0][2:]

# Converts the linkflag namespec to the full shared library name
def get_shared_lib_name():
    import tensorflow as tf

    namespec = tf.sysconfig.get_link_flags()
    if is_macos():
        # MacOS
        return "lib" + namespec[1][2:] + ".dylib"
    elif is_windows():
        # Windows
        return "_pywrap_tensorflow_internal.lib"
    elif is_raspi_arm():
        # The below command for linux would return an empty list
        return "_pywrap_tensorflow_internal.so"
    else:
        # Linux
        return namespec[1][3:]

def create_build_configuration():
    print()
    print("Configuring TensorFlow Addons to be built from source...")

    if os.path.isfile(_TFA_BAZELRC):
        os.remove(_TFA_BAZELRC)

    logging.disable(logging.WARNING)

    write_action_env("TF_HEADER_DIR", get_tf_header_dir())
    write_action_env("TF_SHARED_LIBRARY_DIR", get_tf_shared_lib_dir())
    write_action_env("TF_SHARED_LIBRARY_NAME", get_shared_lib_name())
    write_action_env("TF_CXX11_ABI_FLAG", tf.sysconfig.CXX11_ABI_FLAG)

    write("build --spawn_strategy=standalone")
    write("build --strategy=Genrule=standalone")
    write("build -c opt")

    if is_windows():
        write("build --config=windows")
        write("build:windows --enable_runfiles")
        write("build:windows --copt=/experimental:preprocessor")
        write("build:windows --host_copt=/experimental:preprocessor")
        write("build:windows --copt=/arch=AVX2")

    if is_macos() or is_linux():
        write("build --copt=-mavx2")

    if os.getenv("TF_NEED_CUDA", "0") == "1":
        print("> Building GPU & CPU ops")
        configure_cuda()
    else:
        print("> Building only CPU ops")

    print()
    print("Build configurations successfully written to", _TFA_BAZELRC, ":\n")
    print(pathlib.Path(_TFA_BAZELRC).read_text())

def configure_cuda():
    write_action_env("TF_NEED_CUDA", "1")
    write_action_env(
        "CUDA_TOOLKIT_PATH", os.getenv("CUDA_TOOLKIT_PATH", "/usr/local/cuda")
    )
    write_action_env(
        "CUDNN_INSTALL_PATH",
        os.getenv("CUDNN_INSTALL_PATH", "/usr/lib/x86_64-linux-gnu"),
    )
    write_action_env("TF_CUDA_VERSION", os.getenv("TF_CUDA_VERSION", "11"))
    write_action_env("TF_CUDNN_VERSION", os.getenv("TF_CUDNN_VERSION", "8"))

    write("test --config=cuda")
    write("build --config=cuda")
    write("build:cuda --define=using_cuda=true --define=using_cuda_nvcc=true")
    write("build:cuda --crosstool_top=@local_config_cuda//crosstool:toolchain")

if __name__ == "__main__":
    create_build_configuration()
<commit_msg>Build with c++14 (#2323)<commit_after># Copyright 2020 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
# Usage: python configure.py
#

import os
import pathlib
import platform
import logging

import tensorflow as tf

_TFA_BAZELRC = ".bazelrc"

# Writes variables to bazelrc file
def write(line):
    with open(_TFA_BAZELRC, "a") as f:
        f.write(line + "\n")

def write_action_env(var_name, var):
    write('build --action_env {}="{}"'.format(var_name, var))

def is_macos():
    return platform.system() == "Darwin"

def is_windows():
    return platform.system() == "Windows"

def is_linux():
    return platform.system() == "Linux"

def is_raspi_arm():
    return os.uname()[4] == "armv7l"

def get_tf_header_dir():
    import tensorflow as tf

    tf_header_dir = tf.sysconfig.get_compile_flags()[0][2:]
    if is_windows():
        tf_header_dir = tf_header_dir.replace("\\", "/")
    return tf_header_dir

def get_tf_shared_lib_dir():
    import tensorflow as tf

    # OS Specific parsing
    if is_windows():
        tf_shared_lib_dir = tf.sysconfig.get_compile_flags()[0][2:-7] + "python"
        return tf_shared_lib_dir.replace("\\", "/")
    elif is_raspi_arm():
        return tf.sysconfig.get_compile_flags()[0][2:-7] + "python"
    else:
        return tf.sysconfig.get_link_flags()[0][2:]

# Converts the linkflag namespec to the full shared library name
def get_shared_lib_name():
    import tensorflow as tf

    namespec = tf.sysconfig.get_link_flags()
    if is_macos():
        # MacOS
        return "lib" + namespec[1][2:] + ".dylib"
    elif is_windows():
        # Windows
        return "_pywrap_tensorflow_internal.lib"
    elif is_raspi_arm():
        # The below command for linux would return an empty list
        return "_pywrap_tensorflow_internal.so"
    else:
        # Linux
        return namespec[1][3:]

def create_build_configuration():
    print()
    print("Configuring TensorFlow Addons to be built from source...")

    if os.path.isfile(_TFA_BAZELRC):
        os.remove(_TFA_BAZELRC)

    logging.disable(logging.WARNING)

    write_action_env("TF_HEADER_DIR", get_tf_header_dir())
    write_action_env("TF_SHARED_LIBRARY_DIR", get_tf_shared_lib_dir())
    write_action_env("TF_SHARED_LIBRARY_NAME", get_shared_lib_name())
    write_action_env("TF_CXX11_ABI_FLAG", tf.sysconfig.CXX11_ABI_FLAG)

    write("build --spawn_strategy=standalone")
    write("build --strategy=Genrule=standalone")
    write("build -c opt")

    if is_windows():
        write("build --config=windows")
        write("build:windows --enable_runfiles")
        write("build:windows --copt=/experimental:preprocessor")
        write("build:windows --host_copt=/experimental:preprocessor")
        write("build:windows --copt=/arch=AVX2")
        write("build:windows --cxxopt=/std:c++14")
        write("build:windows --host_cxxopt=/std:c++14")

    if is_macos() or is_linux():
        write("build --copt=-mavx2")
        write("build --cxxopt=-std=c++14")
        write("build --host_cxxopt=-std=c++14")

    if os.getenv("TF_NEED_CUDA", "0") == "1":
        print("> Building GPU & CPU ops")
        configure_cuda()
    else:
        print("> Building only CPU ops")

    print()
    print("Build configurations successfully written to", _TFA_BAZELRC, ":\n")
    print(pathlib.Path(_TFA_BAZELRC).read_text())

def configure_cuda():
    write_action_env("TF_NEED_CUDA", "1")
    write_action_env(
        "CUDA_TOOLKIT_PATH", os.getenv("CUDA_TOOLKIT_PATH", "/usr/local/cuda")
    )
    write_action_env(
        "CUDNN_INSTALL_PATH",
        os.getenv("CUDNN_INSTALL_PATH", "/usr/lib/x86_64-linux-gnu"),
    )
    write_action_env("TF_CUDA_VERSION", os.getenv("TF_CUDA_VERSION", "11"))
    write_action_env("TF_CUDNN_VERSION", os.getenv("TF_CUDNN_VERSION", "8"))

    write("test --config=cuda")
    write("build --config=cuda")
    write("build:cuda --define=using_cuda=true --define=using_cuda_nvcc=true")
    write("build:cuda --crosstool_top=@local_config_cuda//crosstool:toolchain")

if __name__ == "__main__":
    create_build_configuration()
<|endoftext|>


<commit_before>from collections import ChainMap
from django.core.urlresolvers import reverse_lazy
from django.shortcuts import render, redirect
from django.contrib.sites.models import get_current_site
from django.views.generic import FormView, TemplateView
from django.contrib.auth import login, logout

from app.models.account import *
from app.forms.account import *
from app.views.edit import FormsetView

class SignUpView(FormsetView):
    template_name = 'account/signup.html'
    success_template_name = 'account/signup_success.html'
    form_class = SignUpUserForm
    formset_class = SignUpAddressFormSet
    http_method_names = ['get', 'post']
    success_url = reverse_lazy('account:signup_success')

    def form_valid(self, request, form, formset):
        cleaned_data = dict()
        for k, v in ChainMap(formset.cleaned_data, form.cleaned_data).items():
            cleaned_data[k] = v
        self.sign_up(request, **cleaned_data)
        return render(request, self.success_template_name)

    def sign_up(self, request, **cleaned_data):
        cd = cleaned_data

        # Attibutes of the User
        email, password, first_name, last_name, phone_num, pickup_arrangements = cd['email'], cd[
            'password1'], cd['first_name'], cd['last_name'], cd['phone_num'], cd['pickup_arrangements']

        # Attributes of user's Address
        apt_num, street, city, county, state, zip = cd['apt_num'], cd['street'], cd['city'], cd['county'], \
                                                    cd['state'], cd['zip']

        user = RegistrationProfile.objects.create_inactive_user(get_current_site(request), **cleaned_data)

class SignUpSuccessView(TemplateView):
    template_name = 'account/signup_success.html'
    http_method_names = ['get']

class SignInView(FormView):
    template_name = 'account/signin.html'
    form_class = SignInForm
    http_method_names = ['get', 'post']
    success_url = reverse_lazy('dashboard')

    def get(self, request):
        form = self.form_class()
        return render(request, self.template_name, {'form': form})

    def form_valid(self, form):
        login(self.request, form.get_user())
        return super(SignInView, self).form_valid(form)

    def form_invalid(self, form):
        return super(SignInView, self).form_invalid(form)

class SignOutView(FormView):
    http_method_names = ['post']
    success_url = reverse_lazy('account:signout_success')

    def post(self, request):
        logout(request)
        return redirect(self.get_success_url())

class SignOutSuccessView(TemplateView):
    http_method_names = ['get']
    template_name = 'account/signout_success.html'
<commit_msg>Since sign up success is now a render vs redirect, removed the SignUpSuccessView. Added a new view to handle account activation requests.<commit_after>from collections import ChainMap
from django.core.urlresolvers import reverse_lazy
from django.shortcuts import render, redirect
from django.contrib.sites.models import get_current_site
from django.views.generic import FormView, TemplateView
from django.contrib.auth import login, logout

from app.models.account import *
from app.forms.account import *
from app.views.edit import FormsetView

class SignUpView(FormsetView):
    template_name = 'account/signup.html'
    success_template_name = 'account/signup_success.html'
    form_class = SignUpUserForm
    formset_class = SignUpAddressFormSet
    http_method_names = ['get', 'post']
    success_url = reverse_lazy('account:signup_success')

    def form_valid(self, request, form, formset):
        cleaned_data = dict()
        for k, v in ChainMap(formset.cleaned_data, form.cleaned_data).items():
            cleaned_data[k] = v
        self.sign_up(request, **cleaned_data)
        return render(request, self.success_template_name)

    def sign_up(self, request, **cleaned_data):
        cd = cleaned_data

        # Attibutes of the User
        email, password, first_name, last_name, phone_num, pickup_arrangements = cd['email'], cd[
            'password1'], cd['first_name'], cd['last_name'], cd['phone_num'], cd['pickup_arrangements']

        # Attributes of user's Address
        apt_num, street, city, county, state, zip = cd['apt_num'], cd['street'], cd['city'], cd['county'], \
                                                    cd['state'], cd['zip']

        user = RegistrationProfile.objects.create_inactive_user(get_current_site(request), **cleaned_data)

class SignInView(FormView):
    template_name = 'account/signin.html'
    form_class = SignInForm
    http_method_names = ['get', 'post']
    success_url = reverse_lazy('dashboard')

    def get(self, request):
        form = self.form_class()
        return render(request, self.template_name, {'form': form})

    def form_valid(self, form):
        login(self.request, form.get_user())
        return super(SignInView, self).form_valid(form)

    def form_invalid(self, form):
        return super(SignInView, self).form_invalid(form)

class SignOutView(FormView):
    http_method_names = ['post']
    success_url = reverse_lazy('account:signout_success')

    def post(self, request):
        logout(request)
        return redirect(self.get_success_url())

class SignOutSuccessView(TemplateView):
    http_method_names = ['get']
    template_name = 'account/signout_success.html'

class ActivateAccountView(FormView):
    http_method_names = ['get']
    success_template_name = 'account/activation_success.html'

    def get(self, request, activation_key):
        # TODO : Determine what happens if activation fails.
        if RegistrationProfile.objects.activate_user(activation_key):
            return render(request, self.success_template_name)<|endoftext|>


<commit_before># coding: utf-8

""" General utilities. """

from __future__ import division, print_function

__author__ = "adrn <adrn@astro.columbia.edu>"

# Standard library
import os, sys
import logging
import multiprocessing

__all__ = ['get_pool']

# Create logger
logger = logging.getLogger(__name__)

class SerialPool(object):

    def close(self):
        return

    def map(self, *args, **kwargs):
        return map(*args, **kwargs)

def get_pool(mpi=False, threads=None):
    """ Get a pool object to pass to emcee for parallel processing.
        If mpi is False and threads is None, pool is None.

        Parameters
        ----------
        mpi : bool
            Use MPI or not. If specified, ignores the threads kwarg.
        threads : int (optional)
            If mpi is False and threads is specified, use a Python
            multiprocessing pool with the specified number of threads.
    """

    if mpi:
        from emcee.utils import MPIPool

        # Initialize the MPI pool
        pool = MPIPool()

        # Make sure the thread we're running on is the master
        if not pool.is_master():
            pool.wait()
            sys.exit(0)
        logger.debug("Running with MPI...")

    elif threads > 1:
        logger.debug("Running with multiprocessing on {} cores..."\
                    .format(threads))
        pool = multiprocessing.Pool(threads)

    else:
        logger.debug("Running serial...")
        pool = SerialPool()

    return pool

def gram_schmidt(y):
    """ Modified Gram-Schmidt orthonormalization of the matrix y(n,n) """

    n = y.shape[0]
    if y.shape[1] != n:
       raise ValueError("Invalid shape: {}".format(y.shape))
    mo = np.zeros(n)

    # Main loop
    for i in range(n):
        # Remove component in direction i
        for j in range(i):
            esc = np.sum(y[j]*y[i])
            y[i] -= y[j]*esc

        # Normalization
        mo[i] = np.linalg.norm(y[i])
        y[i] /= mo[i]

    return mo<commit_msg>import numpy<commit_after># coding: utf-8

""" General utilities. """

from __future__ import division, print_function

__author__ = "adrn <adrn@astro.columbia.edu>"

# Standard library
import os, sys
import logging
import multiprocessing

# Third-party
import numpy as np

__all__ = ['get_pool']

# Create logger
logger = logging.getLogger(__name__)

class SerialPool(object):

    def close(self):
        return

    def map(self, *args, **kwargs):
        return map(*args, **kwargs)

def get_pool(mpi=False, threads=None):
    """ Get a pool object to pass to emcee for parallel processing.
        If mpi is False and threads is None, pool is None.

        Parameters
        ----------
        mpi : bool
            Use MPI or not. If specified, ignores the threads kwarg.
        threads : int (optional)
            If mpi is False and threads is specified, use a Python
            multiprocessing pool with the specified number of threads.
    """

    if mpi:
        from emcee.utils import MPIPool

        # Initialize the MPI pool
        pool = MPIPool()

        # Make sure the thread we're running on is the master
        if not pool.is_master():
            pool.wait()
            sys.exit(0)
        logger.debug("Running with MPI...")

    elif threads > 1:
        logger.debug("Running with multiprocessing on {} cores..."\
                    .format(threads))
        pool = multiprocessing.Pool(threads)

    else:
        logger.debug("Running serial...")
        pool = SerialPool()

    return pool

def gram_schmidt(y):
    """ Modified Gram-Schmidt orthonormalization of the matrix y(n,n) """

    n = y.shape[0]
    if y.shape[1] != n:
       raise ValueError("Invalid shape: {}".format(y.shape))
    mo = np.zeros(n)

    # Main loop
    for i in range(n):
        # Remove component in direction i
        for j in range(i):
            esc = np.sum(y[j]*y[i])
            y[i] -= y[j]*esc

        # Normalization
        mo[i] = np.linalg.norm(y[i])
        y[i] /= mo[i]

    return mo<|endoftext|>


<commit_before>from random import randint

num_reps = 1000000
accum = 0

Thresholds = [93,92,91,89,87,84,80,72,55,0]

for rep in range(num_reps):
	Deck = list(range(100)) # Cards from 0 to 99
	Hold = -1 # -1 is dummy value until we hold
	Highest = -1
	for deal in range(10):
		card = Deck.pop(randint(0,99-deal))
		if card > Highest:
			Highest = card
			# The thresholds are for cards numbered 1 to 100
			if Hold == -1 and card >= Thresholds[deal]-1:
			Hold = card
	if Hold == Highest:
		accum += 1

print(accum/num_reps)
<commit_msg>Update PickACard538.py<commit_after>from random import randint

num_reps = 1000000
accum = 0

Thresholds = [93,92,91,89,87,84,80,72,55,0]

for rep in range(num_reps):
	Deck = list(range(100)) # Cards from 0 to 99
	Hold = -1 # -1 is dummy value until we hold
	Highest = -1
	for deal in range(10):
		card = Deck.pop(randint(0,99-deal))
		if card > Highest:
			Highest = card
			# The thresholds are for cards numbered 1 to 100
			if Hold == -1 and card >= Thresholds[deal]-1:
				Hold = card
	if Hold == Highest:
		accum += 1

print(accum/num_reps)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
__version__ = '0.2.1'

from flask import Flask
app = Flask('streck')
app.config['VERSION'] = __version__
app.config['DATABASE'] = './streck/streck.db'
app.config['PAID_BARCODE'] = 'BETALT'
app.config['UNDO_BARCODE'] = 'undo'
app.config['LOGOUT_BARCODE'] = 'log out'
app.config['JOBBMAT_BARCODE'] = 'Jobbmat'
app.config['REMOVE_JOBBMAT_BARCODE'] = 'Ta+bort+jobbmat'
app.config['ALLOWED_JOBBMAT_CATEGORIES'] = [u'Ickeöl']
app.config['UPLOAD_FOLDER'] = './pictures/'
app.secret_key = '\xbe\xb8_i\xbe\xe7{\xd0\xb8\xb6\x9b\xb3\x8c#\xc4\x81\x8bZ\x994cEcf'

import streck.models
import streck.controller
<commit_msg>Bump version to 0.2.2<commit_after># -*- coding: utf-8 -*-
__version__ = '0.2.2'

from flask import Flask
app = Flask('streck')
app.config['VERSION'] = __version__
app.config['DATABASE'] = './streck/streck.db'
app.config['PAID_BARCODE'] = 'BETALT'
app.config['UNDO_BARCODE'] = 'undo'
app.config['LOGOUT_BARCODE'] = 'log out'
app.config['JOBBMAT_BARCODE'] = 'Jobbmat'
app.config['REMOVE_JOBBMAT_BARCODE'] = 'Ta+bort+jobbmat'
app.config['ALLOWED_JOBBMAT_CATEGORIES'] = [u'Ickeöl']
app.config['UPLOAD_FOLDER'] = './pictures/'
app.secret_key = '\xbe\xb8_i\xbe\xe7{\xd0\xb8\xb6\x9b\xb3\x8c#\xc4\x81\x8bZ\x994cEcf'

import streck.models
import streck.controller
<|endoftext|>


<commit_before>import ctypes
import logging
import os
import shutil
import numpy as np

log = logging.getLogger(__name__)

class ZIPulsarMixin:
    """Mixin containing utility functions needed by ZI AWG pulsar interfaces.

    Classes deriving from this mixin must have a ``pulsar`` attribute.
    """

    zi_waves_cleared = False
    """Flag set when waves are cleared."""

    @staticmethod
    def _zi_wave_dir():
        if os.name == "nt":
            dll = ctypes.windll.shell32
            buf = ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH + 1)
            if dll.SHGetSpecialFolderPathW(None, buf, 0x0005, False):
                _basedir = buf.value
            else:
                log.warning("Could not extract my documents folder")
        else:
            _basedir = os.path.expanduser("~")
        wave_dir = os.path.join(_basedir, "Zurich Instruments", "LabOne",
            "WebServer", "awg", "waves")
        if not os.path.exists(wave_dir):
            os.makedirs(wave_dir)
        return wave_dir

    @classmethod
    def _zi_clear_waves(cls):
        wave_dir = cls._zi_wave_dir()
        for f in os.listdir(wave_dir):
            if f.endswith(".csv"):
                os.remove(os.path.join(wave_dir, f))
            elif f.endswith(".cache"):
                shutil.rmtree(os.path.join(wave_dir, f))
        cls.zi_waves_cleared = True

    @staticmethod
    def _zi_wavename_pair_to_argument(w1, w2):
        if w1 is not None and w2 is not None:
            return f"{w1}, {w2}"
        elif w1 is not None and w2 is None:
            return f"1, {w1}"
        elif w1 is None and w2 is not None:
            return f"2, {w2}"
        else:
            return ""

    def _zi_wave_definition(self, wave, defined_waves=None,
                            placeholder_wave_length=None,
                            placeholder_wave_index=None):
        if defined_waves is None:
            if placeholder_wave_length is None:
                defined_waves = set()
            else:
                defined_waves = set(), dict()
        wave_definition = []
        w1, w2 = self._zi_waves_to_wavenames(wave)
        if placeholder_wave_length is None:
            # don"t use placeholder waves
            for analog, marker, wc in [(wave[0], wave[1], w1),
                                       (wave[2], wave[3], w2)]:
                if analog is not None:
                    wa = self.pulsar._hash_to_wavename(analog)
                    if wa not in defined_waves:
                        wave_definition.append(f'wave {wa} = "{wa}";')
                        defined_waves.add(wa)
                if marker is not None:
                    wm = self.pulsar._hash_to_wavename(marker)
                    if wm not in defined_waves:
                        wave_definition.append(f'wave {wm} = "{wm}";')
                        defined_waves.add(wm)
                if analog is not None and marker is not None:
                    if wc not in defined_waves:
                        wave_definition.append(f"wave {wc} = {wa} + {wm};")
                        defined_waves.add(wc)
        else:
            # use placeholder waves
            n = placeholder_wave_length
            if w1 is None and w2 is not None:
                w1 = f"{w2}_but_zero"
            for wc, marker in [(w1, wave[1]), (w2, wave[3])]:
                if wc is not None and wc not in defined_waves[0]:
                    wave_definition.append(
                        f"wave {wc} = placeholder({n}" +
                        ("" if marker is None else ", true") +
                        ");")
                    defined_waves[0].add(wc)
            wave_definition.append(
                f"assignWaveIndex({self._zi_wavename_pair_to_argument(w1, w2)},"
                f" {placeholder_wave_index});"
            )
            defined_waves[1][placeholder_wave_index] = wave
        return wave_definition

    @staticmethod
    def _zi_playback_string_loop_start(metadata, channels):
        loop_len = metadata.get("loop", False)
        if not loop_len:
            return []
        playback_string = []
        sweep_params = metadata.get("sweep_params", {})
        for k, v in sweep_params.items():
            for ch in channels:
                if k.startswith(f"{ch}_"):
                    playback_string.append(
                        f'wave {k} = vect({",".join([f"{a}" for a in v])})')
        playback_string.append(
            f"for (cvar i_sweep = 0; i_sweep < {loop_len}; i_sweep += 1) {{")
        for k, v in sweep_params.items():
            for ch in channels:
                if k.startswith(f"{ch}_"):
                    node = k[len(f"{ch}_"):].replace("_", "/")
                    playback_string.append(
                        f'setDouble("{node}", {k}[i_sweep]);')
        return playback_string

    @staticmethod
    def _zi_playback_string_loop_end(metadata):
        return ["}"] if metadata.get("end_loop", False) else []

    def _zi_codeword_table_entry(self, codeword, wave, placeholder_wave=False):
        w1, w2 = self._zi_waves_to_wavenames(wave)
        use_hack = True
        if w1 is None and w2 is not None and use_hack and not placeholder_wave:
            # This hack is needed due to a bug on the HDAWG.
            # Remove this if case once the bug is fixed.
            return [f"setWaveDIO({codeword}, zeros(1) + marker(1, 0), {w2});"]
        elif w1 is None and w2 is not None and use_hack and placeholder_wave:
            return [f"setWaveDIO({codeword}, {w2}_but_zero, {w2});"]
        elif not (w1 is None and w2 is None):
            return ["setWaveDIO({}, {});".format(codeword,
                        self._zi_wavename_pair_to_argument(w1, w2))]
        else:
            return []

    def _zi_waves_to_wavenames(self, wave):
        wavenames = []
        for analog, marker in [(wave[0], wave[1]), (wave[2], wave[3])]:
            if analog is None and marker is None:
                wavenames.append(None)
            elif analog is None and marker is not None:
                wavenames.append(self.pulsar._hash_to_wavename(marker))
            elif analog is not None and marker is None:
                wavenames.append(self.pulsar._hash_to_wavename(analog))
            else:
                wavenames.append(self.pulsar._hash_to_wavename((analog, marker)))
        return wavenames

    def _zi_write_waves(self, waveforms):
        wave_dir = self._zi_wave_dir()
        for h, wf in waveforms.items():
            filename = os.path.join(wave_dir, self.pulsar._hash_to_wavename(h)+".csv")
            if os.path.exists(filename):
                continue
            fmt = "%.18e" if wf.dtype == np.float else "%d"
            np.savetxt(filename, wf, delimiter=",", fmt=fmt)

    def _zi_playback_string(self, name, device, wave, acq=False, codeword=False,
                            prepend_zeros=0, placeholder_wave=False,
                            allow_filter=False, negate_q=False):
        playback_string = []
        if allow_filter:
            playback_string.append(
                "if (i_seg >= first_seg && i_seg <= last_seg) {")
        if prepend_zeros:
            playback_string.append(f"playZero({prepend_zeros});")
        w1, w2 = self._zi_waves_to_wavenames(wave)
        if w2 is not None and negate_q:
            w2 = f"(-({w2}))"
        use_hack = True # set this to false once the bugs with HDAWG are fixed
        trig_source = self.pulsar.get("{}_trigger_source".format(name))
        if trig_source == "Dig1":
            playback_string.append(
                "waitDigTrigger(1{});".format(", 1" if device == "uhf" else ""))
        elif trig_source == "Dig2":
            playback_string.append("waitDigTrigger(2,1);")
        else:
            playback_string.append(f"wait{trig_source}Trigger();")

        if codeword and not (w1 is None and w2 is None):
            playback_string.append("playWaveDIO();")
        else:
            if w1 is None and w2 is not None and use_hack and not placeholder_wave:
                # This hack is needed due to a bug on the HDAWG.
                # Remove this if case once the bug is fixed.
                playback_string.append(f"playWave(marker(1,0)*0*{w2}, {w2});")
            elif w1 is None and w2 is not None and use_hack and placeholder_wave:
                # This hack is needed due to a bug on the HDAWG.
                # Remove this if case once the bug is fixed.
                playback_string.append(f"playWave({w2}_but_zero, {w2});")
            elif w1 is not None and w2 is None and use_hack and not placeholder_wave:
                # This hack is needed due to a bug on the HDAWG.
                # Remove this if case once the bug is fixed.
                playback_string.append(f"playWave({w1}, marker(1,0)*0*{w1});")
            elif w1 is not None or w2 is not None:
                playback_string.append("playWave({});".format(
                    self._zi_wavename_pair_to_argument(w1, w2)))
        if acq:
            playback_string.append("setTrigger(RO_TRIG);")
            playback_string.append("setTrigger(WINT_EN);")
        if allow_filter:
            playback_string.append("}")
        return playback_string

    def _zi_interleaved_playback_string(self, name, device, counter,
                                        wave, acq=False, codeword=False):
        playback_string = []
        w1, w2 = self._zi_waves_to_wavenames(wave)
        if w1 is None or w2 is None:
            raise ValueError("When using HDAWG modulation both I and Q need "
                              "to be defined")

        wname = f"wave{counter}"
        interleaves = [f"wave {wname} = interleave({w1}, {w2});"]

        if not codeword:
            if not acq:
                playback_string.append(f"prefetch({wname},{wname});")

        trig_source = self.pulsar.get("{}_trigger_source".format(name))
        if trig_source == "Dig1":
            playback_string.append(
                "waitDigTrigger(1{});".format(", 1" if device == "uhf" else ""))
        elif trig_source == "Dig2":
            playback_string.append("waitDigTrigger(2,1);")
        else:
            playback_string.append(f"wait{trig_source}Trigger();")

        if codeword:
            # playback_string.append("playWaveDIO();")
            raise NotImplementedError("Modulation in combination with codeword"
                                      "pulses has not yet been implemented!")
        else:
            playback_string.append(f"playWave({wname},{wname});")
        if acq:
            playback_string.append("setTrigger(RO_TRIG);")
            playback_string.append("setTrigger(WINT_EN);")
        return playback_string, interleaves
<commit_msg>zi_pulsar_mixin: add methods to create seqc code for digital oscillator sweeps<commit_after>import ctypes
import logging
import os
import shutil
import numpy as np

log = logging.getLogger(__name__)

class ZIPulsarMixin:
    """Mixin containing utility functions needed by ZI AWG pulsar interfaces.

    Classes deriving from this mixin must have a ``pulsar`` attribute.
    """

    zi_waves_cleared = False
    """Flag set when waves are cleared."""

    @staticmethod
    def _zi_wave_dir():
        if os.name == "nt":
            dll = ctypes.windll.shell32
            buf = ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH + 1)
            if dll.SHGetSpecialFolderPathW(None, buf, 0x0005, False):
                _basedir = buf.value
            else:
                log.warning("Could not extract my documents folder")
        else:
            _basedir = os.path.expanduser("~")
        wave_dir = os.path.join(_basedir, "Zurich Instruments", "LabOne",
            "WebServer", "awg", "waves")
        if not os.path.exists(wave_dir):
            os.makedirs(wave_dir)
        return wave_dir

    @classmethod
    def _zi_clear_waves(cls):
        wave_dir = cls._zi_wave_dir()
        for f in os.listdir(wave_dir):
            if f.endswith(".csv"):
                os.remove(os.path.join(wave_dir, f))
            elif f.endswith(".cache"):
                shutil.rmtree(os.path.join(wave_dir, f))
        cls.zi_waves_cleared = True

    @staticmethod
    def _zi_wavename_pair_to_argument(w1, w2):
        if w1 is not None and w2 is not None:
            return f"{w1}, {w2}"
        elif w1 is not None and w2 is None:
            return f"1, {w1}"
        elif w1 is None and w2 is not None:
            return f"2, {w2}"
        else:
            return ""

    def _zi_wave_definition(self, wave, defined_waves=None,
                            placeholder_wave_length=None,
                            placeholder_wave_index=None):
        if defined_waves is None:
            if placeholder_wave_length is None:
                defined_waves = set()
            else:
                defined_waves = set(), dict()
        wave_definition = []
        w1, w2 = self._zi_waves_to_wavenames(wave)
        if placeholder_wave_length is None:
            # don"t use placeholder waves
            for analog, marker, wc in [(wave[0], wave[1], w1),
                                       (wave[2], wave[3], w2)]:
                if analog is not None:
                    wa = self.pulsar._hash_to_wavename(analog)
                    if wa not in defined_waves:
                        wave_definition.append(f'wave {wa} = "{wa}";')
                        defined_waves.add(wa)
                if marker is not None:
                    wm = self.pulsar._hash_to_wavename(marker)
                    if wm not in defined_waves:
                        wave_definition.append(f'wave {wm} = "{wm}";')
                        defined_waves.add(wm)
                if analog is not None and marker is not None:
                    if wc not in defined_waves:
                        wave_definition.append(f"wave {wc} = {wa} + {wm};")
                        defined_waves.add(wc)
        else:
            # use placeholder waves
            n = placeholder_wave_length
            if w1 is None and w2 is not None:
                w1 = f"{w2}_but_zero"
            for wc, marker in [(w1, wave[1]), (w2, wave[3])]:
                if wc is not None and wc not in defined_waves[0]:
                    wave_definition.append(
                        f"wave {wc} = placeholder({n}" +
                        ("" if marker is None else ", true") +
                        ");")
                    defined_waves[0].add(wc)
            wave_definition.append(
                f"assignWaveIndex({self._zi_wavename_pair_to_argument(w1, w2)},"
                f" {placeholder_wave_index});"
            )
            defined_waves[1][placeholder_wave_index] = wave
        return wave_definition

    @staticmethod
    def _zi_playback_string_loop_start(metadata, channels):
        loop_len = metadata.get("loop", False)
        if not loop_len:
            return []
        playback_string = []
        sweep_params = metadata.get("sweep_params", {})
        for k, v in sweep_params.items():
            for ch in channels:
                if k.startswith(f"{ch}_"):
                    playback_string.append(
                        f'wave {k} = vect({",".join([f"{a}" for a in v])})')
        playback_string.append(
            f"for (cvar i_sweep = 0; i_sweep < {loop_len}; i_sweep += 1) {{")
        for k, v in sweep_params.items():
            for ch in channels:
                if k.startswith(f"{ch}_"):
                    node = k[len(f"{ch}_"):].replace("_", "/")
                    playback_string.append(
                        f'setDouble("{node}", {k}[i_sweep]);')
        return playback_string

    @staticmethod
    def _zi_playback_string_loop_end(metadata):
        return ["}"] if metadata.get("end_loop", False) else []

    @staticmethod
    def _zi_playback_string_osc_sweep_prepare(metadata):
        osc_sweep_params = metadata.get("osc_sweep_params", False)
        if not osc_sweep_params:
            return []
        playback_string = []
        playback_string.append('//set up frequency sweep')
        osc = str(osc_sweep_params.get('osc', '0'))
        playback_string.append(f'const SWEEP_OSC = {osc};\n')
        start_freq = osc_sweep_params['start_freq']
        freq_inc = osc_sweep_params['freq_inc']
        playback_string.append(
            f'configFreqSweep(SWEEP_OSC,{start_freq},{freq_inc});')
        return playback_string

    @staticmethod
    def _zi_playback_string_osc_sweep_body(metadata):
        osc_sweep_params = metadata.get("osc_sweep_params", False)
        if not osc_sweep_params:
            return []
        playback_string = []
        playback_string.append('  waitWave();\n')
        playback_string.append('  setSweepStep(SWEEP_OSC, i_sweep);\n')
        osc_sweep_params = metadata.get("osc_sweep_params", {})
        if osc_sweep_params.get('reset_osc', False):
            # The reset_mask can be used to specify the subset of oscillators
            # that will be reset in each iteration of the loop
            # (e.g. 0b00000101, for only reseting oscillator 0 and 2).
            # If not specified it will reset the oscillator specified in the
            # osc_sweep_params. If this is not given, all oscillators will be
            # reset. TODO: move to docstring
            reset_mask = osc_sweep_params.get('reset_osc_mask', False)
            if not reset_mask:
                # reset_osc_mask not specified
                if 'osc' in osc_sweep_params.keys():
                    # reset only the osc used in the sweep
                    reset_mask = "0b{:08b}".format(
                        1 << int(osc_sweep_params['osc'])
                    )
                else:
                    # do not specify mask, thereby resetting all oscillators
                    reset_mask = ''
            playback_string.append(f'  resetOscPhase({reset_mask});\n')
        return playback_string

    def _zi_codeword_table_entry(self, codeword, wave, placeholder_wave=False):
        w1, w2 = self._zi_waves_to_wavenames(wave)
        use_hack = True
        if w1 is None and w2 is not None and use_hack and not placeholder_wave:
            # This hack is needed due to a bug on the HDAWG.
            # Remove this if case once the bug is fixed.
            return [f"setWaveDIO({codeword}, zeros(1) + marker(1, 0), {w2});"]
        elif w1 is None and w2 is not None and use_hack and placeholder_wave:
            return [f"setWaveDIO({codeword}, {w2}_but_zero, {w2});"]
        elif not (w1 is None and w2 is None):
            return ["setWaveDIO({}, {});".format(codeword,
                        self._zi_wavename_pair_to_argument(w1, w2))]
        else:
            return []

    def _zi_waves_to_wavenames(self, wave):
        wavenames = []
        for analog, marker in [(wave[0], wave[1]), (wave[2], wave[3])]:
            if analog is None and marker is None:
                wavenames.append(None)
            elif analog is None and marker is not None:
                wavenames.append(self.pulsar._hash_to_wavename(marker))
            elif analog is not None and marker is None:
                wavenames.append(self.pulsar._hash_to_wavename(analog))
            else:
                wavenames.append(self.pulsar._hash_to_wavename((analog, marker)))
        return wavenames

    def _zi_write_waves(self, waveforms):
        wave_dir = self._zi_wave_dir()
        for h, wf in waveforms.items():
            filename = os.path.join(wave_dir, self.pulsar._hash_to_wavename(h)+".csv")
            if os.path.exists(filename):
                continue
            fmt = "%.18e" if wf.dtype == np.float else "%d"
            np.savetxt(filename, wf, delimiter=",", fmt=fmt)

    def _zi_playback_string(self, name, device, wave, acq=False, codeword=False,
                            prepend_zeros=0, placeholder_wave=False,
                            allow_filter=False, negate_q=False):
        playback_string = []
        if allow_filter:
            playback_string.append(
                "if (i_seg >= first_seg && i_seg <= last_seg) {")
        if prepend_zeros:
            playback_string.append(f"playZero({prepend_zeros});")
        w1, w2 = self._zi_waves_to_wavenames(wave)
        if w2 is not None and negate_q:
            w2 = f"(-({w2}))"
        use_hack = True # set this to false once the bugs with HDAWG are fixed
        trig_source = self.pulsar.get("{}_trigger_source".format(name))
        if trig_source == "Dig1":
            playback_string.append(
                "waitDigTrigger(1{});".format(", 1" if device == "uhf" else ""))
        elif trig_source == "Dig2":
            playback_string.append("waitDigTrigger(2,1);")
        else:
            playback_string.append(f"wait{trig_source}Trigger();")

        if codeword and not (w1 is None and w2 is None):
            playback_string.append("playWaveDIO();")
        else:
            if w1 is None and w2 is not None and use_hack and not placeholder_wave:
                # This hack is needed due to a bug on the HDAWG.
                # Remove this if case once the bug is fixed.
                playback_string.append(f"playWave(marker(1,0)*0*{w2}, {w2});")
            elif w1 is None and w2 is not None and use_hack and placeholder_wave:
                # This hack is needed due to a bug on the HDAWG.
                # Remove this if case once the bug is fixed.
                playback_string.append(f"playWave({w2}_but_zero, {w2});")
            elif w1 is not None and w2 is None and use_hack and not placeholder_wave:
                # This hack is needed due to a bug on the HDAWG.
                # Remove this if case once the bug is fixed.
                playback_string.append(f"playWave({w1}, marker(1,0)*0*{w1});")
            elif w1 is not None or w2 is not None:
                playback_string.append("playWave({});".format(
                    self._zi_wavename_pair_to_argument(w1, w2)))
        if acq:
            playback_string.append("setTrigger(RO_TRIG);")
            playback_string.append("setTrigger(WINT_EN);")
        if allow_filter:
            playback_string.append("}")
        return playback_string

    def _zi_interleaved_playback_string(self, name, device, counter,
                                        wave, acq=False, codeword=False):
        playback_string = []
        w1, w2 = self._zi_waves_to_wavenames(wave)
        if w1 is None or w2 is None:
            raise ValueError("When using HDAWG modulation both I and Q need "
                              "to be defined")

        wname = f"wave{counter}"
        interleaves = [f"wave {wname} = interleave({w1}, {w2});"]

        if not codeword:
            if not acq:
                playback_string.append(f"prefetch({wname},{wname});")

        trig_source = self.pulsar.get("{}_trigger_source".format(name))
        if trig_source == "Dig1":
            playback_string.append(
                "waitDigTrigger(1{});".format(", 1" if device == "uhf" else ""))
        elif trig_source == "Dig2":
            playback_string.append("waitDigTrigger(2,1);")
        else:
            playback_string.append(f"wait{trig_source}Trigger();")

        if codeword:
            # playback_string.append("playWaveDIO();")
            raise NotImplementedError("Modulation in combination with codeword"
                                      "pulses has not yet been implemented!")
        else:
            playback_string.append(f"playWave({wname},{wname});")
        if acq:
            playback_string.append("setTrigger(RO_TRIG);")
            playback_string.append("setTrigger(WINT_EN);")
        return playback_string, interleaves
<|endoftext|>