<commit_before>from django.http import HttpResponseRedirect, HttpResponse
from django.template import RequestContext
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response

from .forms import DatasetForm
from .models import Dataset
from qPRC.lib.parser import parse

def home(request):
    if request.method == 'POST':
        form = DatasetForm(request.POST, request.FILES)
        if form.is_valid():
            new_file = Dataset(file=request.FILES['file'])
            new_file.save()
            return HttpResponseRedirect(reverse('datasets:home'))
    else:
        form = DatasetForm
    data = {
        'form': form,
        'datasets': Dataset.objects.all()
    }
    return render_to_response('datasets/index.html', data,
                              context_instance=RequestContext(request))

def overview(request, dataset_id):
    dataset = Dataset.objects.get(pk=dataset_id)
    dna = parse(dataset.file)
    well, dye = dna.columns[0]
    # TODO: in the template show all the well and dye selection options
    # and for every selection redraw the graph in JS
    url = "/{}/well/{}/dye/{}".format(dataset_id, well, dye)
    data = {'dna': dna}
    return render_to_response('datasets/overview.html', data,
                              context_instance=RequestContext(request))

def detail(request, dataset_id):
    # TODO: some way to open http://localhost:8000/1/well/15/dye/ROX
    dataset = Dataset.objects.get(pk=dataset_id)
    dna = parse(dataset.file)
    # TODO: plot using D3
    return HttpResponse('
Dataset {}
{}'.format(dataset_id,
                                                       dna.to_html()))

# API

from django.core import serializers

def index(request):
    datasets = Dataset.objects.all()
    JSONSerializer = serializers.get_serializer("json")
    json_serializer = JSONSerializer()
    return HttpResponse(json_serializer.serialize(datasets))

def well(request, dataset_id, well, dye):
    """well number, dye as parameters"""
    dataset = Dataset.objects.get(pk=dataset_id)
    dna = parse(dataset.file)
    well_json = dna.loc[:, (int(well), dye)].to_json()
    return HttpResponse(well_json)
<commit_msg>pandas file reading from S3<commit_after>from django.http import HttpResponseRedirect, HttpResponse
from django.template import RequestContext
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response

from .forms import DatasetForm
from .models import Dataset
from qPRC.lib.parser import parse

def home(request):
    if request.method == 'POST':
        form = DatasetForm(request.POST, request.FILES)
        if form.is_valid():
            new_file = Dataset(file=request.FILES['file'])
            new_file.save()
            return HttpResponseRedirect(reverse('datasets:home'))
    else:
        form = DatasetForm
    data = {
        'form': form,
        'datasets': Dataset.objects.all()
    }
    return render_to_response('datasets/index.html', data,
                              context_instance=RequestContext(request))

def overview(request, dataset_id):
    dataset = Dataset.objects.get(pk=dataset_id)
    dna = parse(dataset.file.url)
    well, dye = dna.columns[0]
    # TODO: in the template show all the well and dye selection options
    # and for every selection redraw the graph in JS
    url = "/{}/well/{}/dye/{}".format(dataset_id, well, dye)
    data = {'dna': dna}
    return render_to_response('datasets/overview.html', data,
                              context_instance=RequestContext(request))

def detail(request, dataset_id):
    # TODO: some way to open http://localhost:8000/1/well/15/dye/ROX
    dataset = Dataset.objects.get(pk=dataset_id)
    dna = parse(dataset.file.url)
    # TODO: plot using D3
    return HttpResponse('
Dataset {}
{}'.format(dataset_id,
                                                       dna.to_html()))

# API

from django.core import serializers

def index(request):
    datasets = Dataset.objects.all()
    JSONSerializer = serializers.get_serializer("json")
    json_serializer = JSONSerializer()
    return HttpResponse(json_serializer.serialize(datasets))

def well(request, dataset_id, well, dye):
    """well number, dye as parameters"""
    dataset = Dataset.objects.get(pk=dataset_id)
    dna = parse(dataset.file.url)
    well_json = dna.loc[:, (int(well), dye)].to_json()
    return HttpResponse(well_json)
<|endoftext|>


<commit_before>import unittest
import sys

class Day2(unittest.TestCase):
  def test1(self):
    instructions = "ULL\nRRDDD\nLURDL\nUUUUD"
    self.assertEqual('1985', getBathroomCode(instructions))

  def test2(self):
    instructions = "UU\nRR\nDR\nLLL\nDL"
    self.assertEqual('23647', getBathroomCode(instructions))

def getBathroomCode(instructions):
  moves = {'U':-3, 'D':+3, 'L':-1, 'R':+1}
  code = []
  pos = 5

  for line in instructions.split('\n'):
    for c in line:
      pos += moves[c]
      if pos < 1 or pos > 9:
        pos -= moves[c]
    code.append(pos)

  return ''.join(map(str, code))

def main():
  print(getBathroomCode(sys.stdin.read()))

if __name__ == "__main__":
  unittest.main(exit=False)
  main()
<commit_msg>Day 2 Part 1: New implementation for getBathroomCode()<commit_after>import unittest
import sys

class Day2(unittest.TestCase):
  def test1(self):
    instructions = "ULL\nRRDDD\nLURDL\nUUUUD"
    self.assertEqual('1985', getBathroomCode(instructions))

  def test2(self):
    instructions = "UU\nRR\nDR\nLLL\nDL"
    self.assertEqual('23647', getBathroomCode(instructions))

def getBathroomCode(instructions):
  movesx = { 'U': 0 , 'D':0 , 'L':-1, 'R':1 }
  movesy = { 'U':-1 , 'D':1 , 'L': 0, 'R':0 }
  code = []
  x = 1
  y = 1

  for line in instructions.split('\n'):
    for c in line:
      x += movesx[c]
      y += movesy[c]

      if x < 0 or x > 2:
        x -= movesx[c]

      if y < 0 or y > 2:
        y -= movesy[c]

    code.append(3*y + x + 1)

  return ''.join(map(str, code))

def main():
  print(getBathroomCode(sys.stdin.read()))

if __name__ == "__main__":
  unittest.main(exit=False)
  main()
<|endoftext|>


<commit_before>from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
from six import string_types

import numpy as np
import scipy.stats
import pandas as pd

from ggplot.utils import make_iterable_ntimes
from .stat import stat

def bootstrap_statistics(series, statistic, n_samples=1000, confidence_interval=0.95):
    """
    Default parameters taken from
    R's Hmisc smean.cl.boot
    """
    alpha = 1 - confidence_interval
    inds = np.random.randint(0, len(series), size=(n_samples, len(series)))
    samples = series.values[inds]
    means = np.sort(statistic(samples, axis=1))
    return pd.Series({'ymin': means[int((alpha/2)*n_samples)],
                      'ymax': means[int((1-alpha/2)*n_samples)],
                      'y': statistic(series)})

def mean_cl_boot(series, n_samples=1000, confidence_interval=0.95):
    return bootstrap_statistics(series, np.mean, n_samples=n_samples, confidence_interval=confidence_interval)

def mean_cl_normal(series, confidence_interval=0.95):
    """
    Adapted from http://stackoverflow.com/a/15034143
    """
    a = np.asarray(series)
    m = np.mean(a)
    se = scipy.stats.sem(a)
    h = se * scipy.stats.t._ppf((1+confidence_interval)/2, len(a)-1)
    return pd.Series({'y': m,
                      'ymin': m-h,
                      'ymax': m+h})

def mean_sdl(series, mult=2):
    m = series.mean()
    s = series.std()
    return pd.Series({'y': m,
                      'ymin': m-mult*s,
                      'ymax': m+mult*s})

def median_hilow(series, confidence_interval=0.95):
    tail = (1 - confidence_interval) / 2
    return pd.Series({'y': np.median(series),
                      'ymin': np.percentile(series, 100 * tail),
                      'ymax': np.percentile(series, 100 * (1 - tail))})

def mean_se(series, mult=1):
    m = np.mean(series)
    se = mult * np.sqrt(np.var(series) / len(series))
    return pd.Series({'y': m,
                      'ymin': m-se,
                      'ymax': m+se})

function_dict = {'mean_cl_boot': mean_cl_boot,
                 'mean_cl_normal': mean_cl_normal,
                 'mean_sdl': mean_sdl,
                 'median_hilow': median_hilow,
                 'mean_se': mean_se}

def combined_fun_data(series, fun_y, fun_ymin, fun_ymax):
    d = {}
    if fun_y:
        d['y'] = fun_y(series)
    if fun_ymin:
        d['ymin'] = fun_ymin(series)
    if fun_ymax:
        d['ymax'] = fun_ymax(series)
    return pd.Series(d)

class stat_summary(stat):
    """
    Calculate summary statistics depending on x, usually by
    calculating three values ymin, y and ymax for each value of x.

    Parameters
    ----------

    fun_data : string or function
        One of `"mean_cl_boot"`, `"mean_cl_normal"`, `"mean_sdl"`, `"median_hilow"` or
        any function that takes a pandas series and returns a series with three
        rows indexed as `y`, `ymin` and `ymax`. Defaults to `"mean_cl_boot"`.
    fun_y, fun_ymin, fun_ymax : function
        Any function that takes a pandas series and returns a value

    Notes
    -----

    If any of `fun_y`, `fun_ymin` or `fun_ymax` are provided, the value of
    `fun_data` will be ignored.

    As R's syntax `fun.data = some_function` is not valid in python, here
    `fun_data = somefunction` is used for now.

    Examples
    --------

    General usage:

    .. plot::
        :include-source:

        from ggplot import *

        ggplot(aes(x='cut', y='carat'), data=diamonds) \
            + stat_summary(fun_data = 'mean_cl_boot')

    Provide own function:

    .. plot::
        :include-source:

        import numpy as np
        from ggplot import *
        def median_quantile(series):
            return pd.Series({'y': np.median(series),
                              'ymin': np.percentile(series, 5),
                              'ymax': np.percentile(series, 95)})
        ggplot(aes(x='cut', y='carat'), data=diamonds) \
            + stat_summary(fun_data = median_quantile)

    Provide different funtions for y, ymin and ymax:

    .. plot:
        :include-source:

        import numpy as np
        from ggplot import *
        ggplot(aes(x='cut', y='carat'), data=diamonds) \
            + stat_summary(fun_y = np.median, fun_ymin=np.min, fun_ymax=np.max)

    """
    REQUIRED_AES = {'x', 'y'}
    DEFAULT_PARAMS = {'geom': 'pointrange', 'position': 'identity', 'fun_data': 'mean_cl_boot',
                      'fun_y': None, 'fun_ymin': None, 'fun_ymax': None}
    CREATES = {'ymin', 'ymax'}

    def _calculate(self, data):

        if self.params['fun_y'] or self.params['fun_ymin'] or self.params['fun_ymax']:
            fun_data = lambda s: combined_fun_data(s, self.params['fun_y'], self.params['fun_ymin'], self.params['fun_ymax'])
        elif isinstance(self.params['fun_data'], string_types):
            fun_data = function_dict[self.params['fun_data']]
        else:
            fun_data = self.params['fun_data']

        new_data = data.groupby('x').apply(lambda df: fun_data(df['y'])).reset_index()
        data.pop('x')
        data.pop('y')

        # Copy the other aesthetics into the new dataframe
        n = len(new_data.x)
        for ae in data:
            new_data[ae] = make_iterable_ntimes(data[ae].iloc[0], n)
        return new_data
<commit_msg>Typo<commit_after>from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
from six import string_types

import numpy as np
import scipy.stats
import pandas as pd

from ggplot.utils import make_iterable_ntimes
from .stat import stat

def bootstrap_statistics(series, statistic, n_samples=1000, confidence_interval=0.95):
    """
    Default parameters taken from
    R's Hmisc smean.cl.boot
    """
    alpha = 1 - confidence_interval
    inds = np.random.randint(0, len(series), size=(n_samples, len(series)))
    samples = series.values[inds]
    means = np.sort(statistic(samples, axis=1))
    return pd.Series({'ymin': means[int((alpha/2)*n_samples)],
                      'ymax': means[int((1-alpha/2)*n_samples)],
                      'y': statistic(series)})

def mean_cl_boot(series, n_samples=1000, confidence_interval=0.95):
    return bootstrap_statistics(series, np.mean, n_samples=n_samples, confidence_interval=confidence_interval)

def mean_cl_normal(series, confidence_interval=0.95):
    """
    Adapted from http://stackoverflow.com/a/15034143
    """
    a = np.asarray(series)
    m = np.mean(a)
    se = scipy.stats.sem(a)
    h = se * scipy.stats.t._ppf((1+confidence_interval)/2, len(a)-1)
    return pd.Series({'y': m,
                      'ymin': m-h,
                      'ymax': m+h})

def mean_sdl(series, mult=2):
    m = series.mean()
    s = series.std()
    return pd.Series({'y': m,
                      'ymin': m-mult*s,
                      'ymax': m+mult*s})

def median_hilow(series, confidence_interval=0.95):
    tail = (1 - confidence_interval) / 2
    return pd.Series({'y': np.median(series),
                      'ymin': np.percentile(series, 100 * tail),
                      'ymax': np.percentile(series, 100 * (1 - tail))})

def mean_se(series, mult=1):
    m = np.mean(series)
    se = mult * np.sqrt(np.var(series) / len(series))
    return pd.Series({'y': m,
                      'ymin': m-se,
                      'ymax': m+se})

function_dict = {'mean_cl_boot': mean_cl_boot,
                 'mean_cl_normal': mean_cl_normal,
                 'mean_sdl': mean_sdl,
                 'median_hilow': median_hilow,
                 'mean_se': mean_se}

def combined_fun_data(series, fun_y, fun_ymin, fun_ymax):
    d = {}
    if fun_y:
        d['y'] = fun_y(series)
    if fun_ymin:
        d['ymin'] = fun_ymin(series)
    if fun_ymax:
        d['ymax'] = fun_ymax(series)
    return pd.Series(d)

class stat_summary(stat):
    """
    Calculate summary statistics depending on x, usually by
    calculating three values ymin, y and ymax for each value of x.

    Parameters
    ----------

    fun_data : string or function
        One of `"mean_cl_boot"`, `"mean_cl_normal"`, `"mean_sdl"`, `"median_hilow"` or
        any function that takes a pandas series and returns a series with three
        rows indexed as `y`, `ymin` and `ymax`. Defaults to `"mean_cl_boot"`.
    fun_y, fun_ymin, fun_ymax : function
        Any function that takes a pandas series and returns a value

    Notes
    -----

    If any of `fun_y`, `fun_ymin` or `fun_ymax` are provided, the value of
    `fun_data` will be ignored.

    As R's syntax `fun.data = some_function` is not valid in python, here
    `fun_data = somefunction` is used for now.

    Examples
    --------

    General usage:

    .. plot::
        :include-source:

        from ggplot import *

        ggplot(aes(x='cut', y='carat'), data=diamonds) \\
            + stat_summary(fun_data = 'mean_cl_boot')

    Provide own function:

    .. plot::
        :include-source:

        import numpy as np
        from ggplot import *
        def median_quantile(series):
            return pd.Series({'y': np.median(series),
                              'ymin': np.percentile(series, 5),
                              'ymax': np.percentile(series, 95)})
        ggplot(aes(x='cut', y='carat'), data=diamonds) \\
            + stat_summary(fun_data = median_quantile)

    Provide different funtions for y, ymin and ymax:

    .. plot:
        :include-source:

        import numpy as np
        from ggplot import *
        ggplot(aes(x='cut', y='carat'), data=diamonds) \\
            + stat_summary(fun_y = np.median, fun_ymin=np.min, fun_ymax=np.max)

    """
    REQUIRED_AES = {'x', 'y'}
    DEFAULT_PARAMS = {'geom': 'pointrange', 'position': 'identity', 'fun_data': 'mean_cl_boot',
                      'fun_y': None, 'fun_ymin': None, 'fun_ymax': None}
    CREATES = {'ymin', 'ymax'}

    def _calculate(self, data):

        if self.params['fun_y'] or self.params['fun_ymin'] or self.params['fun_ymax']:
            fun_data = lambda s: combined_fun_data(s, self.params['fun_y'], self.params['fun_ymin'], self.params['fun_ymax'])
        elif isinstance(self.params['fun_data'], string_types):
            fun_data = function_dict[self.params['fun_data']]
        else:
            fun_data = self.params['fun_data']

        new_data = data.groupby('x').apply(lambda df: fun_data(df['y'])).reset_index()
        data.pop('x')
        data.pop('y')

        # Copy the other aesthetics into the new dataframe
        n = len(new_data.x)
        for ae in data:
            new_data[ae] = make_iterable_ntimes(data[ae].iloc[0], n)
        return new_data
<|endoftext|>


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

import sys
import logging
import time
from urlparse import urljoin

import util

from settings import session, api_url, tenant_url, public_interface, wait_for_addresses

logging.info("using api_url = %s and tenant_url = %s" % (api_url, tenant_url))

step = util.step

#
#
step("Get a list of all instances currently in the system")
#     ===================================================
#

def instance_report():
    logging.info("Requesting a list of instances...")
    r = session.get(tenant_url + "/compute/instance/")
    util.check_response(r)

    instance_ids = r.json()

    logging.info("Found %d existing instances." % (len(instance_ids)))

    if len(instance_ids) > 0:
        t = []

        for id in instance_ids:
            logging.info("Requesting information for instance %s" % (id, ))

            # The instance ID refers to a collection.  Since we want to get a summary
            # of information about the collection, strip off the trailing slash.
            instance_url = tenant_url + "/compute/instance/" + id.rstrip("/")

            r = session.get(instance_url)
            util.check_response(r)
            info = r.json()

            name = "(unassigned)"
            if info["name"]:
                name = info["name"]

            ipv4_address = "(unassigned)"
            r = session.get(instance_url + "/network/" + public_interface + "/address")
            if r.status_code == 200:
                ipv4_address = r.json()["IPv4"]

            t.append((id, name, info["state"], ipv4_address, util.basename(info["size"]), util.basename(info["profile"])))

        print util.column_report("Instance Summary",
                                 ("Id", "Name", "State", "IPv4 Address", "Size", "Profile"), t)
    else:
        print "No VM instances currently exist."
        print

instance_report()

util.end_step()

#
#
step("Request a listing of available VM profiles")
#     ==========================================
#

logging.info("Requesting a list of possible profiles...")
r = session.get(api_url + "/v0/compute/profile/")
util.check_response(r)

profile_ids = r.json()

if len(profile_ids) > 0:
    print util.column_report("Available VM Profiles",
                             ["Profile Id"], [[x] for x in r.json()])
else:
    print "No VM profiles found.  Unfortunately, we can't continue this API example."
    sys.exit(1)

util.end_step()

#
#
step("Request a listing of available VM sizes")
#     =======================================
#

logging.info("Requesting a list of possible VM sizes...")
r = session.get(api_url + "/v0/compute/size/")
util.check_response(r)

t = []
size_ids = r.json()
if len(size_ids) > 0:
    for id in size_ids:
        r = session.get(api_url + "/v0/compute/size/" + id.rstrip("/"))
        util.check_response(r)

        info = r.json()

        t.append([id, info["ncpu"], info["memory"]])

    print util.column_report("Available VM Sizes",
                             ["Id", "Number of CPUs", "Amount of RAM"],
                             t)
else:
    print "No VM sizes found.  Unfortunately, we can't continue this API example."
    sys.exit(1)

util.end_step()

#
#
step("Create some virtual machine instances")
#     =====================================
#

def create_vm(name, size, profile):
    logging.info("Creating new instance named '%s'" % (name))
    form = {
        "size": size,
        "profile": profile,
        "ssh-key": open("id_rsa.pub", "r"),
        "name": name
    }

    r = session.post(tenant_url + "/compute/instance/", files=form)
    util.check_response(r, expected_statuses=[201])

    instance_url = urljoin(api_url, r.headers['location'])
    info = r.json()
    logging.info("New instance located at '%s'." % (instance_url))
    logging.debug(info)

    return instance_url

instance_urls = []

if len(size_ids) < 1:
    raise ValueError("no sizes available from server")

if type(size_ids) is dict:
    k = size_ids.keys()
    size_id = k[0]
elif type(size_ids) is list:
    size_id = size_ids[0]
else:
    raise TypeError("unknown size_id type")

if len(profile_ids) < 1:
    raise ValueError("no profiles available from server")

if type(profile_ids) is dict:
    k = profile_ids.keys()
    profile_id = k[0]
elif type(profile_ids) is list:
    profile_id = profile_id[0]
else:
    raise TypeError("unknown profile_id type")

instance_urls.append(create_vm("New Developer Instance", size_id, profile_id))
instance_urls.append(create_vm("Another Developer Instance", size_id, profile_id))
instance_urls.append(create_vm("Yet Another Developer Instance", size_id, profile_id))

instance_report()

util.end_step()

#
#
step("Start all of our new Virtual Machines")
#     =====================================
#

def control_vm(url, action):
    logging.info("Running action '%s' at '%s'" % (action, url))
    r = session.post(url + "/" + action)
    # If the status code is 400, it means that the instance was already in that state.
    util.check_response(r, expected_statuses=[200, 400])

for url in instance_urls:
    control_vm(url, "start")

util.end_step()

#
#
step("Show Our Instance Status")
#     ========================
#

instance_report()

util.end_step()

if wait_for_addresses:
    #
    #
    step("Waiting (up to 180 seconds) For IPv4 Addresses To Be Assigned...")
    #     =============================================================
    #
    logging.info("Waiting for all of our instances to be assigned IPv4 addresses...")

    start = time.time()
    addresses = [None] * len(instance_urls)

    found = 0
    while True:
        if (time.time() - start) > 180:
            logging.error("Timing out waiting for IPv4 addresses.")
            break

        for idx, url in enumerate(instance_urls):
            if addresses[idx] != None:
                continue

            logging.info("Attempting to get the address for instance '%s'" % (url,))
            url = url + "/network/" + public_interface + "/address"
            r = session.get(url)
            if r.status_code != 200:
                continue

            addresses[idx] = r.json()["IPv4"]

            found += 1

        if found >= len(instance_urls):
            break

        logging.debug("Sleeping for 5 seconds...")
        time.sleep(5)

    t = []

    logging.info("got the following addresses %s" % (addresses,))

    instance_report()

    util.end_step()

#
#
step("Deleting all of the Virtual Machines We Created")
#     =============================================
#

def delete_vm(uri):
    control_vm(url, "stop")

    logging.info("Deleting instance at '%s'" % (uri))
    r = session.delete(url)
    util.check_response(r)

for url in instance_urls:
    delete_vm(url)

util.end_step()

#
#
step("Show Our Instance Status")
#     ========================
#

instance_report()
<commit_msg>Whitespace.<commit_after>#!/usr/bin/env python

import sys
import logging
import time
from urlparse import urljoin

import util

from settings import session, api_url, tenant_url, public_interface, wait_for_addresses

logging.info("using api_url = %s and tenant_url = %s" % (api_url, tenant_url))

step = util.step

#
#
step("Get a list of all instances currently in the system")
#     ===================================================
#

def instance_report():
    logging.info("Requesting a list of instances...")
    r = session.get(tenant_url + "/compute/instance/")
    util.check_response(r)

    instance_ids = r.json()

    logging.info("Found %d existing instances." % (len(instance_ids)))

    if len(instance_ids) > 0:
        t = []

        for id in instance_ids:
            logging.info("Requesting information for instance %s" % (id, ))

            # The instance ID refers to a collection.  Since we want to get a summary
            # of information about the collection, strip off the trailing slash.
            instance_url = tenant_url + "/compute/instance/" + id.rstrip("/")

            r = session.get(instance_url)
            util.check_response(r)
            info = r.json()

            name = "(unassigned)"
            if info["name"]:
                name = info["name"]

            ipv4_address = "(unassigned)"
            r = session.get(instance_url + "/network/" + public_interface + "/address")
            if r.status_code == 200:
                ipv4_address = r.json()["IPv4"]

            t.append((id, name, info["state"], ipv4_address, util.basename(info["size"]), util.basename(info["profile"])))

        print util.column_report("Instance Summary",
                                 ("Id", "Name", "State", "IPv4 Address", "Size", "Profile"), t)
    else:
        print "No VM instances currently exist."
        print

instance_report()

util.end_step()

#
#
step("Request a listing of available VM profiles")
#     ==========================================
#

logging.info("Requesting a list of possible profiles...")
r = session.get(api_url + "/v0/compute/profile/")
util.check_response(r)

profile_ids = r.json()

if len(profile_ids) > 0:
    print util.column_report("Available VM Profiles",
                             ["Profile Id"], [[x] for x in r.json()])
else:
    print "No VM profiles found.  Unfortunately, we can't continue this API example."
    sys.exit(1)

util.end_step()

#
#
step("Request a listing of available VM sizes")
#     =======================================
#

logging.info("Requesting a list of possible VM sizes...")
r = session.get(api_url + "/v0/compute/size/")
util.check_response(r)

t = []
size_ids = r.json()
if len(size_ids) > 0:
    for id in size_ids:
        r = session.get(api_url + "/v0/compute/size/" + id.rstrip("/"))
        util.check_response(r)

        info = r.json()

        t.append([id, info["ncpu"], info["memory"]])

    print util.column_report("Available VM Sizes",
                             ["Id", "Number of CPUs", "Amount of RAM"],
                             t)
else:
    print "No VM sizes found.  Unfortunately, we can't continue this API example."
    sys.exit(1)

util.end_step()

#
#
step("Create some virtual machine instances")
#     =====================================
#

def create_vm(name, size, profile):
    logging.info("Creating new instance named '%s'" % (name))
    form = {
        "size": size,
        "profile": profile,
        "ssh-key": open("id_rsa.pub", "r"),
        "name": name
    }

    r = session.post(tenant_url + "/compute/instance/", files=form)
    util.check_response(r, expected_statuses=[201])

    instance_url = urljoin(api_url, r.headers['location'])
    info = r.json()
    logging.info("New instance located at '%s'." % (instance_url))
    logging.debug(info)

    return instance_url

instance_urls = []

if len(size_ids) < 1:
    raise ValueError("no sizes available from server")

if type(size_ids) is dict:
    k = size_ids.keys()
    size_id = k[0]
elif type(size_ids) is list:
    size_id = size_ids[0]
else:
    raise TypeError("unknown size_id type")

if len(profile_ids) < 1:
    raise ValueError("no profiles available from server")

if type(profile_ids) is dict:
    k = profile_ids.keys()
    profile_id = k[0]
elif type(profile_ids) is list:
    profile_id = profile_id[0]
else:
    raise TypeError("unknown profile_id type")

instance_urls.append(create_vm("New Developer Instance", size_id, profile_id))
instance_urls.append(create_vm("Another Developer Instance", size_id, profile_id))
instance_urls.append(create_vm("Yet Another Developer Instance", size_id, profile_id))

instance_report()

util.end_step()

#
#
step("Start all of our new Virtual Machines")
#     =====================================
#

def control_vm(url, action):
    logging.info("Running action '%s' at '%s'" % (action, url))
    r = session.post(url + "/" + action)
    # If the status code is 400, it means that the instance was already in that state.
    util.check_response(r, expected_statuses=[200, 400])

for url in instance_urls:
    control_vm(url, "start")

util.end_step()

#
#
step("Show Our Instance Status")
#     ========================
#

instance_report()

util.end_step()

if wait_for_addresses:
    #
    #
    step("Waiting (up to 180 seconds) For IPv4 Addresses To Be Assigned...")
    #     =============================================================
    #
    logging.info("Waiting for all of our instances to be assigned IPv4 addresses...")

    start = time.time()
    addresses = [None] * len(instance_urls)

    found = 0
    while True:
        if (time.time() - start) > 180:
            logging.error("Timing out waiting for IPv4 addresses.")
            break

        for idx, url in enumerate(instance_urls):
            if addresses[idx] != None:
                continue

            logging.info("Attempting to get the address for instance '%s'" % (url,))
            url = url + "/network/" + public_interface + "/address"
            r = session.get(url)
            if r.status_code != 200:
                continue

            addresses[idx] = r.json()["IPv4"]

            found += 1

        if found >= len(instance_urls):
            break

        logging.debug("Sleeping for 5 seconds...")
        time.sleep(5)

    t = []

    logging.info("got the following addresses %s" % (addresses,))

    instance_report()

    util.end_step()

#
#
step("Deleting all of the Virtual Machines We Created")
#     =============================================
#

def delete_vm(uri):
    control_vm(url, "stop")

    logging.info("Deleting instance at '%s'" % (uri))
    r = session.delete(url)
    util.check_response(r)

for url in instance_urls:
    delete_vm(url)

util.end_step()

#
#
step("Show Our Instance Status")
#     ========================
#

instance_report()
<|endoftext|>


<commit_before>"""
Functions for more advanced calculations of quantities and properties of
quantum objects.
"""

from itertools import product
from collections import OrderedDict
import numpy as np
from quijy.core import (isket, isbra, isop, qonvert, kron, ldmul, comm,
                        eyepad, tr)
from quijy.gen import sig
from quijy.solve import eigvals, eigsys, norm2

def trx(p, dims, keep):
    """ Perform partial trace.
    Input:
        p: state to perform partial trace on, vector or operator
        dims: list of subsystem dimensions
        keep: index of subsytems to keep
    Returns:
        Density matrix of subsytem dimensions dims[keep]
    """
    # Cast as ndarrays for 2D+ reshaping
    if np.size(keep) == np.size(dims):  # keep all subsystems
        if not isop(p):
            return p * p.H  # but return as density operator for consistency
        return p
    n = len(dims)
    dims = np.array(dims)
    keep = np.array(keep)
    keep = np.reshape(keep, [keep.size])  # make sure array
    lose = np.delete(np.arange(n), keep)
    dimkeep = np.prod(dims[keep])
    dimlose = np.prod(dims[lose])
    # Permute dimensions into block of keep and block of lose
    perm = np.r_[keep, lose]
    # Apply permutation to state and trace out block of lose
    if not isop(p):  # p = psi
        p = np.array(p)
        p = p.reshape(dims) \
            .transpose(perm) \
            .reshape([dimkeep, dimlose])
        p = np.matrix(p, copy=True)
        return qonvert(p * p.H)
    else:  # p = rho
        p = np.array(p)
        p = p.reshape(np.r_[dims, dims]) \
            .transpose(np.r_[perm, perm + n]) \
            .reshape([dimkeep, dimlose, dimkeep, dimlose]) \
            .trace(axis1=1, axis2=3)
        return qonvert(p)

def partial_transpose(p, dims=[2, 2]):
    """
    Partial transpose
    """
    if isket(p):  # state vector supplied
        p = p * p.H
    elif isbra(p):
        p = p.H * p
    p = np.array(p)\
        .reshape(np.concatenate((dims, dims)))  \
        .transpose([2, 1, 0, 3])  \
        .reshape([np.prod(dims), np.prod(dims)])
    return qonvert(p)

def entropy(rho):
    """
    Computes the (von Neumann) entropy of positive matrix rho
    """
    l = eigvals(rho)
    l = l[np.nonzero(l)]
    return np.sum(-l * np.log2(l))

def mutual_information(p, dims=[2, 2], sysa=0, sysb=1):
    """
    Partitions rho into dims, and finds the mutual information between the
    subsystems at indices sysa and sysb
    """
    if isop(p) or len(dims) > 2:  # mixed combined system
        rhoab = trx(p, dims, [sysa, sysb])
        rhoa = trx(rhoab, np.r_[dims[sysa], dims[sysb]], 0)
        rhob = trx(rhoab, np.r_[dims[sysa], dims[sysb]], 1)
        hab = entropy(rhoab)
        ha = entropy(rhoa)
        hb = entropy(rhob)
    else:  # pure combined system
        hab = 0.0
        rhoa = trx(p, dims, sysa)
        ha = entropy(rhoa)
        hb = ha
    return ha + hb - hab

def sqrtm(a):
    # returns sqrt of hermitan matrix, seems faster than scipy.linalg.sqrtm
    l, v = eigsys(a, sort=False)
    l = np.sqrt(l.astype(complex))
    return v * ldmul(l, v.H)

def trace_norm(a):
    """
    Returns the trace norm of operator a, that is, the sum of abs eigvals.
    """
    return np.absolute(eigvals(a, sort=False)).sum()

def trace_distance(p, w):
    return 0.5 * trace_norm(p - w)

def negativity(rho, dims=[2, 2], sysa=0, sysb=1):
    if np.size(dims) > 2:
        rho = trx(rho, dims, [sysa, sysb])
    n = (trace_norm(partial_transpose(rho)) - 1.0) / 2.0
    return max(0.0, n)

def logneg(rho, dims=[2, 2], sysa=0, sysb=1):
    if np.size(dims) > 2:
        rho = trx(rho, dims, [sysa, sysb])
        dims = [dims[sysa], dims[sysb]]
    e = np.log2(trace_norm(partial_transpose(rho, dims)))
    return max(0.0, e)

def concurrence(p):
    if isop(p):
        p = qonvert(p, 'dop')  # make sure density operator
        pt = kron(sig(2), sig(2)) * p.conj() * kron(sig(2), sig(2))
        l = np.sqrt(np.linalg.eigvals(p * pt)).real
        return max(0, 2 * np.max(l) - np.sum(l))
    else:
        p = qonvert(p, 'ket')
        pt = kron(sig(2), sig(2)) * p.conj()
        c = np.real(np.abs(p.H * p)).item(0)
        return max(0, c)

def qid(p, dims, inds, precomp_func=False, sparse_comp=True):
    inds = np.atleast_1d(inds)
    # Construct operators
    ops_i = list([list([eyepad(sig(s), dims, ind, sparse=sparse_comp)
                        for s in (1, 2, 3)])
                  for ind in inds])

    # Define function closed over precomputed operators
    def qid_func(x):
        qds = np.zeros(np.size(inds))
        for i, ops in enumerate(ops_i):
            for op in ops:
                qds[i] += 0.5 * norm2(comm(x, op))**2
        return np.sqrt(qds)

    return qid_func if precomp_func else qid_func(p)

def pauli_decomp(a, mode='p', tol=1e-3):
    """
    Decomposes an operator via the Hilbert-schmidt inner product into the
    pauli group. Can both print the decomposition or return it.
    Parameters
    ----------
        a: operator to decompose
        mode: string, include 'p' to print the decomp and/or 'c' to return dict
        tol: print operators with contirbution above tol only.
    Returns
    -------
        nds: OrderedDict of Pauli operator name and overlap with a.
    Examples
    --------
    >>> pauli_decomp( singlet(), tol=1e-2)
    II  0.25
    XX -0.25
    YY -0.25
    ZZ -0.25
    """
    a = qonvert(a, 'dop')  # make sure operator
    n = int(np.log2(a.shape[0]))  # infer number of qubits

    # define generator for inner product to iterate over efficiently
    def calc_name_and_overlap(fa):
        for perm in product('IXYZ', repeat=n):
            name = "".join(perm)
            op = kron(*[sig(s, sparse=True) for s in perm]) / 2**n
            d = tr(a * op)
            yield name, d
    nds = [nd for nd in calc_name_and_overlap(a)]

    # sort by descending overlap and turn into OrderedDict
    nds.sort(key=lambda pair: -abs(pair[1]))
    nds = OrderedDict(nds)

    # Print decomposition
    if 'p' in mode:
        for x, d in nds.items():
            if abs(d) < 0.01:
                break
            dps = int(round(0.5 - np.log10(1.001 * tol)))  # dec places to show
            print(x, '{: .{prec}f}'.format(d, prec=dps))

    # Return full calculation
    if 'c' in mode:
        return nds

def purify(rho, sparse=False):
    n = rho.shape[0]
    ls, vs = eigsys(rho)
    ls = np.sqrt(ls)
    psi = np.zeros(shape=(n**2, 1), dtype=complex)
    for i, l in enumerate(ls.flat):
        psi += l * kron(vs[:, i], basis_vec(i, n, sparse=sparse))
    return psi
<commit_msg>Clean up calc module<commit_after>"""
Functions for more advanced calculations of quantities and properties of
quantum objects.
"""

import numpy as np
import numpy.linalg as nla
from quijy.core import (isket, isbra, isop, qonvert, kron, ldmul, comm,
                        eyepad, tr)
from quijy.gen import (sig, basis_vec)
from quijy.solve import (eigvals, eigsys, norm2)
from itertools import product
from collections import OrderedDict

def trx(p, dims, keep):
    """ Perform partial trace.
    Input:
        p: state to perform partial trace on, vector or operator
        dims: list of subsystem dimensions
        keep: index of subsytems to keep
    Returns:
        Density matrix of subsytem dimensions dims[keep]
    """
    # Cast as ndarrays for 2D+ reshaping
    if np.size(keep) == np.size(dims):  # keep all subsystems
        if not isop(p):
            return p * p.H  # but return as density operator for consistency
        return p
    n = np.size(dims)
    dims = np.array(dims, ndmin=1)
    keep = np.array(keep, ndmin=1)
    lose = np.delete(range(n), keep)
    dimkeep = np.prod(dims[keep])
    dimlose = np.prod(dims[lose])
    # Permute dimensions into block of keep and block of lose
    perm = np.r_[keep, lose]
    # Apply permutation to state and trace out block of lose
    if not isop(p):  # p = psi
        p = np.array(p)
        p = p.reshape(dims) \
            .transpose(perm) \
            .reshape([dimkeep, dimlose])
        p = np.matrix(p, copy=True)
        return qonvert(p * p.H)
    else:  # p = rho
        p = np.array(p)
        p = p.reshape(np.r_[dims, dims]) \
            .transpose(np.r_[perm, perm + n]) \
            .reshape([dimkeep, dimlose, dimkeep, dimlose]) \
            .trace(axis1=1, axis2=3)
        return qonvert(p)

def partial_transpose(p, dims=[2, 2]):
    """
    Partial transpose
    """
    if isket(p):  # state vector supplied
        p = p * p.H
    elif isbra(p):
        p = p.H * p
    p = np.array(p)\
        .reshape(np.concatenate((dims, dims)))  \
        .transpose([2, 1, 0, 3])  \
        .reshape([np.prod(dims), np.prod(dims)])
    return qonvert(p)

def entropy(rho):
    """
    Computes the (von Neumann) entropy of positive matrix rho
    """
    l = eigvals(rho)
    l = l[l > 0.0]
    return np.sum(-l * np.log2(l))

def mutual_information(p, dims=[2, 2], sysa=0, sysb=1):
    """
    Partitions rho into dims, and finds the mutual information between the
    subsystems at indices sysa and sysb
    """
    if isop(p) or np.size(dims) > 2:  # mixed combined system
        rhoab = trx(p, dims, [sysa, sysb])
        rhoa = trx(rhoab, np.r_[dims[sysa], dims[sysb]], 0)
        rhob = trx(rhoab, np.r_[dims[sysa], dims[sysb]], 1)
        hab = entropy(rhoab)
        ha = entropy(rhoa)
        hb = entropy(rhob)
    else:  # pure combined system
        hab = 0.0
        rhoa = trx(p, dims, sysa)
        ha = entropy(rhoa)
        hb = ha
    return ha + hb - hab

def sqrtm(a):
    # returns sqrt of hermitan matrix, seems faster than scipy.linalg.sqrtm
    l, v = eigsys(a, sort=False)
    l = np.sqrt(l.astype(complex))
    return v * ldmul(l, v.H)

def trace_norm(a):
    """
    Returns the trace norm of operator a, that is, the sum of abs eigvals.
    """
    return np.sum(np.absolute(eigvals(a, sort=False)))

def trace_distance(p, w):
    return 0.5 * trace_norm(p - w)

def negativity(rho, dims=[2, 2], sysa=0, sysb=1):
    if np.size(dims) > 2:
        rho = trx(rho, dims, [sysa, sysb])
    n = (trace_norm(partial_transpose(rho)) - 1.0) / 2.0
    return max(0.0, n)

def logneg(rho, dims=[2, 2], sysa=0, sysb=1):
    if np.size(dims) > 2:
        rho = trx(rho, dims, [sysa, sysb])
        dims = [dims[sysa], dims[sysb]]
    e = np.log2(trace_norm(partial_transpose(rho, dims)))
    return max(0.0, e)

def concurrence(p):
    if isop(p):
        p = qonvert(p, 'dop')  # make sure density operator
        pt = kron(sig(2), sig(2)) * p.conj() * kron(sig(2), sig(2))
        l = (nla.eigvals(p * pt).real**2)**0.25
        return max(0, 2 * np.max(l) - np.sum(l))
    else:
        p = qonvert(p, 'ket')
        pt = kron(sig(2), sig(2)) * p.conj()
        c = np.real(abs(p.H * pt)).item(0)
        return max(0, c)

def qid(p, dims, inds, precomp_func=False, sparse_comp=True):
    p = qonvert(p, 'dop')
    inds = np.array(inds, ndmin=1)
    # Construct operators
    ops_i = list([list([eyepad(sig(s), dims, ind, sparse=sparse_comp)
                        for s in (1, 2, 3)])
                  for ind in inds])

    # Define function closed over precomputed operators
    def qid_func(x):
        qds = np.zeros(np.size(inds))
        for i, ops in enumerate(ops_i):
            for op in ops:
                qds[i] += norm2(comm(x, op))**2 / 3.0
        return qds

    return qid_func if precomp_func else qid_func(p)

def pauli_decomp(a, mode='p', tol=1e-3):
    """
    Decomposes an operator via the Hilbert-schmidt inner product into the
    pauli group. Can both print the decomposition or return it.
    Parameters
    ----------
        a: operator to decompose
        mode: string, include 'p' to print the decomp and/or 'c' to return dict
        tol: print operators with contirbution above tol only.
    Returns
    -------
        nds: OrderedDict of Pauli operator name and overlap with a.
    Examples
    --------
    >>> pauli_decomp( singlet(), tol=1e-2)
    II  0.25
    XX -0.25
    YY -0.25
    ZZ -0.25
    """
    a = qonvert(a, 'dop')  # make sure operator
    n = int(np.log2(a.shape[0]))  # infer number of qubits

    # define generator for inner product to iterate over efficiently
    def calc_name_and_overlap(fa):
        for perm in product('IXYZ', repeat=n):
            name = "".join(perm)
            op = kron(*[sig(s, sparse=True) for s in perm]) / 2**n
            d = tr(a * op)
            yield name, d

    nds = [nd for nd in calc_name_and_overlap(a)]
    # sort by descending overlap and turn into OrderedDict
    nds.sort(key=lambda pair: -abs(pair[1]))
    nds = OrderedDict(nds)
    # Print decomposition
    if 'p' in mode:
        for x, d in nds.items():
            if abs(d) < 0.01:
                break
            dps = int(round(0.5 - np.log10(1.001 * tol)))  # dec places to show
            print(x, '{: .{prec}f}'.format(d, prec=dps))
    # Return full calculation
    if 'c' in mode:
        return nds

def purify(rho, sparse=False):
    n = rho.shape[0]
    ls, vs = eigsys(rho)
    ls = np.sqrt(ls)
    psi = np.zeros(shape=(n**2, 1), dtype=complex)
    for i, l in enumerate(ls.flat):
        psi += l * kron(vs[:, i], basis_vec(i, n, sparse=sparse))
    return psi
<|endoftext|>


<commit_before>
from django.core.management.color import no_style
from django.db import connection, transaction, models
from django.db.backends.util import truncate_name
from django.dispatch import dispatcher
from django.conf import settings

class DatabaseOperations(object):

    """
    Generic SQL implementation of the DatabaseOperations.
    Some of this code comes from Django Evolution.
    """

    def __init__(self):
        self.debug = False
        self.deferred_sql = []

    def execute(self, sql, params=[]):
        """
        Executes the given SQL statement, with optional parameters.
        If the instance's debug attribute is True, prints out what it executes.
        """
        cursor = connection.cursor()
        if self.debug:
            print "   = %s" % sql, params
        cursor.execute(sql, params)
        try:
            return cursor.fetchall()
        except:
            return []

    def add_deferred_sql(self, sql):
        """
        Add a SQL statement to the deferred list, that won't be executed until
        this instance's execute_deferred_sql method is run.
        """
        self.deferred_sql.append(sql)

    def execute_deferred_sql(self):
        """
        Executes all deferred SQL, resetting the deferred_sql list
        """
        for sql in self.deferred_sql:
            self.execute(sql)

        self.deferred_sql = []

    def create_table(self, table_name, fields):
        """
        Creates the table 'table_name'. 'fields' is a tuple of fields,
        each repsented by a 2-part tuple of field name and a
        django.db.models.fields.Field object
        """
        qn = connection.ops.quote_name
        columns = [
            self.column_sql(table_name, field_name, field)
            for field_name, field in fields
        ]

        self.execute('CREATE TABLE %s (%s);' % (qn(table_name), ', '.join([col for col in columns if col])))

    add_table = create_table # Alias for consistency's sake

    def rename_table(self, old_table_name, table_name):
        """
        Renames the table 'old_table_name' to 'table_name'.
        """
        if old_table_name == table_name:
            # No Operation
            return
        qn = connection.ops.quote_name
        params = (qn(old_table_name), qn(table_name))
        self.execute('ALTER TABLE %s RENAME TO %s;' % params)

    def delete_table(self, table_name):
        """
        Deletes the table 'table_name'.
        """
        qn = connection.ops.quote_name
        params = (qn(table_name), )
        self.execute('DROP TABLE %s;' % params)

    drop_table = delete_table

    def add_column(self, table_name, name, field):
        """
        Adds the column 'name' to the table 'table_name'.
        Uses the 'field' paramater, a django.db.models.fields.Field instance,
        to generate the necessary sql

        @param table_name: The name of the table to add the column to
        @param name: The name of the column to add
        @param field: The field to use
        """
        qn = connection.ops.quote_name
        sql = self.column_sql(table_name, name, field)
        if sql:
            params = (
                qn(table_name),
                sql,
            )
            sql = 'ALTER TABLE %s ADD COLUMN %s;' % params
            self.execute(sql)

    alter_string_set_type = 'ALTER COLUMN %(column)s TYPE %(type)s'
    alter_string_set_null = 'ALTER COLUMN %(column)s SET NOT NULL'
    alter_string_drop_null = 'ALTER COLUMN %(column)s DROP NOT NULL'

    def alter_column(self, table_name, name, field):
        """
        Alters the given column name so it will match the given field.
        Note that conversion between the two by the database must be possible.

        @param table_name: The name of the table to add the column to
        @param name: The name of the column to alter
        @param field: The new field definition to use
        """

        # hook for the field to do any resolution prior to it's attributes being queried
        if hasattr(field, 'south_init'):
            field.south_init()

        qn = connection.ops.quote_name

        # First, change the type
        params = {
            "column": qn(name),
            "type": field.db_type(),
        }
        sqls = [self.alter_string_set_type % params]

        # Next, set any default
        params = (
            qn(name),
        )

        if not field.null and field.has_default():
            default = field.get_default()
            if isinstance(default, basestring):
                default = "'%s'" % default
            params += ("SET DEFAULT %s",)
        else:
            params += ("DROP DEFAULT",)

        sqls.append('ALTER COLUMN %s %s ' % params)

        # Next, nullity
        params = {
            "column": qn(name),
            "type": field.db_type(),
        }
        if field.null:
            sqls.append(self.alter_string_drop_null % params)
        else:
            sqls.append(self.alter_string_set_null % params)

        # TODO: Unique

        self.execute("ALTER TABLE %s %s;" % (qn(table_name), ", ".join(sqls)))

    def column_sql(self, table_name, field_name, field, tablespace=''):
        """
        Creates the SQL snippet for a column. Used by add_column and add_table.
        """
        qn = connection.ops.quote_name

        field.set_attributes_from_name(field_name)

        # hook for the field to do any resolution prior to it's attributes being queried
        if hasattr(field, 'south_init'):
            field.south_init()

        sql = field.db_type()
        if sql:
            field_output = [qn(field.column), sql]
            field_output.append('%sNULL' % (not field.null and 'NOT ' or ''))
            if field.primary_key:
                field_output.append('PRIMARY KEY')
            elif field.unique:
                field_output.append('UNIQUE')

            tablespace = field.db_tablespace or tablespace
            if tablespace and connection.features.supports_tablespaces and field.unique:
                # We must specify the index tablespace inline, because we
                # won't be generating a CREATE INDEX statement for this field.
                field_output.append(connection.ops.tablespace_sql(tablespace, inline=True))

            sql = ' '.join(field_output)
            sqlparams = ()
            # if the field is "NOT NULL" and a default value is provided, create the column with it
            # this allows the addition of a NOT NULL field to a table with existing rows
            if not field.null and field.has_default():
                default = field.get_default()
                if isinstance(default, basestring):
                    default = "'%s'" % default.replace("'", "''")
                sql += " DEFAULT %s"
                sqlparams = (default)

            if field.rel:
                self.add_deferred_sql(
                    self.foreign_key_sql(
                        table_name,
                        field.column,
                        field.rel.to._meta.db_table,
                        field.rel.to._meta.get_field(field.rel.field_name).column
                    )
                )

            if field.db_index and not field.unique:
                self.add_deferred_sql(self.create_index_sql(table_name, [field.column]))

        if hasattr(field, 'post_create_sql'):
            style = no_style()
            for stmt in field.post_create_sql(style, table_name):
                self.add_deferred_sql(stmt)

        if sql:
            return sql % sqlparams
        else:
            return None

    def foreign_key_sql(self, from_table_name, from_column_name, to_table_name, to_column_name):
        """
        Generates a full SQL statement to add a foreign key constraint
        """
        constraint_name = '%s_refs_%s_%x' % (from_column_name, to_column_name, abs(hash((from_table_name, to_table_name))))
        return 'ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % (
            from_table_name,
            truncate_name(constraint_name, connection.ops.max_name_length()),
            from_column_name,
            to_table_name,
            to_column_name,
            connection.ops.deferrable_sql() # Django knows this
        )

    def create_index_name(self, table_name, column_names):
        """
        Generate a unique name for the index
        """
        index_unique_name = ''
        if len(column_names) > 1:
            index_unique_name = '_%x' % abs(hash((table_name, ','.join(column_names))))

        return '%s_%s%s' % (table_name, column_names[0], index_unique_name)

    def create_index_sql(self, table_name, column_names, unique=False, db_tablespace=''):
        """
        Generates a create index statement on 'table_name' for a list of 'column_names'
        """
        if not column_names:
            print "No column names supplied on which to create an index"
            return ''

        if db_tablespace and connection.features.supports_tablespaces:
            tablespace_sql = ' ' + connection.ops.tablespace_sql(db_tablespace)
        else:
            tablespace_sql = ''

        index_name = self.create_index_name(table_name, column_names)
        qn = connection.ops.quote_name
        return 'CREATE %sINDEX %s ON %s (%s)%s;' % (
            unique and 'UNIQUE ' or '',
            index_name,
            table_name,
            ','.join([qn(field) for field in column_names]),
            tablespace_sql
            )

    def create_index(self, table_name, column_names, unique=False, db_tablespace=''):
        """ Executes a create index statement """
        sql = self.create_index_sql(table_name, column_names, unique, db_tablespace)
        self.execute(sql)

    def delete_index(self, table_name, column_names, db_tablespace=''):
        """
        Deletes an index created with create_index.
        This is possible using only columns due to the deterministic
        index naming function which relies on column names.
        """
        name = self.create_index_name(table_name, column_names)
        sql = "DROP INDEX %s" % name
        self.execute(sql)

    def delete_column(self, table_name, name):
        """
        Deletes the column 'column_name' from the table 'table_name'.
        """
        qn = connection.ops.quote_name
        params = (qn(table_name), qn(name))
        self.execute('ALTER TABLE %s DROP COLUMN %s CASCADE;' % params, [])

    def rename_column(self, table_name, old, new):
        """
        Renames the column 'old' from the table 'table_name' to 'new'.
        """
        raise NotImplementedError("rename_column has no generic SQL syntax")

    def start_transaction(self):
        """
        Makes sure the following commands are inside a transaction.
        Must be followed by a (commit|rollback)_transaction call.
        """
        transaction.commit_unless_managed()
        transaction.enter_transaction_management()
        transaction.managed(True)

    def commit_transaction(self):
        """
        Commits the current transaction.
        Must be preceded by a start_transaction call.
        """
        transaction.commit()
        transaction.leave_transaction_management()

    def rollback_transaction(self):
        """
        Rolls back the current transaction.
        Must be preceded by a start_transaction call.
        """
        transaction.rollback()
        transaction.leave_transaction_management()

    def send_create_signal(self, app_label, model_names):
        """
        Sends a post_syncdb signal for the model specified.

        If the model is not found (perhaps it's been deleted?),
        no signal is sent.

        TODO: The behavior of django.contrib.* apps seems flawed in that
        they don't respect created_models.  Rather, they blindly execute
        over all models within the app sending the signal.  This is a
        patch we should push Django to make  For now, this should work.
        """
        app = models.get_app(app_label)
        if not app:
            return

        created_models = []
        for model_name in model_names:
            model = models.get_model(app_label, model_name)
            if model:
                created_models.append(model)

        if created_models:
            # syncdb defaults -- perhaps take these as options?
            verbosity = 1
            interactive = True

            if hasattr(dispatcher, "send"):
                dispatcher.send(signal=models.signals.post_syncdb, sender=app,
                app=app, created_models=created_models,
                verbosity=verbosity, interactive=interactive)
            else:
                models.signals.post_syncdb.send(sender=app,
                app=app, created_models=created_models,
                verbosity=verbosity, interactive=interactive)

    def mock_model(self, model_name, db_table, db_tablespace='',
                    pk_field_name='id', pk_field_type=models.AutoField,
                    pk_field_kwargs={}):
        """
        Generates a MockModel class that provides enough information
        to be used by a foreign key/many-to-many relationship.

        Migrations should prefer to use these rather than actual models
        as models could get deleted over time, but these can remain in
        migration files forever.
        """
        class MockOptions(object):
            def __init__(self):
                self.db_table = db_table
                self.db_tablespace = db_tablespace or settings.DEFAULT_TABLESPACE
                self.object_name = model_name
                self.module_name = model_name.lower()

                if pk_field_type == models.AutoField:
                    pk_field_kwargs['primary_key'] = True

                self.pk = pk_field_type(**pk_field_kwargs)
                self.pk.set_attributes_from_name(pk_field_name)
                self.abstract = False

            def get_field_by_name(self, field_name):
                # we only care about the pk field
                return (self.pk, self.model, True, False)

            def get_field(self, name):
                # we only care about the pk field
                return self.pk

        class MockModel(object):
            _meta = None

        # We need to return an actual class object here, not an instance
        MockModel._meta = MockOptions()
        MockModel._meta.model = MockModel
        return MockModel
<commit_msg>Make datetime defaults work correctly.<commit_after>
import datetime
from django.core.management.color import no_style
from django.db import connection, transaction, models
from django.db.backends.util import truncate_name
from django.dispatch import dispatcher
from django.conf import settings

class DatabaseOperations(object):

    """
    Generic SQL implementation of the DatabaseOperations.
    Some of this code comes from Django Evolution.
    """

    def __init__(self):
        self.debug = False
        self.deferred_sql = []

    def execute(self, sql, params=[]):
        """
        Executes the given SQL statement, with optional parameters.
        If the instance's debug attribute is True, prints out what it executes.
        """
        cursor = connection.cursor()
        if self.debug:
            print "   = %s" % sql, params
        cursor.execute(sql, params)
        try:
            return cursor.fetchall()
        except:
            return []

    def add_deferred_sql(self, sql):
        """
        Add a SQL statement to the deferred list, that won't be executed until
        this instance's execute_deferred_sql method is run.
        """
        self.deferred_sql.append(sql)

    def execute_deferred_sql(self):
        """
        Executes all deferred SQL, resetting the deferred_sql list
        """
        for sql in self.deferred_sql:
            self.execute(sql)

        self.deferred_sql = []

    def create_table(self, table_name, fields):
        """
        Creates the table 'table_name'. 'fields' is a tuple of fields,
        each repsented by a 2-part tuple of field name and a
        django.db.models.fields.Field object
        """
        qn = connection.ops.quote_name
        columns = [
            self.column_sql(table_name, field_name, field)
            for field_name, field in fields
        ]

        self.execute('CREATE TABLE %s (%s);' % (qn(table_name), ', '.join([col for col in columns if col])))

    add_table = create_table # Alias for consistency's sake

    def rename_table(self, old_table_name, table_name):
        """
        Renames the table 'old_table_name' to 'table_name'.
        """
        if old_table_name == table_name:
            # No Operation
            return
        qn = connection.ops.quote_name
        params = (qn(old_table_name), qn(table_name))
        self.execute('ALTER TABLE %s RENAME TO %s;' % params)

    def delete_table(self, table_name):
        """
        Deletes the table 'table_name'.
        """
        qn = connection.ops.quote_name
        params = (qn(table_name), )
        self.execute('DROP TABLE %s;' % params)

    drop_table = delete_table

    def add_column(self, table_name, name, field):
        """
        Adds the column 'name' to the table 'table_name'.
        Uses the 'field' paramater, a django.db.models.fields.Field instance,
        to generate the necessary sql

        @param table_name: The name of the table to add the column to
        @param name: The name of the column to add
        @param field: The field to use
        """
        qn = connection.ops.quote_name
        sql = self.column_sql(table_name, name, field)
        if sql:
            params = (
                qn(table_name),
                sql,
            )
            sql = 'ALTER TABLE %s ADD COLUMN %s;' % params
            self.execute(sql)

    alter_string_set_type = 'ALTER COLUMN %(column)s TYPE %(type)s'
    alter_string_set_null = 'ALTER COLUMN %(column)s SET NOT NULL'
    alter_string_drop_null = 'ALTER COLUMN %(column)s DROP NOT NULL'

    def alter_column(self, table_name, name, field):
        """
        Alters the given column name so it will match the given field.
        Note that conversion between the two by the database must be possible.

        @param table_name: The name of the table to add the column to
        @param name: The name of the column to alter
        @param field: The new field definition to use
        """

        # hook for the field to do any resolution prior to it's attributes being queried
        if hasattr(field, 'south_init'):
            field.south_init()

        qn = connection.ops.quote_name

        # First, change the type
        params = {
            "column": qn(name),
            "type": field.db_type(),
        }
        sqls = [self.alter_string_set_type % params]

        # Next, set any default
        params = (
            qn(name),
        )

        if not field.null and field.has_default():
            default = field.get_default()
            if isinstance(default, basestring):
                default = "'%s'" % default
            params += ("SET DEFAULT %s",)
        else:
            params += ("DROP DEFAULT",)

        sqls.append('ALTER COLUMN %s %s ' % params)

        # Next, nullity
        params = {
            "column": qn(name),
            "type": field.db_type(),
        }
        if field.null:
            sqls.append(self.alter_string_drop_null % params)
        else:
            sqls.append(self.alter_string_set_null % params)

        # TODO: Unique

        self.execute("ALTER TABLE %s %s;" % (qn(table_name), ", ".join(sqls)))

    def column_sql(self, table_name, field_name, field, tablespace=''):
        """
        Creates the SQL snippet for a column. Used by add_column and add_table.
        """
        qn = connection.ops.quote_name

        field.set_attributes_from_name(field_name)

        # hook for the field to do any resolution prior to it's attributes being queried
        if hasattr(field, 'south_init'):
            field.south_init()

        sql = field.db_type()
        if sql:
            field_output = [qn(field.column), sql]
            field_output.append('%sNULL' % (not field.null and 'NOT ' or ''))
            if field.primary_key:
                field_output.append('PRIMARY KEY')
            elif field.unique:
                field_output.append('UNIQUE')

            tablespace = field.db_tablespace or tablespace
            if tablespace and connection.features.supports_tablespaces and field.unique:
                # We must specify the index tablespace inline, because we
                # won't be generating a CREATE INDEX statement for this field.
                field_output.append(connection.ops.tablespace_sql(tablespace, inline=True))

            sql = ' '.join(field_output)
            sqlparams = ()
            # if the field is "NOT NULL" and a default value is provided, create the column with it
            # this allows the addition of a NOT NULL field to a table with existing rows
            if not field.null and field.has_default():
                default = field.get_default()
                if isinstance(default, basestring):
                    default = "'%s'" % default.replace("'", "''")
                elif isinstance(default, datetime.date):
                    default = "'%s'" % default
                sql += " DEFAULT %s"
                sqlparams = (default)

            if field.rel:
                self.add_deferred_sql(
                    self.foreign_key_sql(
                        table_name,
                        field.column,
                        field.rel.to._meta.db_table,
                        field.rel.to._meta.get_field(field.rel.field_name).column
                    )
                )

            if field.db_index and not field.unique:
                self.add_deferred_sql(self.create_index_sql(table_name, [field.column]))

        if hasattr(field, 'post_create_sql'):
            style = no_style()
            for stmt in field.post_create_sql(style, table_name):
                self.add_deferred_sql(stmt)

        if sql:
            return sql % sqlparams
        else:
            return None

    def foreign_key_sql(self, from_table_name, from_column_name, to_table_name, to_column_name):
        """
        Generates a full SQL statement to add a foreign key constraint
        """
        constraint_name = '%s_refs_%s_%x' % (from_column_name, to_column_name, abs(hash((from_table_name, to_table_name))))
        return 'ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % (
            from_table_name,
            truncate_name(constraint_name, connection.ops.max_name_length()),
            from_column_name,
            to_table_name,
            to_column_name,
            connection.ops.deferrable_sql() # Django knows this
        )

    def create_index_name(self, table_name, column_names):
        """
        Generate a unique name for the index
        """
        index_unique_name = ''
        if len(column_names) > 1:
            index_unique_name = '_%x' % abs(hash((table_name, ','.join(column_names))))

        return '%s_%s%s' % (table_name, column_names[0], index_unique_name)

    def create_index_sql(self, table_name, column_names, unique=False, db_tablespace=''):
        """
        Generates a create index statement on 'table_name' for a list of 'column_names'
        """
        if not column_names:
            print "No column names supplied on which to create an index"
            return ''

        if db_tablespace and connection.features.supports_tablespaces:
            tablespace_sql = ' ' + connection.ops.tablespace_sql(db_tablespace)
        else:
            tablespace_sql = ''

        index_name = self.create_index_name(table_name, column_names)
        qn = connection.ops.quote_name
        return 'CREATE %sINDEX %s ON %s (%s)%s;' % (
            unique and 'UNIQUE ' or '',
            index_name,
            table_name,
            ','.join([qn(field) for field in column_names]),
            tablespace_sql
            )

    def create_index(self, table_name, column_names, unique=False, db_tablespace=''):
        """ Executes a create index statement """
        sql = self.create_index_sql(table_name, column_names, unique, db_tablespace)
        self.execute(sql)

    def delete_index(self, table_name, column_names, db_tablespace=''):
        """
        Deletes an index created with create_index.
        This is possible using only columns due to the deterministic
        index naming function which relies on column names.
        """
        name = self.create_index_name(table_name, column_names)
        sql = "DROP INDEX %s" % name
        self.execute(sql)

    def delete_column(self, table_name, name):
        """
        Deletes the column 'column_name' from the table 'table_name'.
        """
        qn = connection.ops.quote_name
        params = (qn(table_name), qn(name))
        self.execute('ALTER TABLE %s DROP COLUMN %s CASCADE;' % params, [])

    def rename_column(self, table_name, old, new):
        """
        Renames the column 'old' from the table 'table_name' to 'new'.
        """
        raise NotImplementedError("rename_column has no generic SQL syntax")

    def start_transaction(self):
        """
        Makes sure the following commands are inside a transaction.
        Must be followed by a (commit|rollback)_transaction call.
        """
        transaction.commit_unless_managed()
        transaction.enter_transaction_management()
        transaction.managed(True)

    def commit_transaction(self):
        """
        Commits the current transaction.
        Must be preceded by a start_transaction call.
        """
        transaction.commit()
        transaction.leave_transaction_management()

    def rollback_transaction(self):
        """
        Rolls back the current transaction.
        Must be preceded by a start_transaction call.
        """
        transaction.rollback()
        transaction.leave_transaction_management()

    def send_create_signal(self, app_label, model_names):
        """
        Sends a post_syncdb signal for the model specified.

        If the model is not found (perhaps it's been deleted?),
        no signal is sent.

        TODO: The behavior of django.contrib.* apps seems flawed in that
        they don't respect created_models.  Rather, they blindly execute
        over all models within the app sending the signal.  This is a
        patch we should push Django to make  For now, this should work.
        """
        app = models.get_app(app_label)
        if not app:
            return

        created_models = []
        for model_name in model_names:
            model = models.get_model(app_label, model_name)
            if model:
                created_models.append(model)

        if created_models:
            # syncdb defaults -- perhaps take these as options?
            verbosity = 1
            interactive = True

            if hasattr(dispatcher, "send"):
                dispatcher.send(signal=models.signals.post_syncdb, sender=app,
                app=app, created_models=created_models,
                verbosity=verbosity, interactive=interactive)
            else:
                models.signals.post_syncdb.send(sender=app,
                app=app, created_models=created_models,
                verbosity=verbosity, interactive=interactive)

    def mock_model(self, model_name, db_table, db_tablespace='',
                    pk_field_name='id', pk_field_type=models.AutoField,
                    pk_field_kwargs={}):
        """
        Generates a MockModel class that provides enough information
        to be used by a foreign key/many-to-many relationship.

        Migrations should prefer to use these rather than actual models
        as models could get deleted over time, but these can remain in
        migration files forever.
        """
        class MockOptions(object):
            def __init__(self):
                self.db_table = db_table
                self.db_tablespace = db_tablespace or settings.DEFAULT_TABLESPACE
                self.object_name = model_name
                self.module_name = model_name.lower()

                if pk_field_type == models.AutoField:
                    pk_field_kwargs['primary_key'] = True

                self.pk = pk_field_type(**pk_field_kwargs)
                self.pk.set_attributes_from_name(pk_field_name)
                self.abstract = False

            def get_field_by_name(self, field_name):
                # we only care about the pk field
                return (self.pk, self.model, True, False)

            def get_field(self, name):
                # we only care about the pk field
                return self.pk

        class MockModel(object):
            _meta = None

        # We need to return an actual class object here, not an instance
        MockModel._meta = MockOptions()
        MockModel._meta.model = MockModel
        return MockModel
<|endoftext|>