from __future__ import print_function
import argparse
import datetime
import os
import sys
import time

import azure.storage.blob as azureblob
import azure.batch.batch_service_client as batch
import azure.batch.batch_auth as batchauth
import azure.batch.models as batchmodels

sys.path.append('.')
import helpers
import batch_client

# Azure Batch client program which submits a job.
# Chris Joakim, Microsoft, 2018/09/13
#
# python unzip_client.py --pool UnzipPool --job unzip --task unzip_task.py

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--function',  required=True, help='logical function to execute; create_pool or submit_job')
    parser.add_argument('--pool',      required=True, help='The name of the Azure Batch Pool')
    parser.add_argument('--job',       required=False, help='The name of the Azure Batch Job')
    parser.add_argument('--task',      required=False, help='The name the Task Python script')
    parser.add_argument('--nodecount', required=False, help='The number of nodes in Azure Batch Pool', default='3')
    parser.add_argument('--ctask',     required=False, help='The name of the Task Blob Container', default='batchtask')
    parser.add_argument('--cin',       required=False, help='The name of the Input Blob Container', default='batchzips')
    parser.add_argument('--cout',      required=False, help='The name of the Output Blob Container', default='batchcsv')
    parser.add_argument('--clog',      required=False, help='The name of the Logging Blob Container', default='batchlog')
    parser.add_argument('--timeout',   required=False, help='Batch job timeout period in minutes', default='30')
    parser.add_argument('--outdir',    required=False, help='The name of the Local Output Directory', default='out')
    args = parser.parse_args()
    print('Batch Client {} at {}'.format(__file__, datetime.datetime.utcnow()))

    util = batch_client.BatchClient(args)  # BatchClient is my custom reusable class

    if args.function == 'create_pool':
        util.create_pool()

    elif args.function == 'submit_job':
        # Add the (Python) Task script that will be executed on the Azure Batch nodes.
        util.add_task_file(os.path.realpath(args.task))

        # Add the input zip files that will be uploaded and processed by the Task script in Azure.
        util.add_local_input_file(os.path.realpath('./data/NC1.zip'))
        util.add_local_input_file(os.path.realpath('./data/NC2.zip'))
        util.add_local_input_file(os.path.realpath('./data/NC3.zip'))

        util.execute(False)

        print()
        input('Press ENTER to list and download the blobs...')
        util.list_blobs(args.ctask)
        util.list_blobs(args.cin)
        util.list_blobs(args.cout)
        util.download_blobs_from_container(args.cout, args.outdir)

        print()
        input('Press ENTER to delete the job and pool...')
        util.delete_job()
        util.delete_pool()
        print('batch client script completed.')

    elif args.function == 'execute':
        # Add the (Python) Task script that will be executed on the Azure Batch nodes.
        util.add_task_file(os.path.realpath(args.task))

        # Add the input zip files that will be uploaded and processed by the Task script in Azure.
        util.add_local_input_file(os.path.realpath('./data/NC1.zip'))
        util.add_local_input_file(os.path.realpath('./data/NC2.zip'))
        util.add_local_input_file(os.path.realpath('./data/NC3.zip'))

        util.execute(True)

        print()
        input('Press ENTER to list and download the blobs...')
        util.list_blobs(args.ctask)
        util.list_blobs(args.cin)
        util.list_blobs(args.cout)
        util.download_blobs_from_container(args.cout, args.outdir)

        print()
        input('Press ENTER to delete the job and pool...')
        util.delete_job()
        util.delete_pool()
        print('batch client script completed.')


#
#    Copyright (C) 2017 Kenneth A. Giusti
#
#    Licensed to the Apache Software Foundation (ASF) under one
#    or more contributor license agreements.  See the NOTICE file
#    distributed with this work for additional information
#    regarding copyright ownership.
#
#    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.
#

import abc
import json
import logging
import math
import os
import socket
import threading
import time
from time import time as now
try:
    import Queue as queue
except ImportError:
    import queue
import oslo_messaging as om
import uuid

__all__ = [
    "RPCTestClient",
    "RPCTestServer",
    "TestNotifier",
    "TestListener",
    "Controller"
]

# the types of oslo.messaging clients
RPC_CLIENT = 'RPCClient'
RPC_SERVER = 'RPCServer'
LISTENER = 'Listener'
NOTIFIER = 'Notifier'
MESSAGING_CLIENT_TYPES = [RPC_CLIENT, RPC_SERVER, LISTENER, NOTIFIER]

# addressing for control messages
CONTROL_EXCHANGE = 'ombt-control'
CONTROLLER_TOPIC = 'controller-%s'
CLIENT_TOPIC = "client-%s-%s"    # client-$type-$topic

# addressing for RPC tests
RPC_EXCHANGE = 'ombt-rpc-test'
RPC_TOPIC = "rpc-%s"

# addressing for Notification tests
NOTIFY_EXCHANGE = 'ombt-notify-test'
NOTIFY_TOPIC = "notify-%s"

def _wait_stabilize(delay, count_fn):
    # helper to wait until a counter has stabilized for delay seconds
    count = count_fn()
    timeout = delay
    while timeout > 0:
        time.sleep(1.0)
        new_count = count_fn()
        if count != new_count:
            # reset
            count = new_count
            timeout = delay
        else:
            timeout -= 1

class Stats(object):
    """Manage a single statistic"""
    def __init__(self, min=None, max=None, total=0, count=0,
                 sum_of_squares=0, distribution=None):
        self.min = min
        self.max = max
        self.total = total
        self.count = count
        self.sum_of_squares = sum_of_squares
        # distribution of values grouped by powers of 10
        self.distribution = distribution or dict()

    @classmethod
    def from_dict(cls, values):
        if 'distribution' in values:
            # hack alert!
            # when a Stats is passed via an RPC call it appears as if the
            # distribution map's keys are converted from int to str.
            # Fix that by re-indexing the distribution map:
            new_dict = dict()
            old_dict = values['distribution']
            for k in old_dict.keys():
                new_dict[int(k)] = old_dict[k]
            values['distribution'] = new_dict
        return Stats(**values)

    def to_dict(self):
        new_dict = dict()
        for a in ["min", "max", "total", "count", "sum_of_squares"]:
            new_dict[a] = getattr(self, a)
        new_dict["distribution"] = self.distribution.copy()
        return new_dict

    def update(self, value):
        self.total += value
        self.count += 1
        self.sum_of_squares += value**2
        self.min = min(self.min, value) if self.min else value
        self.max = max(self.max, value) if self.max else value
        log = int(math.log10(value)) if value >= 1.0 else 0
        base = 10**log
        index = int(value / base)  # 0..9
        if log not in self.distribution:
            self.distribution[log] = [0 for i in range(10)]
        self.distribution[log][index] += 1

    def reset(self):
        self.__init__()

    def average(self):
        return (self.total / float(self.count)) if self.count else 0

    def std_deviation(self):
        return math.sqrt((self.sum_of_squares / float(self.count)) -
                         (self.average() ** 2)) if self.count else -1

    def merge(self, stats):
        if stats.min is not None and self.min is not None:
            self.min = min(self.min, stats.min)
        else:
            self.min = self.min or stats.min
        if stats.max is not None and self.max is not None:
            self.max = max(self.max, stats.max)
        else:
            self.max = self.max or stats.max

        self.total += stats.total
        self.count += stats.count
        self.sum_of_squares += stats.sum_of_squares
        for k in stats.distribution.keys():
            if k in self.distribution:
                self.distribution[k] = [z for z in map(lambda a, b: a + b,
                                                       stats.distribution[k],
                                                       self.distribution[k])]
            else:
                self.distribution[k] = stats.distribution[k]

    def __str__(self):
        return "min=%i, max=%i, avg=%f, std-dev=%f" % (self.min, self.max,
                                                       self.average(),
                                                       self.std_deviation())

    def print_distribution(self):
        keys = list(self.distribution.keys())
        keys.sort()
        for order in keys:
            row = self.distribution[order]
            # order=0, index=0 is special case as it is < 1.0, for all orders >
            # 0, index 0 is ignored since everthing < 10^order is accounted for
            # in index 9 of the (order - 1) row
            index = 0 if order == 0 else 1
            while index < len(row):
                print("[%d..<%d):  %d" %
                      ((10 ** int(order)) * index,
                       (10 ** int(order)) * (index + 1),
                       row[index]))
                index += 1

class NullOutputter(object):
    """ Output handler used if no output is desired
    """

    def write(self, msg):
        pass

class FileOutputter(object):
    """Output handler used for sending output to a file
    """

    def __init__(self, filepath):
        self._fobj = open(filepath, 'w', -1)

    def write(self, msg):
        self._fobj.write(msg)

class TestResults(object):
    """Client results of a test run.
    """

    def __init__(self, start_time=None, stop_time=None, latency=None,
                 msgs_ok=0, msgs_fail=0, errors=None):
        super(TestResults, self).__init__()
        self.start_time = start_time
        self.stop_time = stop_time
        self.latency = latency or Stats()
        self.msgs_ok = msgs_ok  # count of successful msg transfers
        self.msgs_fail = msgs_fail  # count of failed msg transfers
        self.errors = errors or dict()  # error msgs and counts

    @classmethod
    def from_dict(cls, values):
        if 'latency' in values:
            values['latency'] = Stats.from_dict(values['latency'])
        if 'errors' in values:
            values['errors'] = values['errors'].copy()
        return TestResults(**values)

    def to_dict(self):
        new_dict = dict()
        for a in ['start_time', 'stop_time', 'msgs_ok', 'msgs_fail']:
            new_dict[a] = getattr(self, a)
        new_dict['latency'] = self.latency.to_dict()
        new_dict['errors'] = self.errors.copy()
        return new_dict

    def error(self, reason):
        key = str(reason)
        self.errors[key] = self.errors.get(key, 0) + 1

    def reset(self):
        self.__init__()

    def merge(self, results):
        self.start_time = (min(self.start_time, results.start_time)
                           if self.start_time and results.start_time
                           else (self.start_time or results.start_time))
        self.stop_time = (max(self.stop_time, results.stop_time)
                          if self.stop_time and results.stop_time
                          else (self.stop_time or results.stop_time))
        self.msgs_ok += results.msgs_ok
        self.msgs_fail += results.msgs_fail
        self.latency.merge(results.latency)
        for err in results.errors:
            self.errors[err] = self.errors.get(err, 0) + results.errors[err]

    def print_results(self):
        if self.msgs_fail:
            print("Error: %d message transfers failed"
                  % self.msgs_fail)
        if self.errors:
            print("Error: errors detected:")
            for err in self.errors:
                print("  '%s' (occurred %d times)" % (err, self.errors[err]))

        total = self.msgs_ok + self.msgs_fail
        print("Total Messages: %d" % total)

        delta_time = self.stop_time - self.start_time
        print("Test Interval: %f - %f (%f secs)" % (self.start_time,
                                                    self.stop_time,
                                                    delta_time))

        if delta_time > 0.0:
            print("Aggregate throughput: %f msgs/sec" %
                  (float(total) / delta_time))

        latency = self.latency
        if latency.count:
            print("Latency %d samples (msecs): Average %f StdDev %f"
                  " Min %f Max %f"
                  % (latency.count,
                     latency.average(), latency.std_deviation(),
                     latency.min, latency.max))
            print("Latency Distribution: ")
            latency.print_distribution()

class _Base(object):
    """Common base for all ombt2 processes.  Establishes a connection to the
    control message bus and a subscription for control messages
    """

    def __init__(self, cfg, ctl_url, topic, output, name, unique=False,
                 kind=None, timeout=None):
        super(_Base, self).__init__()
        self._finished = threading.Event()

        self._timeout = timeout
        if kind is None:
            ctl_topic = CONTROLLER_TOPIC % (topic
                                            if not unique else 'singleton')
            self.kind = "Controller"
        else:
            ctl_topic = CLIENT_TOPIC % ((kind, topic)
                                        if not unique else (kind, 'singleton'))
            self.kind = kind

        self.name = name or 'ombt-%s-%s-%s-%s-%s' % (topic,
                                                     kind,
                                                     socket.gethostname(),
                                                     os.getpid(),
                                                     uuid.uuid4().hex)
        self.ctl_url = ctl_url
        self.ctl_tport = om.get_rpc_transport(cfg.CONF,
                                              url=ctl_url)
        # My address and subscription for receiving control commands/responses
        self.ctl_target = om.Target(exchange=CONTROL_EXCHANGE,
                                    topic=ctl_topic,
                                    server=self.name)
        self._ctl_server = om.get_rpc_server(self.ctl_tport,
                                             target=self.ctl_target,
                                             endpoints=[self],
                                             executor="threading")
        self._ctl_server.start()

        if output is not None:
            try:
                self._output = FileOutputter(output)
            except Exception as exc:
                logging.error("Cannot open output file %s: %s!",
                              output, str(exc))
                self._output = NullOutputter()
        else:
            self._output = NullOutputter()

    def start(self):
        # blocks until connection to the control bus is active
        ready = False
        attempts = 0
        logging.debug("%s connecting to the control message bus...", self.name)
        # call my "self_ready" method until it returns successfully.
        # this indicates the connection to the control bus is active.
        client = om.RPCClient(self.ctl_tport,
                              target=self.ctl_target,
                              timeout=2)
        while not ready and attempts < 25:
            try:
                ready = client.call({}, 'self_ready')
            except om.MessagingTimeout:
                attempts += 1
        if not ready:
            raise Exception("Unable to contact message bus")
        logging.debug("%s is listening", self.name)

    def wait(self, timeout=None):
        # blocks until client completes shutdown
        return self._finished.wait(timeout)

    def _do_shutdown(self):
        self._ctl_server.stop()
        self._ctl_server.wait()
        self._finished.set()
        logging.debug("%s has shut down", self.name)

    #
    # RPC calls:
    #

    def shutdown(self, ctxt):
        # cannot synchronously shutdown server since this call is dispatched by
        # the server...
        threading.Thread(target=self._do_shutdown).start()

    def self_ready(self, ctxt):
        # simple ping to determine when message bus is connected
        return True

class _Client(_Base):
    """Common base for non-controller clients.  Defines RPC calls that are
    invoked by the Controller to control the tests.
    """
    def __init__(self, cfg, ctl_url, topic, kind, timeout, name,
                 unique=False, output=None):
        # listen on 'client-$topic' for controller commands:
        super(_Client, self).__init__(cfg, ctl_url, topic, output, name,
                                      unique, kind, timeout)
        self.topic = CLIENT_TOPIC % ((kind, topic)
                                     if not unique else (kind, 'singleton'))
        self.results = TestResults()
        self._results_lock = threading.Lock()
        self._output.write('{"client-name": "%(client)s",'
                           ' "kind": "%(kind)s"}\n'
                           % {'client': self.name,
                              'kind': kind})

    #
    # RPC Calls
    #

    def client_ping(self, ctxt, reply_addr):
        # invoked by controller via rpc-cast to roll-call available clients
        logging.debug("Client ping received (%s)", self.name)
        target = om.Target(**reply_addr)
        ctrl = om.RPCClient(self.ctl_tport, target=target,
                            timeout=self._timeout)
        try:
            ctrl.call({}, "client_pong", kind=self.kind, name=self.name)
        except Exception as exc:
            err = str(exc)
            logging.error("client pong call failed: %s", err)
            self.error(err)
        else:
            logging.debug("Client pong sent (%s) (%s)", self.name, target)

class _TestClient(_Client):
    """Base class for Notifier and RPC clients
    """
    def __init__(self, cfg, ctl_url, topic, kind, name, timeout, unique=False,
                 output=None):
        super(_TestClient, self).__init__(cfg, ctl_url, topic, kind, timeout,
                                          name, unique, output)

    # helper to execute func(timestamp) count times, pausing pause seconds
    # between invocation.  Provides extra logging if verbose
    def _execute(self, func, count=0, pause=0, verbose=False):
        stop = False
        msgid = uuid.uuid4().hex
        seq = 0
        self.results.start_time = now()
        while not stop:
            err = None
            ts = now()
            try:
                func(ts, "%s:%d" % (msgid, seq))
            except Exception as exc:
                self.results.msgs_fail += 1
                err = str(exc)
                self.results.error(err)
                logging.error("Test client failed to send message: %s", err)
            else:
                self.results.msgs_ok += 1
            done = now()
            self.results.latency.update((done - ts) * 1000)
            self._output.write('{"id": "%(msgid)s", "start": %(start)f,'
                               ' "stop": %(stop)f%(error)s}\n'
                               % {'msgid': "%s:%d" % (msgid, seq),
                                  'start': ts,
                                  'stop': done,
                                  'error':
                                  (', "error": "%s"' % err) if err else ""
                                  }
                               )
            seq += 1
            if pause:
                time.sleep(pause)
            if count and self.results.latency.count >= count:
                stop = True
        self.results.stop_time = now()

    #
    # RPC Calls
    #

    @abc.abstractmethod
    def run_test(self, ctxt, test, kwargs, reply_addr):
        """Called by the controller to have the client run test 'test' with
        arguments kwargs. When the test completes the client sends the results
        to the controller at 'reply_addr' by calling its 'client_result'
        method.  Note: this is an RPC method that is invoked by the test
        controller via a fanout 'cast' - not 'call' (the controller does not
        block for results)
        """

class _TestServer(_Client):
    """Base class for Listener and RPC servers
    """
    def __init__(self, cfg, ctl_url, topic, kind, name, timeout, unique=False,
                 output=None):
        super(_TestServer, self).__init__(cfg, ctl_url, topic, kind, timeout,
                                          name, unique, output)

    #
    # Controller RPC Calls
    #
    def get_server_results(self, ctxt, reply_addr):
        """Called by the controller to gather server side test data.  May be
        called repeatedly until the test completes.  Note this is invoked by
        the controller via a fanout 'cast' - not a 'call' (the controller does
        not block for results)
        """
        with self._results_lock:
            results = self.results.to_dict()
            self.results.reset()

        controller = om.RPCClient(self.ctl_tport,
                                  om.Target(**reply_addr),
                                  timeout=self._timeout)
        try:
            controller.call({}, 'client_result', name=self.name,
                            kind=self.kind, results=results)
        except Exception as exc:
            # I don't think recovery is possible as the call may be in-doubt.
            # For now simply let folks know the results may be invalid
            err = str(exc)
            logging.error("%s failed to report results!"
                          " Test results may be invalid!"
                          " Error: %s", err)
        else:
            logging.debug("Server %s test results sent", self.name)

class RPCTestClient(_TestClient):
    """Runs the RPC tests against the RPCTestServer
    """
    def __init__(self, cfg, ctl_url, test_url, topic, name, timeout,
                 unique=False, output=None):
        super(RPCTestClient, self).__init__(cfg, ctl_url, topic, RPC_CLIENT,
                                            name, timeout, unique, output)
        # for calling the test RPC server(s):
        target = om.Target(exchange=RPC_EXCHANGE,
                           topic=RPC_TOPIC % topic)
        fanout_target = om.Target(exchange=RPC_EXCHANGE,
                                  topic=RPC_TOPIC % topic,
                                  fanout=True)
        tport = (self.ctl_tport
                 if test_url == self.ctl_url
                 else om.get_rpc_transport(cfg.CONF, url=test_url))
        self._rpc_client = om.RPCClient(tport,
                                        target=target,
                                        timeout=timeout)
        self._fanout_client = om.RPCClient(tport,
                                           target=fanout_target,
                                           timeout=timeout)
    #
    # RPC Calls:
    #

    def run_test(self, ctxt, test, kwargs, reply_addr):
        func = None
        verbose = kwargs.get("verbose", False)
        pause = kwargs.get("pause", 0)
        data = kwargs.get("data", "")
        count = kwargs.get("count", 0)

        if test == "test_call":
            func = lambda ts, msgid: self._rpc_client.call({}, 'echo',
                                                           data=data,
                                                           timestamp=ts,
                                                           msgid=msgid)
        elif test == "test_cast":
            func = lambda ts, msgid: self._rpc_client.cast({}, 'noop',
                                                           data=data,
                                                           timestamp=ts,
                                                           msgid=msgid)
        elif test == "test_fanout":
            func = lambda ts, msgid: self._fanout_client.cast({}, 'noop',
                                                              data=data,
                                                              timestamp=ts,
                                                              msgid=msgid)
        else:
            logging.error("Client %s ignoring unknown test %s",
                          self.name, test)
            return

        self._output.write('{"test-name": "%(name)s",'
                           ' "test-start": %(start)f}\n'
                           % {'name': test, 'start': now()})

        controller = om.RPCClient(self.ctl_tport,
                                  om.Target(**reply_addr),
                                  timeout=self._timeout)
        logging.debug("Client %s starting test %s ...", self.name, test)

        # Before running the test, try to ping the server.  This will force a
        # link setup so the first latency-timed message will not be blocked
        # waiting for the setup to complete.
        try:
            self._rpc_client.call({}, "self_ready")
        except Exception as exc:
            logging.warning("Client %s is unable to reach RPC server: %s",
                            self.name, str(exc))
            self.results.error(str(exc))
            # keep going, perhaps the test will not fail...

        self._execute(func, count, pause, verbose)

        self._output.write('{"test-end": %f}\n' % now())

        logging.debug("Client %s test %s finished, sending results...",
                      self.name, test)
        try:
            controller.call({}, 'client_result', name=self.name,
                            kind=self.kind, results=self.results.to_dict())
        except Exception as exc:
            # I don't think recovery is possible as the call may be in-doubt.
            # For now simply let folks know the results may be invalid
            logging.error("%s failed to report results!"
                          " Test results may be invalid!"
                          " Error: %s", RPC_CLIENT, str(exc))
        else:
            logging.debug("Client %s test %s results sent", self.name, test)
        self.results.reset()

class RPCTestServer(_TestServer):
    """Response to RPC requests from RPCTestClient
    """
    def __init__(self, cfg, ctl_url, test_url, topic, executor, name, timeout,
                 unique=False, output=None):
        super(RPCTestServer, self).__init__(cfg, ctl_url, topic, RPC_SERVER,
                                            name, timeout, unique, output)
        target = om.Target(exchange=RPC_EXCHANGE,
                           topic=RPC_TOPIC % topic,
                           server=self.name)
        tport = (self.ctl_tport
                 if test_url == self.ctl_url
                 else om.get_rpc_transport(cfg.CONF, url=test_url))
        self._rpc_server = om.get_rpc_server(tport,
                                             target,
                                             [self],
                                             executor=executor)
        self._rpc_server.start()

    def _update_stats(self, timestamp, msgid):
        # given timestamp from arriving message
        ts = now()
        self._output.write('{"id": "%s", "start": %f, "recv": %f'
                           % (msgid, timestamp, ts))

        if timestamp > ts:
            logging.error("Clock error detected:"
                          " send time (%f) after arrival time (%f)"
                          " test results will be invalid!",
                          timestamp, ts)
            with self._results_lock:
                self.results.error("Clocks not synchronized")
                self.results.msgs_fail += 1
            self._output.write(', "error": "unsynchronized clocks"\n')
        else:
            with self._results_lock:
                self.results.start_time = (min(self.results.start_time, ts)
                                           if self.results.start_time else ts)
                self.results.stop_time = (max(self.results.stop_time, ts)
                                          if self.results.stop_time else ts)
                self.results.msgs_ok += 1
                self.results.latency.update((ts - timestamp) * 1000)
        self._output.write('}\n')

    #
    # Controller RPC Calls:
    #

    def shutdown(self, ctxt):
        self._rpc_server.stop()
        self._rpc_server.wait()
        super(RPCTestServer, self).shutdown(ctxt)

    #
    # Test RPC Calls:
    #

    def noop(self, ctxt, data, timestamp, msgid):
        # for cast testing - called by RPCTestClient, no return value
        self._update_stats(timestamp, msgid)
        logging.debug("RPCServer.noop(timestamp=%s)", timestamp)

    def echo(self, ctxt, data, timestamp, msgid):
        # for call testing - called by RPCTestClient
        self._update_stats(timestamp, msgid)
        logging.debug("RPCServer.echo(timestamp=%s)", timestamp)
        return data

class TestNotifier(_TestClient):
    """Client for issuing Notification calls to the TestListener
    """
    def __init__(self, cfg, ctl_url, test_url, topic, name, timeout,
                 output=None):
        super(TestNotifier, self).__init__(cfg,
                                           ctl_url,
                                           topic,
                                           NOTIFIER,
                                           name,
                                           timeout,
                                           output)
        # for notifying the test listener:
        om.set_transport_defaults(control_exchange=NOTIFY_EXCHANGE)
        tport = om.get_notification_transport(cfg.CONF, url=test_url)
        topic = NOTIFY_TOPIC % topic
        self._notifier = om.notify.notifier.Notifier(tport,
                                                     self.name,
                                                     driver='messaging',
                                                     topics=[topic])
    #
    # RPC Calls:
    #

    def run_test(self, ctxt, test, kwargs, reply_addr):
        if test != 'test_notify':
            # ignore other tests, like rpc-call, etc
            return
        verbose = kwargs.get("verbose", False)
        pause = kwargs.get("pause", 0)
        data = kwargs.get("data", "")
        count = kwargs.get("count", 0)
        severity = kwargs.get("severity", "debug")

        controller = om.RPCClient(self.ctl_tport,
                                  om.Target(**reply_addr),
                                  timeout=self._timeout)
        logging.debug("Client %s starting test %s ...", self.name, test)

        func = getattr(self._notifier, severity)
        payload = {'payload': data}

        def test_func(timestamp, msgid):
            payload['timestamp'] = timestamp
            payload['msgid'] = msgid
            func({}, "notification-test", payload)

        self._output.write('{"test-name": "test_notify",'
                           ' "test-start": %(start)f}\n'
                           % {'start': now()})

        self._execute(test_func, count, pause, verbose)

        self._output.write('{"test-end": %f}\n' % now())

        logging.debug("Client %s test %s finished, sending results...",
                      self.name, test)

        with self._results_lock:
            results = self.results.to_dict()
            self.results.reset()

        try:
            controller.call({}, 'client_result', name=self.name,
                            kind=self.kind, results=results)
        except Exception as exc:
            # I don't think recovery is possible as the call may be in-doubt.
            # For now simply let folks know the results may be invalid
            logging.error("%s failed to report results!"
                          " Test results may be invalid!"
                          " Error: %s", str(exc))
        else:
            logging.debug("Client %s test %s results sent", self.name, test)

class TestListener(_TestServer):
    def __init__(self, cfg, ctl_url, test_url, topic, executor, name, timeout,
                 pool=None, output=None):
        super(TestListener, self).__init__(cfg,
                                           ctl_url,
                                           topic,
                                           LISTENER,
                                           name,
                                           timeout, output)
        target = om.Target(exchange=NOTIFY_EXCHANGE,
                           topic=NOTIFY_TOPIC % topic,
                           server=self.name)
        om.set_transport_defaults(control_exchange=NOTIFY_EXCHANGE)
        tport = om.get_notification_transport(cfg.CONF, url=test_url)
        self._listener = om.get_notification_listener(tport,
                                                      [target],
                                                      [self],
                                                      executor=executor,
                                                      pool=pool)
        self._listener.start()

    #
    # Controller RPC Calls:
    #

    def shutdown(self, ctxt):
        self._listener.stop()
        self._listener.wait()
        super(TestListener, self).shutdown(ctxt)

    #
    # Notifications:
    #

    def _report(self, severity, ctx, publisher, event_type, payload, metadata):
        ts = now()
        logging.debug("%s Notification %s:%s:%s:%s:%s", self.name, severity,
                      publisher, event_type, payload, metadata)

        timestamp = payload['timestamp']
        msgid = payload['msgid']

        self._output.write('{"id": "%(msgid)s", "start": %(start)f,'
                           ' "recv": %(recv)f'
                           % {'msgid': msgid, 'start': timestamp, 'recv': ts})

        if timestamp > ts:
            logging.error("Clock error detected:"
                          " send time (%f) after arrival time (%f)"
                          " test results will be invalid!",
                          timestamp, ts)
            with self._results_lock:
                self.results.error("Clocks not synchronized")
                self.results.msgs_fail += 1
            self._output.write(', "error": "unsynchronized clocks"\n')
        else:
            with self._results_lock:
                self.results.start_time = (min(self.results.start_time, ts)
                                           if self.results.start_time else ts)
                self.results.stop_time = (max(self.results.stop_time, ts)
                                          if self.results.stop_time else ts)
                self.results.latency.update((ts - timestamp) * 1000)
                self.results.msgs_ok += 1
        self._output.write('}\n')

    def debug(self, ctx, publisher, event_type, payload, metadata):
        self._report("debug", ctx, publisher, event_type, payload, metadata)

    def audit(self, ctx, publisher, event_type, payload, metadata):
        self._report("audit", ctx, publisher, event_type, payload, metadata)

    def critical(self, ctx, publisher, event_type, payload, metadata):
        self._report("critical", ctx, publisher, event_type, payload, metadata)

    def error(self, ctx, publisher, event_type, payload, metadata):
        self._report("error", ctx, publisher, event_type, payload, metadata)

    def info(self, ctx, publisher, event_type, payload, metadata):
        self._report("info", ctx, publisher, event_type, payload, metadata)

    def warn(self, ctx, publisher, event_type, payload, metadata):
        self._report("warn", ctx, publisher, event_type, payload, metadata)

class Controller(_Base):
    """The test controller
    """
    def __init__(self, cfg, ctl_url, topic, timeout, unique=False, idle=2,
                 output=None):
        # each controller has a unique topic not to be confused
        # with future or past controller instances
        self.topic = topic
        self._idle = idle
        self.unique = unique
        super(Controller, self).__init__(cfg, ctl_url, topic, output,
                                         unique=False,
                                         name=None,
                                         kind=None,
                                         timeout=timeout)
        self._total_minions = 0
        self._queue = queue.Queue()

        # count of clients per type
        self._minions = dict([(k, 0) for k in MESSAGING_CLIENT_TYPES])
        # aggregated client results per type
        self._results = dict([(k, TestResults())
                              for k in MESSAGING_CLIENT_TYPES])
        # control rpc client for each type:
        self._clients = dict()

    def start(self):
        super(Controller, self).start()
        logging.debug("Polling for clients...")
        reply = {'exchange': self.ctl_target.exchange,
                 'topic': self.ctl_target.topic,
                 'server': self.ctl_target.server}
        for kind in MESSAGING_CLIENT_TYPES:
            target = om.Target(exchange=CONTROL_EXCHANGE,
                               topic=CLIENT_TOPIC %
                               ((kind, self.topic)
                                if not self.unique else (kind, 'singleton')),
                               fanout=True)
            self._clients[kind] = om.RPCClient(self.ctl_tport, target=target)
            self._clients[kind].cast({}, 'client_ping', reply_addr=reply)

        # wait until no more clients reply to the ping
        # (things are idle)
        _wait_stabilize(self._idle, lambda: self._total_minions)

    def shutdown(self):
        """Shutdown this Controller
        """
        super(Controller, self).shutdown({})
        self.wait()

    def shutdown_clients(self):
        """Shutdown all clients listening to $topic
        """
        for kind in MESSAGING_CLIENT_TYPES:
            self._clients[kind].cast({}, 'shutdown')
        time.sleep(1.0)

    def run_call_test(self, count, data, verbose, pause):
        clients = self._minions[RPC_CLIENT]
        servers = self._minions[RPC_SERVER]
        kwargs = {'verbose': verbose,
                  'pause': pause,
                  'data': data,
                  'count': count}
        self._run_test(RPC_CLIENT, 'test_call', kwargs)
        # note: set the poll time to 2x the client's pause between calls,
        # otherwise we're polling too frequently
        self._query_servers(RPC_SERVER, pause * 2, count * clients)

        print("RPC call test results")
        print("%d RPC clients, %d RPC Servers (%d total)"
              % (clients, servers, clients + servers))

        print("\n")
        print("Aggregated RPC Client results:")
        print("------------------------------")
        self._results[RPC_CLIENT].print_results()
        print("\n")
        print("Aggregated RPC Server results:")
        print("------------------------------")
        self._results[RPC_SERVER].print_results()

    def run_cast_test(self, count, data, verbose, pause, delay):
        clients = self._minions[RPC_CLIENT]
        servers = self._minions[RPC_SERVER]
        kwargs = {'verbose': verbose,
                  'pause': pause,
                  'data': data,
                  'count': count}
        self._run_test(RPC_CLIENT, 'test_cast', kwargs)
        # cast are async, wait a bit for msgs to propagate
        time.sleep(delay)
        # note: set the poll time to 2x the client's pause between calls,
        # otherwise we're polling too frequently
        self._query_servers(RPC_SERVER, pause * 2, count * clients)

        print("RPC cast test results")
        print("%d RPC clients, %d RPC Servers (%d total)"
              % (clients, servers, clients + servers))

        print("\n")
        print("Aggregated RPC Client results:")
        print("------------------------------")
        self._results[RPC_CLIENT].print_results()
        print("\n")
        print("Aggregated RPC Server results:")
        print("------------------------------")
        self._results[RPC_SERVER].print_results()

    def run_fanout_test(self, count, data, verbose, pause,
                        delay):
        clients = self._minions[RPC_CLIENT]
        servers = self._minions[RPC_SERVER]
        kwargs = {'verbose': verbose,
                  'pause': pause,
                  'data': data,
                  'count': count}
        self._run_test(RPC_CLIENT, 'test_fanout', kwargs)
        # fanouts are async, wait a bit for msgs to propagate
        time.sleep(delay)
        # note: set the poll time to 2x the client's pause between calls,
        # otherwise we're polling too frequently
        self._query_servers(RPC_SERVER, pause * 2,
                            count * clients * servers)

        print("RPC fanout test results")
        print("%d RPC clients, %d RPC Servers (%d total)"
              % (clients, servers, clients + servers))

        print("\n")
        print("Aggregated RPC Client results:")
        print("------------------------------")
        self._results[RPC_CLIENT].print_results()
        print("\n")
        print("Aggregated RPC Server results:")
        print("------------------------------")
        self._results[RPC_SERVER].print_results()

        start = self._results[RPC_CLIENT].start_time
        stop = self._results[RPC_SERVER].stop_time
        print("\n")
        print("Fanout propagation delay:")
        print("-------------------------")
        print("  First client transmit time: %f" % start)
        print("  Last server receive time: %f" % stop)
        print("  Duration (secs): %f" % (stop - start))

    def run_notification_test(self, count, data, severity, verbose, pause,
                              delay):
        clients = self._minions[NOTIFIER]
        servers = self._minions[LISTENER]
        kwargs = {'verbose': verbose,
                  'pause': pause,
                  'data': data,
                  'count': count,
                  'severity': severity}
        self._run_test(NOTIFIER, 'test_notify', kwargs)
        # notifications are async, wait a bit for msgs to propagate
        time.sleep(delay)
        # note: set the poll time to 2x the client's pause between calls,
        # otherwise we're polling too frequently
        self._query_servers(LISTENER, pause * 2, count * clients)

        print("Notification test results")
        print("%d Notifiers, %d Listeners (%d total)"
              % (clients, servers, clients + servers))

        print("\n")
        print("Aggregated Notifier (Client) results:")
        print("------------------------------------")
        self._results[NOTIFIER].print_results()
        print("\n")
        print("Aggregated Listener (Server) results:")
        print("-------------------------------------")
        self._results[LISTENER].print_results()

    def _run_test(self, kind, test, kwargs):
        """Tell the messaging clients to run a test.  When the client completes
        it will call the 'client_result' method below.
        """
        count = self._minions[kind]
        if count == 0:
            raise Exception("No %s clients visible" % kind)

        reply = {'exchange': self.ctl_target.exchange,
                 'topic': self.ctl_target.topic,
                 'server': self.ctl_target.server}

        # tell 'kind' clients to run the test
        self._clients[kind].cast({}, 'run_test',
                                 test=test,
                                 kwargs=kwargs,
                                 reply_addr=reply)

        results_per_client = dict()
        # wait for the clients to send results
        while count:
            try:
                name, ckind, results = self._queue.get(timeout=self._timeout)
            except queue.Empty:
                raise Exception("%s test timed out: no response from clients!"
                                % test)
            results_per_client[name] = results.to_dict()
            self._results[ckind].merge(results)
            if ckind == kind:
                count -= 1
            else:
                # TODO(kgiusti) uh, is this a problem?
                logging.warning("Huh? results from %s while expecting a %s",
                                ckind, kind)
        self._output.write(json.dumps(results_per_client) + '\n')

    def _query_servers(self, kind, pause, total):
        """Ask the servers for any data gathered during the test. The servers
        will respond by calling the 'client_result' method below.  Once the
        servers stop reporting new statistics the query is done.

        :param kind: the type of server to query - RPC or LISTENER
        :type kind: str
        :param pause: time in seconds to wait between each server poll.  Should
                      be at least twice the client's inter-message pause time.
        :type pause: float
        :param total: total number of messages expected to be received by all
                      servers
        """
        if self._minions[kind] == 0:
            raise Exception("No %s servers visible" % kind)

        # avoid hammering the servers if no pause given
        pause = max(pause, 0.250) if pause else 0.250

        server_results = self._results[kind]
        reply = {'exchange': self.ctl_target.exchange,
                 'topic': self.ctl_target.topic,
                 'server': self.ctl_target.server}

        logging.debug("Querying servers...")

        results_per_server = dict()
        done = False
        start = now()
        while not done and abs(now() - start) < self._timeout:

            # tell 'kind' servers to return results
            self._clients[kind].cast({}, 'get_server_results',
                                     reply_addr=reply)
            # wait for the servers to send results
            count = self._minions[kind]
            seen = 0
            while count:
                try:
                    _ = self._queue.get(timeout=self._timeout)
                    name, ckind, results = _
                except queue.Empty:
                    raise Exception("%s test timed out: no response from"
                                    " servers!" % kind)

                if ckind != kind:
                    # TODO(kgiusti): uh, is this a problem?
                    logging.warning("Huh? results from %s while expecting %s",
                                    ckind, kind)
                    continue
                if name not in results_per_server:
                    results_per_server[name] = results
                else:
                    results_per_server[name].merge(results)

                server_results.merge(results)
                seen += results.msgs_ok + results.msgs_fail
                count -= 1

            # exit loop once the expected number of messages have been received
            # by the servers, or the test times out
            done = server_results.msgs_ok + server_results.msgs_fail >= total
            if not done:
                time.sleep(pause)
                if seen == 0:
                    # no replies: try pausing longer next time
                    pause = min(pause * 2.0, self._timeout)

        if not done:
            logging.error("Test timed out - not all messages accounted for")
        results_per_server = dict([[k, v.to_dict()]
                                   for k, v in results_per_server.items()])
        self._output.write(json.dumps(results_per_server) + '\n')

        logging.debug("... servers queried")

    #
    # RPC calls:
    #
    def client_pong(self, ctxt, kind, name):
        # A client 'name' is checking in
        if kind not in self._minions:
            self._minions[kind] = 0
        self._minions[kind] += 1
        self._total_minions += 1
        logging.debug("New %s detected (%s) - %d total clients found",
                      kind, name, self._total_minions)
        return True

    def client_result(self, ctxt, name, kind, results):
        # A test client is reporting a test result in response to the above
        # _run_test method.
        logging.debug("%s results received from %s", (kind, name))
        try:
            self._queue.put((name, kind, TestResults.from_dict(results)))
        except Exception as exc:
            logging.error("Invalid TestResult from %s:%s (%s)",
                          kind, str(exc), str(results))


from django.db import models
import datetime
from django.utils.timezone import now

class Chat(models.Model):
	title = models.CharField('заголовок', max_length=255, default='')
	is_group_chat = models.BooleanField('групповой чат', default=False)
	topic = models.CharField('топик', max_length=255, default='')
	avatar = models.ImageField('аватар', upload_to='images/', null=True)
	last_message_text = models.CharField('текст последнего сообщения', max_length=255, default='')
	last_message_date = models.DateTimeField('дата создания', default=now)

	def __str__(self):
		return self.title

	class Meta:
		verbose_name = "Чат"
		verbose_name_plural = "Чаты"
		ordering = ["-last_message_date"]

class Message(models.Model):
	content = models.TextField('контент', default='')
	date = models.DateTimeField('дата создания', default=now)
	chat = models.ForeignKey(Chat, on_delete=models.SET_NULL, null=True, related_name='messages', verbose_name="чат")
	user = models.ForeignKey('user_profile.User', on_delete=models.SET_NULL, null=True, related_name='messages', verbose_name="пользователь")

	def __str__(self):
		return self.content

	class Meta:
		verbose_name = "Сообщение"
		verbose_name_plural = "Сообщения"
		ordering = ["date", "content"]

class Attachment(models.Model):
	chat = models.ForeignKey(Chat, on_delete=models.SET_NULL, null=True, related_name='attachments', verbose_name="чат")
	user = models.ForeignKey('user_profile.User', on_delete=models.SET_NULL, null=True, related_name='attachments', verbose_name="пользователь")
	content_type = models.CharField('MIME тип', max_length=255, default='image/png')
	url = models.ImageField('адрес', upload_to='uploads/', null=True)
	message = models.OneToOneField(Message, on_delete=models.SET_NULL, null=True, related_name='attachment', unique=True, verbose_name="сообщение")

	class Meta:
		verbose_name = "Прикрепление"
		verbose_name_plural = "Прикрепления"
		ordering = ["content_type"]


# -*- coding:utf-8 -*-
from mako import runtime, filters, cache
UNDEFINED = runtime.UNDEFINED
STOP_RENDERING = runtime.STOP_RENDERING
__M_dict_builtin = dict
__M_locals_builtin = locals
_magic_number = 10
_modified_time = 1463637607.218917
_enable_loop = True
_template_filename = 'G:/public_html/iutvalence-python-mangacollection/View/template/dessinateur_new.html'
_template_uri = 'dessinateur_new.html'
_source_encoding = 'utf-8'
_exports = ['container']

def _mako_get_namespace(context, name):
    try:
        return context.namespaces[(__name__, name)]
    except KeyError:
        _mako_generate_namespaces(context)
        return context.namespaces[(__name__, name)]
def _mako_generate_namespaces(context):
    pass
def _mako_inherit(template, context):
    _mako_generate_namespaces(context)
    return runtime._inherit_from(context, 'base.html', _template_uri)
def render_body(context,**pageargs):
    __M_caller = context.caller_stack._push_frame()
    try:
        __M_locals = __M_dict_builtin(pageargs=pageargs)
        def container():
            return render_container(context._locals(__M_locals))
        __M_writer = context.writer()
        __M_writer('\r\n')
        if 'parent' not in context._data or not hasattr(context._data['parent'], 'container'):
            context['self'].container(**pageargs)

        return ''
    finally:
        context.caller_stack._pop_frame()

def render_container(context,**pageargs):
    __M_caller = context.caller_stack._push_frame()
    try:
        def container():
            return render_container(context)
        __M_writer = context.writer()
        __M_writer('\r\n
\r\n    <form action="/dessinateur/add/" method="post">\r\n
\r\n            Dessinateur :\r\n            <input type="text" class="form-control" id="dessinateur" name="dessinateur" required>\r\n
\r\n        <input type="submit" class="btn btn-success">\r\n    </form>\r\n
\r\n')
        return ''
    finally:
        context.caller_stack._pop_frame()

"""
__M_BEGIN_METADATA
{"filename": "G:/public_html/iutvalence-python-mangacollection/View/template/dessinateur_new.html", "line_map": {"56": 50, "34": 2, "27": 0, "44": 3, "50": 3}, "uri": "dessinateur_new.html", "source_encoding": "utf-8"}
__M_END_METADATA
"""


import numpy as np
from pyquil import get_qc
from pyquil.quil import Program
from pyquil.gates import RX, X
import matplotlib.pyplot as plt
import tqdm

# Get our QuantumComputer instance, with a Quantum Virtual Machine (QVM) backend
qpu_name = '8q-qvm' # 8q-qvm   Aspen-8
asqvm = True
isnoisy = False
QPU = get_qc(qpu_name,as_qvm=asqvm, noisy=isnoisy)

calibration_trials = 2**13
measurement_trials = 2**13

program_initialization = Program('PRAGMA INITIAL_REWIRING "NAIVE"') #changed syntax according to documentation

"""
defining ansatz
"""
def calibration_ansatz(state,prog_in = program_initialization):
    prog_out = prog_in.copy()
    if state == 1:
        prog_out += X(0)
        prog_out += X(1)
    #prog_out.define_noisy_readout(0, p00=0.9, p11=0.8)
    #prog_out.define_noisy_readout(1, p00=0.95, p11=0.85)
    return prog_out

def ansatz(angle_1,angle_2,prog_in = program_initialization):
    prog_out = prog_in.copy()
    prog_out += RX(angle_1, 0)
    prog_out += RX(angle_2, 1)
   # prog_out += CNOT(0,1)
    #prog_out.define_noisy_readout(0, p00=0.9, p11=0.8)
    #prog_out.define_noisy_readout(1, p00=0.95, p11=0.85)
    return prog_out

# Function to replace the run_and_measure function from pyquil which seems to create problems with Aspen-8
def run_and_measure_wrapped(device, prog_in, trials=calibration_trials):
    result=[]
    p=prog_in.copy()
    ro = p.declare('ro', 'BIT', 2)
    p += Program().measure(0, ro[0]) # Measure qubit #0 a number of times
    p += Program().measure(1, ro[1]) # Measure qubit #1 a number of times
    p.wrap_in_numshots_loop(shots=trials)
    p.define_noisy_readout(0, p00=1, p11=0.9)
   # p.define_noisy_readout(1, p00=0.9, p11=0.9)
    # We see probabilistic results of about half 1's and half 0's
    result=QPU.run(QPU.compile(p))
    return result

"""
Function that computes the true, noise-free expectation value of Z\otimes Z given the two angles.
"""
def true_expectation(angle_1, angle_2):

    return np.cos(angle_1)*np.cos(angle_2)

test_angles=[0, np.pi/2, np.pi]

test_angles_2=np.arange(0, 2*np.pi, 0.2)

#define random angles for rotations on qubits 1 and 2
"""rand_angle_1 = 2*np.pi*np.random.random()
rand_angle_2 = 2*np.pi*np.random.random()"""

for rand_angle_1 in tqdm.tqdm(test_angles):

    list_of_errors=[]

    for rand_angle_2 in test_angles_2:

        """
        outfile = open("Z_"+qpu_name+"_asqvm_"+str(asqvm)+"_"+str(rand_angle_1)+"_"+str(rand_angle_2)+".txt","w")
        outfile.write("True value: "+str(true)+"\r\n")
        outfile.close()
        """

        """
        The following is based on eq. (40) in the paper.
        """

        # calibration for 0 state
        cal0 = run_and_measure_wrapped(device=QPU, prog_in=calibration_ansatz(0), trials=calibration_trials).T
        # cal0 is dictionary of qubit measurements
        # cal0[q] is list of outputs of qubit q
        # number of ones in cal0[q] is sum(cal0[q])
        # number of zeros is cal0[q] is len(cal0[q]) - sum(cal0[q])
        # pq0 is number ones / len(cal0[q])
        p00 = float(sum(cal0[0]))/len(cal0[0])
        p10 = float(sum(cal0[1]))/len(cal0[1])

        # calibration for 1 state
        cal1 = run_and_measure_wrapped(device=QPU, prog_in=calibration_ansatz(1), trials=calibration_trials).T
        # number zeros is len(cal1[q]) - sum(cal1[q])
        p01 = float(len(cal1[0]) - sum(cal1[0]))/len(cal1[0])
        p11 = float(len(cal1[1]) - sum(cal1[1]))/len(cal1[1])

        # compute the gammas according to the paper.
        gamma_Z1=1-p00-p01
        gamma_Z2=1-p10-p11
        gamma_I1=p01-p00
        gamma_I2=p11-p10

        # compute the coefficients based on eq. (40)
        # the indices correspond to the following operators:
        # 0 - Z_1 \otimes Z_2
        # 1 - Z_1 \otimes id_2
        # 2 - id_1 \otimes Z_2
        # 3 - id_1 \otimes id_2
        coeffs=[1/(gamma_Z1*gamma_Z2),
                -gamma_I1/(gamma_Z1*gamma_Z2),
                -gamma_I2/(gamma_Z1*gamma_Z2),
                (gamma_I1*gamma_I2)/(gamma_Z1*gamma_Z2)]

        # compute the sum of all absolute values of the coefficients
        sum_of_abs=np.sum(np.abs(coeffs))

        #create the probability distribution as well as a list of the signs of the coeffients
        Omega=[]
        sigma=[]
        for k in coeffs:
            Omega.append(np.abs(k)/sum_of_abs)

            if k != 0:
                sigma.append(k/np.abs(k))

            else:
                sigma.append(1.0)

        results = run_and_measure_wrapped(device=QPU, prog_in=ansatz(rand_angle_1,rand_angle_2), trials=measurement_trials)
        #combine results of first two qubits for further computation

        estimate=0.
        not_mitigated=0.

        test_angles=[-np.pi, -np.pi/2, -np.pi/4, 0,np.pi/4, np.pi/2, np.pi]

        for n,result in enumerate(results):

            res0,res1=result

            rand_idx = np.random.choice(range(4),p=Omega)

            M=np.array([[1,1],[0,1],[1,0],[0,0]])

            m=M[rand_idx]

            # If the corresponding operator contains a Z on qubit q, we want to add the value (-1)^j (multiplied
            # by the corresponding sign and the overall factor of course),
            # where j is the outcome of the measurement for qubit q. Otherwise, we want to add 1 (eigenvalue of Id)
            # We encode this via a list M with entries of the form [m1,m2], where m1,m2=0,1.
            # The correct factor is obtained by taking (-1)^(j*m), which gives -1 only in the case that the
            # operator is Z AND the outcome is 1.
            estimate += sigma[rand_idx] * (-1)**(res0*m[0]+res1*m[1])

            # compute result without mitigation

        # normalize to number of measurements

        estimate*=sum_of_abs/float(measurement_trials)
        not_mitigated/=float(measurement_trials)

        true=true_expectation(rand_angle_1, rand_angle_2)
        list_of_errors.append(estimate-true)
        #+0.1*np.cos(rand_angle_1)-0.1*np.cos(rand_angle_2)

    plt.plot(test_angles_2, list_of_errors, label="theta_1="+str(np.round(rand_angle_1, decimals=2)))

plt.xlabel('theta_2')
plt.ylabel('error')
#plt.axis([0,6.2,-0.2,0.2])
plt.legend()
plt.savefig("plot_p00=0,p01=0.1.png", dpi=150)
plt.show()


import os
import sys
import numpy as np
import pandas as pd
from ortools.linear_solver import pywraplp

print('prog starts from here!')

def example_ortools(desired, n_people, has_accounting=True):
    def accounting_penalty(day, next_day):
        return (day-125)*(day**(0.5 + abs(day-next_day)/50.0))/400
    print('in example_ortools')
    NUM_THREADS = 4
    NUM_SECONDS = 3600
    FAMILY_COST = np.asarray([0,50,50,100,200,200,300,300,400,500])
    MEMBER_COST = np.asarray([0, 0, 9,  9,  9, 18, 18, 36, 36,235])
    num_days = desired.max()
    num_families = desired.shape[0]
    solver = pywraplp.Solver('Santa2019', pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
#     solver.set_time_limit(NUM_SECONDS*NUM_THREADS*1000)
    solver.SetNumThreads(NUM_THREADS)
    C, B, I = {}, {}, {}
    for fid, choices in enumerate(desired):
        for cid in range(10):
            B[fid, choices[cid]-1] = solver.BoolVar('')
            C[fid, choices[cid]-1] = FAMILY_COST[cid] + n_people[fid] * MEMBER_COST[cid]

    for day in range(num_days):
        I[day] = solver.IntVar(125, 300, f'I{day}')
        solver.Add(solver.Sum(n_people[fid]*B[fid, day] for fid in range(num_families) if (fid,day) in B) == I[day])

    for fid in range(num_families):
        solver.Add(solver.Sum(B[fid, day] for day in range(num_days) if (fid,day) in B) == 1)

    objective = solver.Sum(C[fid, day]*B[fid, day] for fid, day in B)
    if has_accounting:
        Y = {}

        for day in range(num_days):
            next_day = np.clip(day+1, 0, num_days-1)
            gen = [(u,v) for v in range(176) for u in range(176)]
            for u,v in gen:
                Y[day,u,v] = solver.BoolVar('')
            solver.Add(solver.Sum(Y[day,u,v]*u for u,v in gen) == I[day]-125)
            solver.Add(solver.Sum(Y[day,u,v]*v for u,v in gen) == I[next_day]-125)
            solver.Add(solver.Sum(Y[day,u,v]   for u,v in gen) == 1)

        accounting_penalties = solver.Sum(accounting_penalty(u+125,v+125) * Y[day,u,v] for day,u,v in Y)
        objective += accounting_penalties

    solver.Minimize(objective)
    sol = solver.Solve()
    status = ['OPTIMAL', 'FEASIBLE', 'INFEASIBLE', 'UNBOUNDED', 'ABNORMAL', 'MODEL_INVALID', 'NOT_SOLVED']
    if status[sol] == 'OPTIMAL':
        print("Result: ", objective.solution_value())
        assigned_days = np.zeros(num_families, int)
        for fid, day in B:
            if B[fid, day].solution_value() > 0.5:
                assigned_days[fid] = day + 1
        return assigned_days

def example_cplex(desired, n_people, has_accounting=True): # can't run on kaggle notebooks
    def accounting_penalty(day, next_day):
        return (day-125)*(day**(0.5 + abs(day-next_day)/50.0))/400

    from docplex.mp.model import Model
    FAMILY_COST = np.asarray([0,50,50,100,200,200,300,300,400,500])
    MEMBER_COST = np.asarray([0, 0, 9,  9,  9, 18, 18, 36, 36,235])
    num_days = desired.max()
    num_families = desired.shape[0]
    solver = Model(name='Santa2019')
    solver.parameters.mip.tolerances.mipgap = 0.00
    solver.parameters.mip.tolerances.absmipgap = 0.00
    C = {}
    for fid, choices in enumerate(desired):
        for cid in range(10):
            C[fid, choices[cid]-1] = FAMILY_COST[cid] + n_people[fid] * MEMBER_COST[cid]

    B = solver.binary_var_dict(C, name='B')
    I = solver.integer_var_list(num_days, lb=125, ub=300, name='I')

    for day in range(num_days):
        solver.add(solver.sum(n_people[fid]*B[fid, day] for fid in range(num_families) if (fid,day) in B) == I[day])

    for fid in range(num_families):
        solver.add(solver.sum(B[fid, day] for day in range(num_days) if (fid,day) in B) == 1)

    preference_cost = solver.sum(C[fid, day]*B[fid, day] for fid, day in B)
    if has_accounting:
        Y = solver.binary_var_cube(num_days, 176, 176, name='Y')

        for day in range(num_days):
            next_day = np.clip(day+1, 0, num_days-1)
            gen = [(u,v) for v in range(176) for u in range(176)]
            solver.add(solver.sum(Y[day,u,v]*u for u,v in gen) == I[day]-125)
            solver.add(solver.sum(Y[day,u,v]*v for u,v in gen) == I[next_day]-125)
            solver.add(solver.sum(Y[day,u,v]   for u,v in gen) == 1)

        gen = [(day,u,v) for day in range(num_days) for v in range(176) for u in range(176)]
        accounting_penalties = solver.sum(accounting_penalty(u+125,v+125) * Y[day,u,v] for day,u,v in gen)
        solver.minimize(accounting_penalties+preference_cost)
    else:
        solver.minimize(preference_cost)

    solver.print_information()
    sol = solver.solve(log_output=True)
    if sol:
        print(sol.objective_value)
        assigned_days = np.zeros(num_families, int)
        for fid, day in C:
            if sol[B[fid, day]] > 0:
                assigned_days[fid] = day + 1
        return assigned_days

print('prog ends here!')


from openpyxl import load_workbook
from config.varCondig import *
class ParseExcel(object):
    '''
    解析excel文件的封装
    '''
    def __init__(self):
        # 加载excel文件到内存
        self.wb = load_workbook(testExcelValuePath)

    def getRowValue(self, sheetName, rawNo):
        '''
        获取某一行的数据
        :param sheetName:
        :param rawNo:
        :return: 列表
        '''
        sh = self.wb[sheetName]
        rowValueList = []
        for y in range(2, sh.max_column+1):
            value = sh.cell(rawNo,y).value
            rowValueList.append(value)
        return rowValueList
    def getColumnValue(self, sheetName, colNo):
        '''
        获取某一列的数据
        :param sheetName:
        :param colNo:
        :return: 列表
        '''
        sh = self.wb[sheetName]
        colValueList = []
        for x in range(2, sh.max_row +1):
            value = sh.cell(x, colNo).value
            colValueList.append(value)
        return colValueList

    def getCellOfValue(self, sheetName, rowNo, colNo):
        '''
        获取某一个单元格的数据
        :param sheetName:
        :param rowNo:
        :param colNo:
        :return: 字符串
        '''
        sh = self.wb[sheetName]
        value = sh.cell(rowNo, colNo).value
        return value
    def writeCell(self, sheetName, rowNo, colNo, value):
        '''
        向某个单元格写入数据
        :param rowNo: 行号
        :param colNo: 列号
        :param value:
        :return: 无
        '''
        sh = self.wb[sheetName]
        sh.cell(rowNo, colNo).value = value
        self.wb.save(testExcelValuePath)
if __name__=='__main__':
    p = ParseExcel()
    print(p.getRowValue('126account',2))
    print(p.getColumnValue('126account',3))
    print(p.getCellOfValue('126account', 2, 3))


#!/usr/bin/python
from __future__ import print_function
import torch
import torch.nn as nn
import torch.nn.parallel
import torch.optim as optim
import torch.utils.data
import torchvision.datasets as dset
import torchvision.transforms as transforms
import torchvision.utils as vutils
from torch.autograd import Variable
import time

from descriminator import D
from generator import G

#takes as parameter a neural network and defines its weights
def weights_init(m):
    classname = m.__class__.__name__
    if classname.find('Conv') != -1:
        m.weight.data.normal_(0.0, 0.02)
    elif classname.find('BatchNorm') != -1:
        m.weight.data.normal_(1.0, 0.02)
        m.bias.data.fill_(0)

print("""\n\tA simple example of a:
\t+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+
\t|G|e|n|e|r|a|t|i|v|e| |A|d|v|e|r|s|a|r|i|a|l| |N|e|t|w|o|r|k|
\t+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+
\tCode created by Davidson Mizael based on the course:
\t'Computer Vision A-Z'
\thttps://www.udemy.com/computer-vision-a-z""")

print("\n")
print("# Starting...")

#sets the size of the image (64x64) and the batch
batchSize = 64
imageSize = 64

#creating the transformations
transform = transforms.Compose([transforms.Scale(imageSize),transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),])

print("# Loading data...")
dataset = dset.CIFAR10(root = './data', download = True, transform = transform)
dataloader = torch.utils.data.DataLoader(dataset, batch_size = batchSize, shuffle = True, num_workers = 2)

print("# Starting generator and descriminator...")
netG = G()
netG.apply(weights_init)

netD = D()
netD.apply(weights_init)

#training the DCGANs
criterion = nn.BCELoss()
optimizerD = optim.Adam(netD.parameters(), lr = 0.0002, betas = (0.5, 0.999))
optimizerG = optim.Adam(netG.parameters(), lr = 0.0002, betas = (0.5, 0.999))

epochs = 25

timeElapsed = []
for epoch in range(epochs):
    print("# Starting epoch [%d/%d]..." % (epoch, epochs))
    for i, data in enumerate(dataloader, 0):
        start = time.time()
        time.clock()

        #updates the weights of the discriminator nn
        netD.zero_grad()

        #trains the discriminator with a real image
        real, _ = data
        input = Variable(real)
        target = Variable(torch.ones(input.size()[0]))
        output = netD(input)
        errD_real = criterion(output, target)

        #trains the discriminator with a fake image
        noise = Variable(torch.randn(input.size()[0], 100, 1, 1))
        fake = netG(noise)
        target = Variable(torch.zeros(input.size()[0]))
        ouput = netD(fake.detach())
        errD_fake = criterion(output, target)

        #backpropagating the total error
        errD = errD_real + errD_fake
        errD.backward()
        optimizerD.step()

        #updates the weights of the generator nn
        netG.zero_grad()
        target = Variable(torch.ones(input.size()[0]))
        output = netD(fake)
        errG  = criterion(output, target)

        #backpropagating the error
        errG.backward()
        optimizerG.step()

        if i % 50 == 0:
            #prints the losses and save the real images and the generated images
            print("# Progress: ")
            print("[%d/%d][%d/%d] Loss_D: %.4f Loss_G: %.4f" % (epoch, epochs, i, len(dataloader), errD.data[0], errG.data[0]))

            #calculates the remaining time by taking the avg seconds that every loop
            #and multiplying by the loops that still need to run
            timeElapsed.append(time.time() - start)
            avg_time = (sum(timeElapsed) / float(len(timeElapsed)))
            all_dtl = (epoch * len(dataloader)) + i
            rem_dtl = (len(dataloader) - i) + ((epochs - epoch) * len(dataloader))
            remaining =  (all_dtl - rem_dtl) * avg_time
            print("# Estimated remaining time: %s" % (time.strftime("%H:%M:%S", time.gmtime(remaining))))

        if i % 100 == 0:
            vutils.save_image(real, "%s/real_samples.png" % "./results", normalize = True)
            vutils.save_image(fake.data, "%s/fake_samples_epoch_%03d.png" % ("./results", epoch), normalize = True)

print ("# Finished.")


import numpy as np
import pandas as pd
from collections import defaultdict
from config import Config
import re
import time

#Core Functions

def throw_ini_error(err_type):
    print(err_type)

def read_ini(ini_path, v_name='nickname', filter_str=None):
    with open(ini_path, 'r') as ini:
        ini_lines = list(filter(None, [ln.strip() for ln in re.split(r'^(\[[A-Za-z]*\])', ini.read(), flags=re.M)]))
        ds = next(i for i, string in enumerate(ini_lines) if '[' in string)
        i_comments = ini_lines[:ds]
        i_keys = ini_lines[ds::2]
        i_values = ini_lines[ds+1::2]
        ini_dict = dict()

        for i in range(len(i_keys)):
            if filter_str and filter_str.lower() not in i_keys[i].lower():
                continue

            value_name = i_keys[i]
            i_tuples = list()

            try:
                i_props = list(filter(None, [ip for ip in i_values[i].split('\n') if ';' not in ip]))
            except IndexError:
                throw_ini_error(IndexError)
                continue

            if not i_props:
                continue

            for ip in i_props:
                i_tuples.append(tuple([i_tup.strip() for i_tup in ip.split('=')]))

            if not i_tuples:
                continue

            partial_dict = defaultdict(list)
            try:
                for k, v in i_tuples:
                    if v_name in k:
                        value_name = v
                    partial_dict[k].append(v)
            except ValueError:
                print('ERR: Invalid INI entry in file {0}'.format(ini_path))

            ini_dict[value_name] = partial_dict

    return ini_dict

def get_data(comm_markets_path, distances_path):
    '''
    A function that pulls in the data from marketcommodities.ini and the flc dump file and scrapes it.
    +++++++++
    Parameters:
    comm_markets_path (str): the path of market_commodities.ini
    distances_path (str): the path of the flc dump file
    +++++++++
    Returns
    distances (Dataframe): pandas dataframe of all the viable distances between bases
    bases(nested dict): dictionary structure keys internal name to a dictionary containing every commodity bought and sold
    comm_set (list): list of all commodities bought or sold on all bases
    base_names (dict): all base names keyed to their internal name
    sys_names (dict): all system names keyed to their internal name
    '''

    #distances = pd.read_csv(distances_path, names = ['start', 'end', 'time'])
    #distances = distances[distances['start']!=distances['end']]
    #distances = distances[distances['time']!=-1]

    distances = pd.read_csv(distances_path, names = ['start', 'end', 'time'])
    distances = distances.set_index(['start', 'end'])
    distances['time'] = distances['time'].apply(lambda x: x + 20000) # adding dock time because that's not exported for some reason

    commodities = dict()
    bases = dict()
    infocards = dict()
    sys_ids = dict()
    system_files = dict()
    systems = dict()

    # TODO: Separate out into helper functions; make a specialized class for this and generalize config parsing

    with open(Config.FILEPATH + 'SERVICE/infocards.txt', 'r', encoding='utf8') as i:
        for line in i:
            if line.strip().isdigit():
                next(i, None)
                infocards[line.strip()] = next(i, None)

    select_equip = read_ini(Config.FILEPATH + 'DATA/EQUIPMENT/select_equip.ini', filter_str="commodity")
    goods = read_ini(Config.FILEPATH + 'DATA/EQUIPMENT/goods.ini')
    market_commodities = read_ini(comm_markets_path, 'base')
    u_systems = read_ini(Config.FILEPATH + 'DATA/UNIVERSE/universe.ini', filter_str="system")
    u_bases = read_ini(Config.FILEPATH + 'DATA/UNIVERSE/universe.ini', filter_str="base")

    for k, v in select_equip.items():
        commodities[k.lower()] = {
            "nickname": k.lower(),
            "ids_name": v['ids_name'],
            "display_name": "",
            "base_price": 0.0,
            "consumed_by": [],
            "produced_by": []
            }

    for k, v in goods.items():
        if k.lower() not in commodities.keys():
            continue
        commodities[k.lower()]["base_price"] = float(v['price'][0])

    for k, v in market_commodities.items():
        bases[k.lower()] = {
            "nickname": k.lower(),
            "ids_name": "",
            "display_name": "",
            "archetype": "",
            "system": "",
            "commodities": {}
        }

        for mgs in v['MarketGood']:
            mg = mgs.split(', ')
            raw_data = [m for m in mg]
            commo = mg.pop(0).lower()
            base = bases[k.lower()]['commodities']
            base[commo] = {
                'raw_data': raw_data,
                'price_mult': float(mg.pop()),
                'consumer': int(mg.pop()),
                'max': int(mg.pop()),
                'min': int(mg.pop()),
                'rep': float(mg.pop()),
                'rank': int(mg.pop()),
                'display_name': infocards[commodities[commo]["ids_name"][0]].strip()
            }

            base[commo]['actual_price'] = base[commo]['price_mult'] * commodities[commo]['base_price']

            if base[commo]['price_mult'] > 1.0 or base[commo]['consumer']:
                commodities[commo]['consumed_by'].append(bases[k.lower()])
            if not base[commo]['consumer']:
                commodities[commo]['produced_by'].append(bases[k.lower()])

    for k, v in u_systems.items():
        sys_ids[k.lower()] = v['strid_name'][0]
        if 'file' in v.keys(): # thanks multiuniverse plugin, very cool
            system_files[k.lower()] = v['file'][0]

    for k, v in u_bases.items():
        try:
            bases[k.lower()]["ids_name"] = v['strid_name'][0].lower()
            bases[k.lower()]["system"] = v['system'][0].lower()
        except KeyError:
            pass

    for b_name, b_dict in bases.items():
        strid_name = b_dict['ids_name']
        system = b_dict['system']
        try:
            sys_strid_name = sys_ids[system]
        except KeyError:
            print(b_dict)
        system_path = ""

        try:
            system_path = system_files[system]
        except KeyError:
            print("WARN: Path not found for system '{0}'.".format(system))
        if system not in systems.keys():
            systems[system] = read_ini(Config.UNIPATH + system_path)

        if strid_name == "0":
            b_dict["display_name"] = strid_name
            continue
        try:
            b_dict["display_name"] = infocards[strid_name].strip()
        except KeyError:
            b_dict["display_name"] = strid_name
            print("ERR: No IDS {0} found in infocards.txt for {1}!".format(strid_name, b_name))

        try:
            b_dict["system_dis"] = infocards[sys_strid_name].strip()
        except KeyError:
            b_dict["system_dis"] = sys_strid_name
            print("ERR: No IDS {0} found in infocards.txt for {1}!".format(sys_strid_name, system))

    for c_name, c_dict in commodities.items():
        strid_name = c_dict["ids_name"][0]
        try:
            c_dict["display_name"] = infocards[strid_name].strip()
        except KeyError:
            c_dict["display_name"] = c_name
            print("ERR: No IDS {0} found in infocards.txt for {1}".format(strid_name, c_name))

    with open('help.txt', 'w') as w:
        w.write(str(commodities['commodity_credit1']['produced_by']))

    return distances, bases, commodities

def sort_by_closest_base(list_of_bases, distances):
    '''
    a function that takes the distances dataframe and any list of bases and sorts all the other bases out into the lists of bases closest to those bases in the list of bases.
    Its got a lot of fuckery, and maybe can be given aother pass for better algorithmic complexity. I'm so sorry.

    Parameters
    list_of_bases (list): a list of string base codes
    distances (DataFrame): the base to base travel times from flcomp formatted as a DataFrame by get_data()

    Returns:
    sorted_l (list of lists) list of list of bases, sorted in the same shape as the list of bases fed in,
    with each list containing those bases that are closest to the base listed at the same index in list_of_bases
    '''
    k = [distances[distances['start'] == i] for i in list_of_bases] # makes a list of dataframes of routes starting from the bases in question
    k = [i[~i['end'].isin(list_of_bases)].reset_index() for i in k] # gets rid of routes between bases in the  list

    df = pd.DataFrame()
    for idx, i in enumerate(list_of_bases): #peices the list k back together into a larger thing
        df[i]=k[idx]['time']
    df['base'] = k[0]['end']
    df = df.set_index('base')

    sorted_bases = df.idxmin(axis=1)
    sorted_bases = sorted_bases.reset_index()
    sorted_l =[]

    for i in list_of_bases:
        sorted_l.append(sorted_bases[sorted_bases[0]==i]['base'].to_list())

    return sorted_l


import requests
import os
from twilio.rest import Client

STOCK_NAME = "TSLA"
COMPANY_NAME = "Tesla Inc"

STOCK_API_KEY = os.environ.get("YOUR_STOCK_API_KEY")
NEWS_API_KEY = os.environ.get("YOUR_NEWS_API_KEY")

TWILIO_ACCOUNT_SID = "ACb19b2054a0a3fbc5732431560d8bd4ea"
TWILIO_AUTH_TOKEN = os.environ.get("YOUR_TWILIO_AUTH_TOKEN")

STOCK_ENDPOINT = "https://www.alphavantage.co/query"
NEWS_ENDPOINT = "https://newsapi.org/v2/everything"

# Use https://www.alphavantage.co/documentation/#daily

stock_params = {
    "function": "TIME_SERIES_DAILY",
    "symbol": STOCK_NAME,
    "apikey": STOCK_API_KEY
}

response = requests.get(STOCK_ENDPOINT, params=stock_params)
data = response.json()["Time Series (Daily)"]
# print(data)

# Get yesterday's closing stock price. Hint: You can perform list comprehensions on Python dictionaries.
# e.g. [new_value for (key, value) in dictionary.items()]
data_list = [value for (key, value) in data.items()]
yesterday_data = data_list[0]
yesterday_closing_price = yesterday_data['4. close']
# print(yesterday_closing_price)

# Get the day before yesterday's closing stock price
day_before_yesterday_data = data_list[1]
day_before_yesterday_closing = day_before_yesterday_data['4. close']
# print(day_before_yesterday_closing)

# Find the positive difference between 1 and 2. e.g. 40 - 20 = -20, but the positive difference is 20.
# Hint: https://www.w3schools.com/python/ref_func_abs.asp

difference = float(yesterday_closing_price) - float(day_before_yesterday_closing)
up_down = None
if difference > 0:
    up_down = "🔺"
else:
    up_down = "🔻"

# Work out the percentage difference in price between closing price yesterday and closing price the day before yesterday
diff_percent = round((difference / float(yesterday_closing_price)) * 100)
# print(diff_percent)

# If percentage is greater than 0.1 then print("Get News").

if abs(diff_percent) > 0.1:

    ## https://newsapi.org/
    # Instead of printing ("Get News"), actually get the first 3 news pieces for the COMPANY_NAME.

    news_params = {
        "qInTitle": COMPANY_NAME,
        "apiKey": NEWS_API_KEY,

    }
    news_response = requests.get(NEWS_ENDPOINT, params=news_params)
    news_data = news_response.json()
    articles = news_data["articles"]
    # print(news_articles)

    # Use Python slice operator to create a list that contains the first 3 articles.
    # Hint: https://stackoverflow.com/questions/509211/understanding-slice-notation
    three_articles = [article for article in articles[:3]]
    # print(three_articles)

    # Create a new list of the first 3 article's headline and description using list comprehension.
    formatted_articles = [f"{STOCK_NAME}: {up_down}{diff_percent}%\nHeadline: {article['title']},\n\nBrief: {article['description']}" for article in three_articles]
    # print(formatted_articles)

    # Send each article as a separate message via Twilio.
    for article in formatted_articles:
        client = Client(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN)
        message = client.messages \
            .create(
            body=article,
            from_='+12183877347',
            to='+923402822957'
        )

        print(message.sid)

# Optional TODO: Format the message like this:
"""
TSLA: 🔺2%
Headline: Were Hedge Funds Right About Piling Into Tesla Inc. (TSLA)?.
Brief: We at Insider Monkey have gone over 821 13F filings that hedge funds and prominent investors are required to file by the SEC The 13F filings show the funds' and investors' portfolio positions as of March 31st, near the height of the coronavirus market crash.
or
"TSLA: 🔻5%
Headline: Were Hedge Funds Right About Piling Into Tesla Inc. (TSLA)?.
Brief: We at Insider Monkey have gone over 821 13F filings that hedge funds and prominent investors are required to file by the SEC The 13F filings show the funds' and investors' portfolio positions as of March 31st, near the height of the coronavirus market crash.
"""


from django.shortcuts import render
from django.http import HttpResponse
from . models import Collection, Piece
# Create your views here.
def index(request):
    all_collection = Collection.objects.all()
    context = {
        "all_collection" : all_collection
    }
    return render(request, "genre/genretemplate.html",context)
def details(request, genre_id):
    Citem = Collection.objects.get(id=genre_id)
    Pitem = Piece.objects.filter(collection=Citem)
    context = {
        "Pitem" : Pitem
    }
    return render(request, "genre/detailtemplate.html", context)


from django.conf.urls import patterns, include, url
from django.conf.urls.static import static

from django.contrib import admin
from misc.views import IndexView, BaseView, NavbarView, FooterView
from picea2.settings import base_settings
from publication.views import IssueDetailView, ArticleDetailView, ArticleElementDetailView, \
    PublicationDetailView, NewPublicationView
from userprofile.views import UserprofileDetailView

admin.autodiscover()

urlpatterns = static(base_settings.MEDIA_URL, document_root=base_settings.MEDIA_ROOT)
urlpatterns += patterns('',
    # Examples:
    # url(r'^$', 'picea2.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),

    # misc views
    url(r'^render/index/$', IndexView.as_view(), name='index'),
    url(r'^render/navbar/$', NavbarView.as_view(), name='navbar'),
    url(r'^render/footer/$', FooterView.as_view(), name='footer'),

    # Allauth account views
    url(r'^render/account/', include('allauth.urls')),

    # Userprofile views
    url(r'^render/userprofile/(?P<pk>\d+)/$', UserprofileDetailView.as_view(), name='userprofile'),

    # publication views
    url(r'^render/publication/(?P<pk>\d+)/$', PublicationDetailView.as_view(), name='publication'),
    url(r'^render/publication/new-publication/$', NewPublicationView.as_view(), name='publication'),
    url(r'^render/issue/(?P<pk>\d+)/$', IssueDetailView.as_view(), name='issue'),
    url(r'^render/article/(?P<pk>\d+)/$', ArticleDetailView.as_view(), name='article'),
    url(r'^render/article-element/(?P<pk>\d+)/$', ArticleElementDetailView.as_view(), name='article_element'),

    url(r'^admin/', include(admin.site.urls)),
    url(r'^rosetta/', include('rosetta.urls')),
    url(r'^.*', BaseView.as_view(), name='base'),
)