from __future__ import absolute_import

import celery
import json
import sys
import time

from collections import OrderedDict
from dateutil import parser
from django.core.cache import cache
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.core.urlresolvers import reverse
from django.test.utils import override_settings
from freezegun import freeze_time
from mock import MagicMock, patch
from requests_oauthlib import OAuth2Session

from fitbit import exceptions as fitbit_exceptions
from fitbit.api import Fitbit, FitbitOauth2Client

from fitapp import utils
from fitapp.models import UserFitbit, TimeSeriesData, TimeSeriesDataType
from fitapp.tasks import get_time_series_data

try:
    from io import BytesIO
except ImportError:  # Python 2.x fallback
    from StringIO import StringIO as BytesIO

from .base import FitappTestBase

class TestRetrievalUtility(FitappTestBase):
    """Tests for the get_fitbit_data utility function."""

    def setUp(self):
        super(TestRetrievalUtility, self).setUp()
        self.period = '30d'
        self.base_date = '2012-06-01'
        self.end_date = None

    @patch.object(Fitbit, 'time_series')
    def _mock_time_series(self, time_series=None, error=None, response=None,
                          error_attrs={}):
        if error:
            exc = error(self._error_response())
            for k, v in error_attrs.items():
                setattr(exc, k, v)
            time_series.side_effect = exc
        elif response:
            time_series.return_value = response
        resource_type = TimeSeriesDataType.objects.get(
            category=TimeSeriesDataType.activities, resource='steps')
        return utils.get_fitbit_data(
            self.fbuser, resource_type, base_date=self.base_date,
            period=self.period, end_date=self.end_date)

    def _error_test(self, error):
        with self.assertRaises(error):
            self._mock_time_series(error=error)

    def test_value_error(self):
        """ValueError from the Fitbit.time_series should propagate."""
        self._error_test(ValueError)

    def test_type_error(self):
        """TypeError from the Fitbit.time_series should propagate."""
        self._error_test(TypeError)

    def test_unauthorized(self):
        """HTTPUnauthorized from the Fitbit.time_series should propagate."""
        self._error_test(fitbit_exceptions.HTTPUnauthorized)

    def test_forbidden(self):
        """HTTPForbidden from the Fitbit.time_series should propagate."""
        self._error_test(fitbit_exceptions.HTTPForbidden)

    def test_not_found(self):
        """HTTPNotFound from the Fitbit.time_series should propagate."""
        self._error_test(fitbit_exceptions.HTTPNotFound)

    def test_conflict(self):
        """HTTPConflict from the Fitbit.time_series should propagate."""
        self._error_test(fitbit_exceptions.HTTPConflict)

    def test_server_error(self):
        """HTTPServerError from the Fitbit.time_series should propagate."""
        self._error_test(fitbit_exceptions.HTTPServerError)

    def test_bad_request(self):
        """HTTPBadRequest from the Fitbit.time_series should propagate."""
        self._error_test(fitbit_exceptions.HTTPBadRequest)

    def test_too_many_requests(self):
        """HTTPTooManyRequests from the Fitbit.time_series should propagate."""
        try:
            self._mock_time_series(error=fitbit_exceptions.HTTPTooManyRequests,
                                   error_attrs={'retry_after_secs': 35})
        except fitbit_exceptions.HTTPTooManyRequests:
            self.assertEqual(sys.exc_info()[1].retry_after_secs, 35)
        else:
            assert False, 'Should have thrown exception'

    def test_retrieval(self):
        """get_fitbit_data should return a list of daily steps data."""
        response = {'activities-steps': [1, 2, 3]}
        steps = self._mock_time_series(response=response)
        self.assertEqual(steps, response['activities-steps'])

    def test_refresh(self):
        """If token expires, it should refresh automatically"""

        with patch.object(OAuth2Session, 'request') as r:
            r.side_effect = [
                MagicMock(
                    status_code=401,
                    content=b'{"errors": [{"errorType": "expired_token"}]}'),
                MagicMock(status_code=200,
                          content=b'{"activities-steps": [1, 2, 3]}')
            ]
            with patch.object(OAuth2Session, 'refresh_token') as rt:
                rt.return_value = {
                    'access_token': 'fake_access_token',
                    'refresh_token': 'fake_refresh_token',
                    'expires_at': time.time() + 300,
                }
                resource_type = TimeSeriesDataType.objects.get(
                    category=TimeSeriesDataType.activities, resource='steps')
                utils.get_fitbit_data(
                    self.fbuser, resource_type, base_date=self.base_date,
                    period=self.period, end_date=self.end_date)

        self.assertEqual(self.fbuser.access_token, 'fake_access_token')
        self.assertEqual(self.fbuser.refresh_token, 'fake_refresh_token')

class TestRetrievalTask(FitappTestBase):
    def setUp(self):
        super(TestRetrievalTask, self).setUp()
        self.category = 'activities'
        self.date = '2013-05-02'
        self.value = 10

    def _receive_fitbit_updates(self, status_code=204, file=False, extra_data=None):
        base_data = [{
            'subscriptionId': self.fbuser.user.id,
            'ownerId': self.fbuser.fitbit_user,
            'collectionType': self.category,
            'date': self.date
        }]
        if extra_data is not None:
            base_data.append(extra_data)
        d = json.dumps(base_data).encode('utf8')
        kwargs = {'data': d, 'content_type': 'application/json'}
        if file:
            updates_stringio = BytesIO(d)
            updates = InMemoryUploadedFile(
                updates_stringio, None, 'updates', 'text', len(d), None)
            kwargs = {'data': {'updates': updates}}
        res = self.client.post(reverse('fitbit-update'), **kwargs)

        assert res.status_code == status_code

    @patch('fitapp.utils.get_fitbit_data')
    def test_subscription_update(self, get_fitbit_data):
        # Check that celery tasks get made when a notification is received
        # from Fitbit.
        get_fitbit_data.return_value = [{'value': self.value}]
        category = getattr(TimeSeriesDataType, self.category)
        resources = TimeSeriesDataType.objects.filter(category=category)
        self._receive_fitbit_updates()
        self.assertEqual(get_fitbit_data.call_count, resources.count())
        # Check that the cache locks have been deleted
        for resource in resources:
            self.assertEqual(
                cache.get('fitapp.get_time_series_data-lock-%s-%s-%s' % (
                    category, resource.resource, self.date)
                ), None)
        date = parser.parse(self.date)
        for tsd in TimeSeriesData.objects.filter(user=self.user, date=date):
            assert tsd.value == self.value

    @patch('fitapp.utils.get_fitbit_data')
    def test_subscription_update_file(self, get_fitbit_data):
        # Check that celery tasks get made when an updates file notification
        # is received from Fitbit.
        get_fitbit_data.return_value = [{'value': self.value}]
        category = getattr(TimeSeriesDataType, self.category)
        resources = TimeSeriesDataType.objects.filter(category=category)
        self._receive_fitbit_updates(file=True)
        self.assertEqual(get_fitbit_data.call_count, resources.count())
        # Check that the cache locks have been deleted
        for resource in resources:
            self.assertEqual(
                cache.get('fitapp.get_time_series_data-lock-%s-%s-%s' % (
                    category, resource.resource, self.date)
                ), None)
        date = parser.parse(self.date)
        for tsd in TimeSeriesData.objects.filter(user=self.user, date=date):
            assert tsd.value == self.value

    @override_settings(FITAPP_SUBSCRIPTIONS=OrderedDict([]))
    @patch('fitapp.utils.get_fitbit_data')
    def test_subscription_update_empty_subs(self, get_fitbit_data):
        # Check that an empty dict of subscriptions results in no retrieval
        date = parser.parse(self.date)
        self._receive_fitbit_updates(file=True)

        self.assertEqual(get_fitbit_data.call_count, 0)
        self.assertEqual(
            TimeSeriesData.objects.filter(user=self.user, date=date).count(),
            0
        )

    @override_settings(FITAPP_SUBSCRIPTIONS=OrderedDict([
        ('foods', ['log/caloriesIn', 'log/water']),
    ]))
    @patch('fitapp.utils.get_fitbit_data')
    def test_subscription_update_no_matching_subs(self, get_fitbit_data):
        # Check that we retrieve no data if there are no matching resources
        # in the FITAPP_SUBSCRIPTIONS dict
        date = parser.parse(self.date)
        self._receive_fitbit_updates(file=True)

        self.assertEqual(get_fitbit_data.call_count, 0)
        self.assertEqual(
            TimeSeriesData.objects.filter(user=self.user, date=date).count(),
            0
        )

    @override_settings(FITAPP_SUBSCRIPTIONS=OrderedDict([
        ('foods', ['log/water', 'log/caloriesIn']),
    ]))
    @patch('fitapp.tasks.get_time_series_data.apply_async')
    def test_subscription_update_file_part_match_subs(self, tsd_apply_async):
        # Check that we only retrieve the data requested
        fbuser = UserFitbit.objects.get()
        foods = TimeSeriesDataType.foods
        kwargs = {'date': parser.parse(self.date)}
        self._receive_fitbit_updates(file=True, extra_data={
            'subscriptionId': self.fbuser.user.id,
            'ownerId': self.fbuser.fitbit_user,
            'collectionType': 'foods',
            'date': self.date
        })

        self.assertEqual(tsd_apply_async.call_count, 2)
        tsd_apply_async.assert_any_call(
            (fbuser.fitbit_user, foods, 'log/water',), kwargs, countdown=0)
        tsd_apply_async.assert_any_call(
            (fbuser.fitbit_user, foods, 'log/caloriesIn'), kwargs, countdown=5)

    @override_settings(FITAPP_SUBSCRIPTIONS=OrderedDict([
        ('foods', ['log/water', 'log/caloriesIn', 'bogus']),
    ]))
    @patch('fitapp.tasks.get_time_series_data.apply_async')
    def test_subscription_update_file_bogus_error(self, tsd_apply_async):
        # Check that we only retrieve the data requested
        fbuser = UserFitbit.objects.get()
        foods = TimeSeriesDataType.foods
        kwargs = {'date': parser.parse(self.date)}
        self._receive_fitbit_updates(status_code=500, file=True, extra_data={
            'subscriptionId': self.fbuser.user.id,
            'ownerId': self.fbuser.fitbit_user,
            'collectionType': 'foods',
            'date': self.date
        })

        self.assertEqual(tsd_apply_async.call_count, 0)

    @patch('fitapp.utils.get_fitbit_data')
    @patch('django.core.cache.cache.add')
    def test_subscription_update_locked(self, mock_add, get_fitbit_data):
        # Check that celery tasks do not get made when a notification is
        # received from Fitbit, but there is already a matching task in
        # progress
        mock_add.return_value = False
        self.assertEqual(TimeSeriesData.objects.count(), 0)
        self._receive_fitbit_updates()
        self.assertEqual(get_fitbit_data.call_count, 0)
        self.assertEqual(TimeSeriesData.objects.count(), 0)

    @patch('fitapp.utils.get_fitbit_data')
    def test_subscription_update_too_many(self, get_fitbit_data):
        # Check that celery tasks get postponed if the rate limit is hit
        cat_id = getattr(TimeSeriesDataType, self.category)
        _type = TimeSeriesDataType.objects.filter(category=cat_id)[0]
        lock_id = 'fitapp.tasks-lock-{0}-{1}-{2}'.format(
            self.fbuser.fitbit_user, _type, self.date)
        exc = fitbit_exceptions.HTTPTooManyRequests(self._error_response())
        exc.retry_after_secs = 21
        def side_effect(*args, **kwargs):
            # Delete the cache lock after the first try and adjust the
            # get_fitbit_data mock to be successful
            cache.delete(lock_id)
            get_fitbit_data.side_effect = None
            get_fitbit_data.return_value = [{
                'dateTime': self.date,
                'value': '34'
            }]
            raise exc
        get_fitbit_data.side_effect = side_effect
        category = getattr(TimeSeriesDataType, self.category)
        resources = TimeSeriesDataType.objects.filter(category=category)
        self.assertEqual(TimeSeriesData.objects.count(), 0)
        result = get_time_series_data.apply_async(
            (self.fbuser.fitbit_user, _type.category, _type.resource,),
            {'date': parser.parse(self.date)})
        result.get()
        # Since celery is in eager mode, we expect a Retry exception first
        # and then a second task execution that is successful
        self.assertEqual(get_fitbit_data.call_count, 2)
        self.assertEqual(TimeSeriesData.objects.count(), 1)
        self.assertEqual(TimeSeriesData.objects.get().value, '34')

    @patch('fitapp.tasks.get_time_series_data.retry')
    @patch('fitapp.utils.get_fitbit_data')
    def test_subscription_update_too_many_retry(self, get_fitbit_data, mock_retry):
        # Check that retry is called with the right arguments
        exc = fitbit_exceptions.HTTPTooManyRequests(self._error_response())
        exc.retry_after_secs = 21
        get_fitbit_data.side_effect = exc
        # This return value is just to keep celery from throwing up
        mock_retry.return_value = Exception()
        category = getattr(TimeSeriesDataType, self.category)
        _type = TimeSeriesDataType.objects.filter(category=category)[0]

        self.assertEqual(TimeSeriesData.objects.count(), 0)

        result = get_time_series_data.apply_async(
            (self.fbuser.fitbit_user, _type.category, _type.resource,),
            {'date': parser.parse(self.date)})

        # 22 = 21 + x ** 0
        get_time_series_data.retry.assert_called_once_with(
            countdown=22, exc=exc)
        self.assertRaises(Exception, result.get)
        self.assertEqual(get_fitbit_data.call_count, 1)
        self.assertEqual(TimeSeriesData.objects.count(), 0)

    @patch('fitapp.utils.get_fitbit_data')
    def test_subscription_update_bad_request(self, get_fitbit_data):
        # Make sure bad requests for floors and elevation are ignored,
        # otherwise Reject exception is raised
        exc = fitbit_exceptions.HTTPBadRequest('HI')
        get_fitbit_data.side_effect = exc
        _type = TimeSeriesDataType.objects.get(
            category=TimeSeriesDataType.activities, resource='elevation')

        self.assertEqual(TimeSeriesData.objects.count(), 0)

        result = get_time_series_data.apply_async(
            (self.fbuser.fitbit_user, _type.category, _type.resource,),
            {'date': parser.parse(self.date)})

        self.assertEqual(result.successful(), True)
        self.assertEqual(result.result, None)
        self.assertEqual(TimeSeriesData.objects.count(), 0)

        _type = TimeSeriesDataType.objects.get(
            category=TimeSeriesDataType.activities, resource='floors')
        result = get_time_series_data.apply_async(
            (self.fbuser.fitbit_user, _type.category, _type.resource,),
            {'date': parser.parse(self.date)})

        self.assertEqual(result.successful(), True)
        self.assertEqual(result.result, None)
        self.assertEqual(TimeSeriesData.objects.count(), 0)

        _type = TimeSeriesDataType.objects.get(
            category=TimeSeriesDataType.activities, resource='steps')
        result = get_time_series_data.apply_async(
            (self.fbuser.fitbit_user, _type.category, _type.resource,),
            {'date': parser.parse(self.date)})

        self.assertEqual(result.successful(), False)
        self.assertEqual(type(result.result), celery.exceptions.Reject)
        self.assertEqual(result.result.reason, exc)
        self.assertEqual(TimeSeriesData.objects.count(), 0)

    def test_subscription_update_bad_resource(self):
        # Make sure a resource we don't have yet is handled
        res = get_time_series_data.apply_async(
            (self.fbuser.fitbit_user, 0, 'new_resource',),
            {'date': parser.parse(self.date)})

        self.assertEqual(res.successful(), False)
        self.assertEqual(type(res.result), celery.exceptions.Reject)
        self.assertEqual(
            type(res.result.reason), TimeSeriesDataType.DoesNotExist)
        self.assertEqual(
            getattr(res.result.reason, 'message', res.result.reason.args[0]),
            'TimeSeriesDataType matching query does not exist.')
        self.assertEqual(TimeSeriesData.objects.count(), 0)

    def test_problem_queueing_task(self):
        get_time_series_data = MagicMock()
        # If queueing the task raises an exception, it doesn't propagate
        get_time_series_data.apply_async.side_effect = Exception
        try:
            self._receive_fitbit_updates()
        except:
            assert False, 'Any errors should be captured in the view'

class RetrievalViewTestBase(object):
    """Base methods for the get_steps view."""
    url_name = 'fitbit-steps'
    valid_periods = utils.get_valid_periods()

    def setUp(self):
        super(RetrievalViewTestBase, self).setUp()
        self.period = '30d'
        self.base_date = '2012-06-06'
        self.end_date = '2012-07-07'

    def _check_response(self, response, code, objects=None, error_msg=None):
        objects = objects or []
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content.decode('utf8'))
        self.assertEqual(data['meta']['status_code'], code, error_msg)
        self.assertEqual(data['meta']['total_count'], len(objects), error_msg)
        self.assertEqual(data['objects'], objects, error_msg)

    def test_not_authenticated(self):
        """Status code should be 101 when user isn't logged in."""
        self.client.logout()
        response = self._get(get_kwargs=self._data())
        self._check_response(response, 101)
        self.assertEqual(UserFitbit.objects.count(), 1)

    def test_not_active(self):
        """Status code should be 101 when user isn't active."""
        self.user.is_active = False
        self.user.save()
        response = self._get(get_kwargs=self._data())
        self._check_response(response, 101)
        self.assertEqual(UserFitbit.objects.count(), 1)

    @override_settings(FITAPP_SUBSCRIBE=False)
    def test_not_integrated(self):
        """
        Status code should be 102 when an unsubscribed user is not integrated.
        """
        self.fbuser.delete()
        response = self._get(get_kwargs=self._data())
        self._check_response(response, 102)
        self.assertEqual(UserFitbit.objects.count(), 0)

    @override_settings(FITAPP_SUBSCRIBE=False)
    def test_invalid_credentials_unauthorized(self):
        """
        Status code should be 103 & credentials should be deleted when user
        integration is invalid.
        """
        response = self._mock_utility(get_kwargs=self._data(),
                                      error=fitbit_exceptions.HTTPUnauthorized)
        self._check_response(response, 103)
        self.assertEqual(UserFitbit.objects.count(), 0)

    @override_settings(FITAPP_SUBSCRIBE=False)
    def test_invalid_credentials_forbidden(self):
        """
        Status code should be 103 & credentials should be deleted when user
        integration is invalid.
        """
        response = self._mock_utility(get_kwargs=self._data(),
                                      error=fitbit_exceptions.HTTPForbidden)
        self._check_response(response, 103)
        self.assertEqual(UserFitbit.objects.count(), 0)

    @override_settings(FITAPP_SUBSCRIBE=False)
    def test_rate_limited(self):
        """Status code should be 105 when Fitbit rate limit is hit."""
        response = self._mock_utility(get_kwargs=self._data(),
                                      error=fitbit_exceptions.HTTPConflict)
        self._check_response(response, 105)

    @override_settings(FITAPP_SUBSCRIBE=False)
    def test_fitbit_error(self):
        """Status code should be 106 when Fitbit server error occurs."""
        response = self._mock_utility(get_kwargs=self._data(),
                                      error=fitbit_exceptions.HTTPServerError)
        self._check_response(response, 106)

    def test_405(self):
        """View should not respond to anything but a GET request."""
        url = reverse('fitbit-data', args=['activities', 'steps'])
        for method in (self.client.post, self.client.head,
                       self.client.options, self.client.put,
                       self.client.delete):
            response = method(url)
            self.assertEqual(response.status_code, 405)

    def test_ambiguous(self):
        """Status code should be 104 when both period & end_date are given."""
        data = {'end_date': self.end_date, 'period': self.period,
                'base_date': self.base_date}
        response = self._get(get_kwargs=data)
        self._check_response(response, 104)

class TestRetrievePeriod(RetrievalViewTestBase, FitappTestBase):

    def _data(self):
        return {'base_date': self.base_date, 'period': self.period}

    def test_no_period(self):
        """Status code should be 104 when no period is given."""
        data = self._data()
        data.pop('period')
        response = self._get(get_kwargs=data)
        self._check_response(response, 104)

    def test_bad_period(self):
        """Status code should be 104 when invalid period is given."""
        self.period = 'bad'
        response = self._get(get_kwargs=self._data())
        self._check_response(response, 104)

    @freeze_time('2012-06-06')
    def test_no_base_date(self):
        """Base date should be optional for period request."""
        data = self._data()
        data.pop('base_date')
        steps = [{'dateTime': '2012-06-07', 'value': '10'}]
        TimeSeriesData.objects.create(
            user=self.user,
            resource_type=TimeSeriesDataType.objects.get(
                category=TimeSeriesDataType.activities, resource='steps'),
            date=steps[0]['dateTime'],
            value=steps[0]['value']
        )
        response = self._mock_utility(response=steps, get_kwargs=data)
        self._check_response(response, 100, steps)

    def test_bad_base_date(self):
        """Status code should be 104 when invalid base date is given."""
        self.base_date = 'bad'
        response = self._get(get_kwargs=self._data())
        self._check_response(response, 104)

    def test_period(self):
        steps = [{'dateTime': '2012-06-07', 'value': '10'}]
        TimeSeriesData.objects.create(
            user=self.user,
            resource_type=TimeSeriesDataType.objects.get(
                category=TimeSeriesDataType.activities, resource='steps'),
            date=steps[0]['dateTime'],
            value=steps[0]['value']
        )
        for period in self.valid_periods:
            self.period = period
            data = self._data()
            response = self._mock_utility(response=steps, get_kwargs=data)
            error_msg = 'Should be able to retrieve data for {0}.'.format(
                self.period)
            self._check_response(response, 100, steps, error_msg)

    def test_period_not_integrated(self):
        """
        Period data is returned to a subscribed user who is not integrated
        """
        self.fbuser.delete()
        steps = [{'dateTime': '2012-06-07', 'value': '10'}]
        TimeSeriesData.objects.create(
            user=self.user,
            resource_type=TimeSeriesDataType.objects.get(
                category=TimeSeriesDataType.activities, resource='steps'),
            date=steps[0]['dateTime'],
            value=steps[0]['value']
        )
        for period in self.valid_periods:
            self.period = period
            data = self._data()
            response = self._mock_utility(response=steps, get_kwargs=data)
            error_msg = 'Should be able to retrieve data for {0}.'.format(
                self.period)
            self._check_response(response, 100, steps, error_msg)

class TestRetrieveRange(RetrievalViewTestBase, FitappTestBase):

    def _data(self):
        return {'base_date': self.base_date, 'end_date': self.end_date}

    def test_range__no_base_date(self):
        """Status code should be 104 when no base date is given."""
        data = self._data()
        data.pop('base_date')
        response = self._get(get_kwargs=data)
        self._check_response(response, 104)

    def test_range__bad_base_date(self):
        """Status code should be 104 when invalid base date is given."""
        self.base_date = 'bad'
        response = self._get(get_kwargs=self._data())
        self._check_response(response, 104)

    def test_range__no_end_date(self):
        """Status code should be 104 when no end date is given."""
        data = self._data()
        data.pop('end_date')
        response = self._get(get_kwargs=data)
        self._check_response(response, 104)

    def test_range__bad_end_date(self):
        """Status code should be 104 when invalid end date is given."""
        self.end_date = 'bad'
        response = self._get(get_kwargs=self._data())
        self._check_response(response, 104)

    def test_range(self):
        steps = [{'dateTime': '2012-06-07', 'value': '10'}]
        TimeSeriesData.objects.create(
            user=self.user,
            resource_type=TimeSeriesDataType.objects.get(
                category=TimeSeriesDataType.activities, resource='steps'),
            date=steps[0]['dateTime'],
            value=steps[0]['value']
        )

        response = self._mock_utility(response=steps,
                                      get_kwargs=self._data())
        self._check_response(response, 100, steps)

    def test_range_not_integrated(self):
        """
        Range data is returned to a subscribed user who is not integrated
        """
        self.fbuser.delete()
        steps = [{'dateTime': '2012-06-07', 'value': '10'}]
        TimeSeriesData.objects.create(
            user=self.user,
            resource_type=TimeSeriesDataType.objects.get(
                category=TimeSeriesDataType.activities, resource='steps'),
            date=steps[0]['dateTime'],
            value=steps[0]['value']
        )

        response = self._mock_utility(response=steps,
                                      get_kwargs=self._data())
        self._check_response(response, 100, steps)


import tkinter as tk
import random
import string
from models import Store, Staff, Customer, Product, Order

def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))

class MainWindow(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.num_of_last_product = 4
        self.product_objects = []
        self.is_receipt_open = False
        self.heading = tk.Label(
            self,
            pady=10,
            text='Welcome to Store Management System',
            font='Helvetica 16 bold'
        )

        self.heading.grid(row=0)
        # Frame for Staff and Customer Info
        self.infoFrame = tk.Frame(self)
        self.infoFrame.grid(row=1, sticky=tk.W, padx=20)

        self.staff_label = tk.Label(self.infoFrame, text='Staff Name')
        self.staff_label.grid(row=0, column=0, sticky=tk.EW, )

        self.staff_name = tk.Entry(self.infoFrame)
        self.staff_name.grid(row=0, column=1, sticky=tk.EW, )

        self.customer_label = tk.Label(self.infoFrame, text='Customer ID')
        self.customer_label.grid(row=1, sticky=tk.W)

        self.customer_id = tk.Entry(self.infoFrame)
        self.customer_id.grid(row=1, column=1, sticky=tk.W)

        # Frame for add more Button
        self.add_more_frame = tk.Frame(self)
        self.add_more_frame.grid(row=2, sticky=tk.W, padx=20, pady=10)

        self.add_more_label = tk.Label(self.add_more_frame, text='Add more products')
        self.add_more_label.pack(side=tk.LEFT)

        self.add_more_btn = tk.Button(
            self.add_more_frame,
            text='+',
            background='lightgreen',
            foreground='#fff',
            command=self.add_product_form
        )
        self.add_more_btn.pack(side=tk.LEFT)

        # Frame for products row
        self.pro_frame = tk.Frame(self, height=10)
        self.pro_frame.grid(row=3, sticky=tk.W)

        self.scroll_frame = tk.Scrollbar(self.pro_frame)
        self.scroll_frame.pack(side=tk.RIGHT, fill=tk.Y)

        self.products_frame = tk.Frame(self.pro_frame)
        self.products_frame.pack()

        # product headers
        self.pro_name_label = tk.Label(self.products_frame, text='Product Name')
        self.pro_name_label.grid(row=0, column=0)

        self.pro_code_label = tk.Label(self.products_frame, text='Product Code')
        self.pro_code_label.grid(row=0, column=1)

        self.pro_price_label = tk.Label(self.products_frame, text='Price')
        self.pro_price_label.grid(row=0, column=2)

        self.pro_qual_label = tk.Label(self.products_frame, text='Quantity')
        self.pro_qual_label.grid(row=0, column=3)

        self.pro_point_label = tk.Label(self.products_frame, text='Points')
        self.pro_point_label.grid(row=0, column=4)

        # initial four row inputs
        for item in range(1, 5):
            self.product_objects.append(ProductFrame(self.products_frame, item))

        self.warning_label = tk.Label(
            self,
            fg='#f0ad4e',
            text='',
            font='Helvetica 16 bold'
        )
        self.warning_label.grid(row=4)

        self.action_frame = tk.Frame(self)
        self.action_frame.grid(row=5, sticky=tk.W)

        self.print_btn = tk.Button(
            self.action_frame,
            text='Print',
            background='lightgreen',
            foreground='#fff',
            padx=50,
            command=self.print_action
        )
        self.print_btn.pack(side=tk.LEFT, padx=10, pady=20)

        self.close_btn = tk.Button(
            self.action_frame,
            text='Close',
            background='lightgreen',
            foreground='#fff',
            padx=50,
            command=self.exit
        )
        self.close_btn.pack(side=tk.LEFT, padx=10, pady=20)

    def exit(self):
        self.master.destroy()

    def on_receipt_close(self):
        self.t.destroy()
        self.is_receipt_open = False

    # to add new product input row
    def add_product_form(self):
        self.num_of_last_product = self.num_of_last_product + 1
        self.product_objects.append(ProductFrame(self.products_frame, self.num_of_last_product))

    def print_action(self):
        store = Store(
            name='Magnit',
            address='2, Amir Temur street, Tashkent',
            ID='2-A-T-T',
            tel='+9987188778877'
        )
        AkhmadjonClient = Customer(
            ssn=id_generator(),
            name=id_generator(),
            address='{}, {}, {}'.format(id_generator(1), id_generator(), id_generator()),
            ID=self.customer_id.get(),
            tel=id_generator(9),
            memberships=['Bronze']
        )

        RuziStaff = Staff(
            ssn=id_generator(),
            name=self.staff_name.get(),
            address='{}, {}, {}'.format(id_generator(1), id_generator(), id_generator()),
            job_id=id_generator(),
            job_title=id_generator(),
            salary=120
        )

        AbdulloOrder = Order(
            store=store,
            customer=AkhmadjonClient,
            staff=RuziStaff
        )

        if self.staff_name.get() is '' or self.customer_id.get() is '':
            self.warning_label['text'] = 'Please fill all fields'
            return False

        filtered_obj = [obj for obj in self.product_objects if obj.not_empty_fields()]

        for item in filtered_obj:
            if item.validate_empty(self.warning_label):
                product = Product(
                    product_code=int(item.product_code),
                    name=item.product_name,
                    description='Product of - {}'.format(id_generator()),
                    price=int(item.product_price),
                    points=int(item.product_point)
                )
                amount = int(item.product_qual)
                AbdulloOrder.add_product({"product": product, "amount": amount})

            else:
                self.warning_label['text'] = 'Please fill all fields'
                return False

        if not self.is_receipt_open:
            self.t = tk.Toplevel(self)
            self.t.wm_title("Receipt")
            self.t.protocol('WM_DELETE_WINDOW', self.on_receipt_close)
            self.draw_receipt(AbdulloOrder)
        self.is_receipt_open = True

    def draw_receipt(self, order):
        self.receipt_data = dict()
        receipt = self.receipt_data

        receipt['heading'] = tk.Label(
            self.t,
            pady=10,
            text='Welcome to {} Store Management System'.format(order.store.name),
            font='Helvetica 16 bold'
        )
        receipt['heading'].grid(row=0, columnspan=6, padx=30)

        # Frame for Staff and Customer Info
        receipt['staff'] = tk.Label(self.t, text='Staff Name: %s' % order.staff.name, padx=10)
        receipt['staff'].grid(row=1, column=0, sticky=tk.W)

        receipt['customer'] = tk.Label(self.t, text='Customer ID: %s' % order.customer.ID, padx=10)
        receipt['customer'].grid(row=2, sticky=tk.W)

        # product headers
        receipt['name_label'] = tk.Label(self.t, text='Product Name', pady=10)
        receipt['name_label'].grid(row=3, column=0)

        receipt['code_label'] = tk.Label(self.t, text='Product Code', pady=10)
        receipt['code_label'].grid(row=3, column=1)

        receipt['price_label'] = tk.Label(self.t, text='Price', pady=10)
        receipt['price_label'].grid(row=3, column=2)

        receipt['quant_label'] = tk.Label(self.t, text='Quantity', pady=10)
        receipt['quant_label'].grid(row=3, column=3)
        row = 4
        total_points = 0
        total_price = 0
        total_items = 0
        for index, obj in enumerate(order.products):
            row += index
            product = obj['product']
            amount = obj['amount']
            total_items += amount
            total_points = total_points + product.points
            total_price = total_price + (amount * product.price)
            tk.Label(self.t, text=product.name).grid(row=row, column=0)
            tk.Label(self.t, text=product.product_code).grid(row=row, column=1)
            tk.Label(self.t, text=product.price).grid(row=row, column=2)
            tk.Label(self.t, text=amount).grid(row=row, column=3)

        tk.Label(self.t, pady=10).grid(row=row + 1, sticky=tk.W)
        tk.Label(self.t, text='Total:    {}$'.format(total_price), padx=10).grid(row=row + 2, sticky=tk.W)
        tk.Label(self.t, text='Total items:    {}'.format(total_items), padx=10).grid(row=row + 3, sticky=tk.W)
        tk.Label(self.t, text='Points:    {}'.format(total_points), padx=10).grid(row=row + 4, sticky=tk.W)
        frame = tk.Frame(self.t)
        frame.grid(row=row + 5, sticky=tk.E, pady=10, column=3)
        tk.Button(frame, text='Close', padx=30, bg='lightgreen', fg='#fff', command=self.on_receipt_close).grid(row=0,
                                                                                column=3,
                                                                                sticky=tk.E)

def validate(in_str, acttyp):
    if acttyp == '1':  # insert
        if not in_str.isdigit():
            return False
    return True

# Class to easily control product input row

class ProductFrame():
    fields = ['product_name', 'product_code', 'product_price', 'product_qual', 'product_point']

    def __init__(self, frame, row):
        self.__product_name = tk.Entry(frame, borderwidth=1)

        self.__product_name.grid(row=row, column=0, padx=5, pady=2)

        validate_number = (frame.register(validate), '%P', '%d')

        self.__product_code = tk.Entry(frame, validate="key", validatecommand=validate_number)
        self.__product_code.grid(row=row, column=1, padx=5, pady=2)

        self.__product_price = tk.Entry(frame, validate="key", validatecommand=validate_number)
        self.__product_price.grid(row=row, column=2, padx=5, pady=2)

        self.__product_qual = tk.Entry(frame, validate="key", validatecommand=validate_number)
        self.__product_qual.grid(row=row, column=3, padx=5, pady=2)

        self.__product_point = tk.Entry(frame, validate="key", validatecommand=validate_number)
        self.__product_point.grid(row=row, column=4, padx=5, pady=2)

    @property
    def product_name(self):
        return self.__product_name.get()

    @property
    def product_code(self):
        return self.__product_code.get()

    @property
    def product_price(self):
        return self.__product_price.get()

    @property
    def product_qual(self):
        return self.__product_qual.get()

    @property
    def product_point(self):
        return self.__product_point.get()

    def not_empty_fields(self):
        vals = [self.product_code, self.product_name, self.product_qual, self.product_price, self.product_point]
        return not all(el == '' for el in vals)

    def validate_empty(self, label):
        vals = [self.product_code, self.product_name, self.product_qual, self.product_price, self.product_point]
        return all(vals)

if __name__ == "__main__":
    root = tk.Tk()
    main = MainWindow(root)
    root.wm_title('Magnit')
    main.pack(side="top", fill="both", expand=True)
    root.mainloop()


from blog_handler import BlogHandler
from models.post import Post
from google.appengine.ext import db

def blog_key(name='default'):
    return db.Key.from_path('blogs', name)

class DeletePost(BlogHandler):

    """ Handler for deleting posts

    There is no GET because users shouldn't be visiting this
    POST: Get the post based on post id and check if the current user is the
    same as the comment's user. If so, delete the post. Else,
    redirect with an error

    """

    def post(self, post_id):
        if self.user:
            key = db.Key.from_path('Post', int(post_id), parent=blog_key())
            post = db.get(key)
            if post.author.name == self.user.name:
                post.delete()
                return self.redirect("/blog?message=Deleted post successfully!")
            else:
                return self.redirect(
                    "/blog/%s?error=You don't have access to delete this post."
                    % post_id)
        else:
            return self.redirect(
                "/login?error=You need to be logged, in order to delete " +
                "a post")


t = int(input())
for i in range(t):
    n,k = map(int, input().split())
    if k>n:
        print(n)
        continue
    ans = 0
    # maxi = 0
    for j in range(1,k+1):
        temp = n%j
        if ans<=temp:
            ans = temp
            # maxi = j
            # print(j,ans)
    print(ans)


# 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 http.client as http_client
from unittest import mock

from oslo_serialization import jsonutils
from oslo_utils import encodeutils
import webob

from senlin.api.common import wsgi
from senlin.api.openstack.v1 import version as v1_controller
from senlin.api.openstack import versions
from senlin.tests.unit.common import base

class VersionControllerTest(base.SenlinTestCase):

    def test_init(self):
        conf = mock.Mock()

        controller = versions.Controller(conf)

        self.assertIsNotNone(controller)
        self.assertEqual(conf, controller.conf)

    @mock.patch.object(v1_controller.VersionController, 'version_info')
    def test_call(self, mock_v1):
        mock_v1.return_value = {'foo': 'bar'}
        conf = mock.Mock()
        controller = versions.Controller(conf)
        environ = {
            'REQUEST_METHOD': 'GET',
            'SERVER_NAME': 'host',
            'SERVER_PORT': 8777,
            'SCRIPT_NAME': '/',
            'PATH_INFO': '/',
            'wsgi.url_scheme': 'http',
        }
        req = wsgi.Request(environ)
        expected_dict = {
            'versions': [{'foo': 'bar'}]
        }
        expected_body = jsonutils.dumps(expected_dict)

        resp = controller(req)

        self.assertIsInstance(resp, webob.Response)
        self.assertEqual(expected_body, encodeutils.safe_decode(resp.body))
        self.assertEqual(http_client.MULTIPLE_CHOICES, resp.status_code)
        self.assertEqual('application/json', resp.content_type)


# -*- coding: UTF-8 -*-
from network.packet import PacketBase

class PacketHandler:
	packet_list = []

	@classmethod
	def register(cls, name, struct, opcode, recv = False):
		cls.packet_list.append({
			"name": name,
			"recv": recv,
			"opcode": opcode,
			"struct": struct,
		})

	@classmethod
	def get_packet_by_opcode(cls, opcode, recv = False, size = None):
		for value in cls.packet_list:
			if opcode == value["opcode"] and recv == value["recv"] and (size is None or size == value['struct'].sizeof()):
				return value['name'], value['struct']
		return f"UNKNOWN_0x{opcode:X}", PacketBase

	@classmethod
	def get_packet_by_name(cls, name, recv = False, size = None):
		for value in cls.packet_list:
			if name == value["name"] and recv == value["recv"] and (size is None or size == value['struct'].sizeof()):
				return value["opcode"], value['struct']
		return 0, PacketBase


class Solution:
    def numberOfArithmeticSlices(self, A: List[int]) -> int:
        count = 0
        carry = 0
        for i in range(2,len(A)):
            # Checking the difference of every slice of 3 numbers.
            if A[i] - A[i - 1] == A[i - 1] - A[i - 2]:
                # Adding one to carry if the differences are consistent after the
                # minimum slice.
                carry += 1
                count += carry
            else:
                carry=0
        return count


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri May 19 06:57:07 2023

@author: dpw

implement a Taylor series about x = 0 to calculate (approximate) the value of e
or any power of e.
"""

from sympy import factorial

def f(x, n):
    return float(x**n / factorial(n))

def sum_series(x, *args, **kwargs):
    max_iterations = 100
    result = 0.0

    for i in range(max_iterations):
        result += f(x, i)

    return result

result = sum_series(1)

# modify this to take cli inputs for  x value, number of iterations

print(result)


#백준 11724 연결요소의 개수
import sys
sys.setrecursionlimit(10000) #재귀함수 최대 깊이 설정
input = sys.stdin.readline
N,M = map(int,input().split())  #노드, 에지 개수 입력
A = [[] for _ in range(N+1)]    #인접 리스트
visited = [False] * (N+1)   #방문 리스트
result = 0  #연결요소의 개수

def DFS(v): #DFS 탐색 실행
    visited[v] = True
    for i in A[v]:
        if not visited[i]:
            DFS(i)

for _ in range(M): #에지 입력
    s, e = map(int, input().split())
    #양방향 에지이므로 양쪽에 에지 더함
    A[s].append(e)
    A[e].append(s)

for i in range(1, N+1): #연결 노드 중 방문x 노드만 탐색
    if not visited[i]:
        result += 1
        DFS(i)

print(result)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import warnings
warnings.filterwarnings(
    'ignore', category=UserWarning)
import nltk.tokenize as tk
import nltk.corpus as nc
import nltk.stem.snowball as sb
import gensim.models.ldamodel as gm
import gensim.corpora as gc

doc = []
with open('topic.txt') as f:
    for line in f.readlines():
        doc.append(line[:-1])

# 正则表达式分词器
tokenizer = tk.RegexpTokenizer(r'\w+')  # 使用1到多个空白字符分割

# 获取废词（出现频率高，但是语义贡献却很小的词）集合
stopwords = nc.stopwords.words('english')

# 创建思诺博词干提取器
stemmer = sb.SnowballStemmer('english')
lines_tokens = []
for line in doc:
    tokens = tokenizer.tokenize(line.lower())
    line_tokens = []
    for token in tokens:
        if token not in stopwords:
            token = stemmer.stem(token)
            line_tokens.append(token)
    lines_tokens.append(line_tokens)  # 变成二维列表
print(lines_tokens)

# 词典 升序排列
dic = gc.Dictionary(lines_tokens)

bow = []
for line_tokens in lines_tokens:
    row = dic.doc2bow(line_tokens)
    bow.append(row)

# 创建隐含狄利克雷分布
# passes=25 设置聚类的规模
model = gm.LdaModel(bow, num_topics=2, id2word=dic, passes=25)
# 类似聚类的方法 提取文档中的主题词
topics = model.print_topics(num_topics=2, num_words=4)
print(topics)


# Import heapq
from heapq import *

# Function to return the minimum cost
def connectRopes(arr):
    # Convert arr to min heap
    heapify(arr)

    # Initialize cost
    cost = 0

    # Traverse till only element remains in min heap
    while len(arr) > 1:
        # Pop the two smallest element
        a = heappop(arr)
        b = heappop(arr)

        # Get the sum
        currCost = a + b

        # Increment the cost
        cost += currCost

        # Push the currCost to min heap
        heappush(arr, currCost)

    # Return the final cost
    return cost

# Initialize list with length of ropes
arr = [1, 2, 3, 4, 5]

# Call the function
print(connectRopes(arr))


from flask import Flask, request, render_template
from flask_sqlalchemy import SQLAlchemy
import math

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = (
    'mysql+pymysql://YanServer:123test@yanzzp.xyz:3306/test2'
)
db = SQLAlchemy(app)

class Calculation(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    expression = db.Column(db.String(255))
    result = db.Column(db.String(255))

@app.route('/')
def calculator():
    calculations = Calculation.query.all()  # 获取所有计算记录
    return render_template('calculator2.html', result="", calculations=calculations)

@app.route('/calculate', methods=['POST'])
def calculate():
    expression = request.form['expression']
    calculations = Calculation.query.all()  # 获取所有计算记录
    try:
        # 提供math库中的三角函数
        safe_globals = {"sin": math.sin, "cos": math.cos, "tan": math.tan}
        result_val = eval(expression, {"__builtins__": None}, safe_globals)

        # 创建一个新的数据库记录并保存
        calculation = Calculation(expression=expression, result=str(result_val))
        db.session.add(calculation)
        db.session.commit()

        return render_template('calculator2.html', result=result_val, expression=expression, calculations=calculations)
    except Exception as e:
        error_message = "Invalid input or calculation error: " + str(e)
        return render_template('calculator2.html', error_message=error_message, calculations=calculations)

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

if __name__ == '__main__':
    app.run(debug=True)


"""
    algorithm:实现软间隔化的核函数SVM二分类算法
    reference:http://github.com/ajtulloch/svmpy
    Note:上面参考地址给出了基于凸优化库cvxopt的svm实现版本，代码写的很棒，但是对于cvxopt库了解不多，后面如果有机会希望重写一下这个算法，相信会加深理解的。
    采用slearn实现svm
    dataset：lonosphere_dataset.txt
    author：crazicoco
"""
from sklearn.svm import SVC
# sklearn.preprocessing 提供三种数据标准化的处理方式，StandardScaler, MinMaxScaler, RobusScaler。防止因为异常点影响结果
from sklearn.preprocessing import StandardScaler
# 网格搜索，在参数列表中穷举搜索找到最优的结果，为了减少偶然性，会结合交叉验证的方法进行
from sklearn.model_selection import GridSearchCV, train_test_split
import random
import numpy as np

def load_data(address):
    features = []
    labels = []
    for line in open(address):
        field = line.strip().split(',')
        feature = field[:-1]
        label = field[-1]
        features.append(feature)
        labels.append(label)
    scaler = StandardScaler()
    # 标准化
    features = scaler.fit_transform(features)
    return features, labels

def split_data(features, labels):
    random.seed(10)
    train_features = []
    train_labels = []
    test_features = []
    test_labels = []
    for i, (feature, label) in enumerate(zip(features, labels)):
        digit = random.random()
        if digit < 0.9:
            train_features.append(feature)
            train_labels.append(label)
        else:
            test_features.append(feature)
            test_labels.append(label)
    return train_features, train_labels, test_features, test_labels

def main():
    name = "data/lonosphere_dataset.txt"
    features, label = load_data(address=name)
    train_features, train_labels, test_features, test_labels = split_data(features=features, labels=label)
    model = SVC(kernel='linear')
    # 参考参数给出是等比数列的形式
    c_range = np.logspace(-5, 15, 11, base=2)
    gamma_range = np.logspace(-9, 3, 13, base=2)
    param_grid = [{'kernel': ['linear'], 'C':c_range, 'gamma':gamma_range}]
    grid = GridSearchCV(model, param_grid=param_grid, cv=3, n_jobs=-1)
    clf = grid.fit(train_features, train_labels)
    score = grid.score(test_features, test_labels)
    print('精度为%s' % score)

if __name__ == "__main__":
    main()


# !/usr/bin/env python
# ! _*_ coding:utf-8 _*_
# @TIME   : 2018/12/14  19:26
# @Author : Noob
# @File   : basepage.py

"""
Project:基础类BasePage，封装所有页面都公用的方法；
定义open函数，重定义find_element,switch_frame,send_keys等函数；
在初始化方法中定义驱动driver,基本url，title；
WebDriverWait提供了显示等待方式；
"""

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os
import time
import yaml
import csv
import xlrd

class BasePage(object):

    """
    1. 初始化driver、url、pagetitle等；
    2. 实例化BasePage类时，最先执行的就是__init__方法，该方法的入参，其实就是BasePage类的入参；
    3. __init__方法不能有返回值，只能返回None；
    4. self指实例本身，相较于类BasePage而言
    """

    def __init__(self, browser_driver, base_url, pagetitle):
        self.driver = browser_driver
        self.base_url = base_url
        self.pagetitle = pagetitle

    """
    1. 通过title断言进入的页面是否正确；
    2. 使用title获取当前窗口title，检查输入的title是否在当前title中，返回比较结果（True or False）
    """
    def on_page(self, pagetitle):
        return pagetitle in self.driver.title

    """
    1. 打开页面，并校验页面链接是否加载正确
    2. 以单下划线_开头的方法，在使用import *时，该方法不会被导入，保证该方法为类私有的；
    """
    def _open(self, url, pagetitle):
        # 使用get打开访问链接地址
        self.driver.get(url)
        self.driver.maximize_window()
        # 使用assert进行校验，打开的窗口title是否与配置的title一致。调用on_page方法。
        assert self.on_page(pagetitle), u'打开页面失败%s' % url

    # 定义open方法，掉用_open()进行打开链接
    def open(self):
        self._open(self.base_url, self.pagetitle)

    # 重写元素定位方法
    def find_element(self, *loc):
        # return self.driver.find_element(*loc)
        try:
            # 确保元素是可见的；
            # 注意：以下入参为元祖的元素，需要加*。Python存在这种特性，就是讲入参放在元祖里；
            # WebDriverWait(self.driver, 10).untli(lamba driver: driver.find_element(*loc).is_displayed())
            # 注意：以下入参本身是元祖，不需要加*
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(loc))
            return self.driver.find_element(*loc)
        except:
            print(u'%s 页面中未能找到%s元素' % (self, loc))

    # 重写switch_frame方法
    def switch_frame(self, loc):
        loc = self.find_element(loc)
        return self.driver.switch_to.frame(loc)

    # 定义scrip方法，用于执行js脚本，范围执行结果
    def scirpt(self, src):
        self.driver.execute_script(src)

    # 重写定义send_keys方法
    def send_keys(self, loc, value, clear_first=True, click_first=True):
        try:
            # getattr相当于实现self.loc
            loc = getattr(self, '_%s' % loc)
            if click_first:
                self.find_element(*loc).click()
            if clear_first:
                self.find_element(*loc).clear()
                self.find_element(*loc).send_keys(value)
        except AttributeError:
            print(u'%s页面中未能找到%s元素' % (self, loc))

    # 重写截图
    def screenshot(self, loc):
        picture_time = time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime(time.time()))
        try:
            # 获取当前脚本的路径
            cwd_path = os.path.dirname(os.path.realpath(__file__))
            # self.__class__.__name__：当前运行文件的类名
            screenshot_path = os.path.join(cwd_path, 'screenshot_' + self.__class__.__name__)
            # 判断放置运行测试脚本的截图文件夹是否存在，如果不存在则创建
            if not os.path.exists(screenshot_path):
                os.makedirs(screenshot_path)
                print('截图目录新建成功：%s' % screenshot_path)
            else:
                print('该目录已存在！')
            error_text = self.find_element(*loc).text
            if 'Incorrect' in error_text:
                self.driver.get_screenshot_as_file(screenshot_path + '\\' + picture_time + '.png')
        except BaseException as msg:
            print('新建截图目录失败：%s' % msg)

    # 外部数据
    def get_data(self, filename):
        cwd_path = os.path.dirname(os.path.realpath(__file__))
        file_path = os.path.join(cwd_path, 'data\\' + filename)
        try:
            assert os.path.isfile(file_path), filename
        except AssertionError as msg:
            if filename == '':
                list_data = (['000', '000'], ['111', '111'])
                return list_data
            else:
                print('该文件不存在：%s' % msg)
        if file_path.endswith('.txt'):
            f = open(file_path, 'r', encoding='utf-8')
            cfg = f.readlines()
            cfg.remove(cfg[0])
            rows = []
            for i in cfg:
                i = i.split(',')
                i[1] = i[1].rstrip('\n')
                rows.append(i)
            return rows
        elif file_path.endswith('.csv'):
            cfg = csv.reader(open(file_path, 'r', encoding='utf-8'))
            next(cfg, None)
            rows = []
            for i in cfg:
                rows.append(i)
            return rows
        elif file_path.endswith('.xlsx'):
            book = xlrd.open_workbook(file_path)
            sheet = book.sheet_by_index(0)
            rows = []
            for idx in range(1, sheet.nrows):
                i = sheet.row_values(idx, 0, sheet.ncols)
                rows.append(i)
            rows[1][0] = int(rows[1][0])
            rows[1][1] = int(rows[1][1])
            return rows
        elif file_path.endswith('.yaml'):
            f = open(file_path, 'r', encoding='utf-8')
            cfg = yaml.load(f)
            f.close()
            cfg.remove(cfg[0])
            return cfg
        else:
            return '不能使用该类型的文件！'

if __name__ == '__main__':
    bp = BasePage(None, None, None)
    i = bp.get_data('data')
    print(i)


class Square:

    def __init__(self, height="0", width="0"):
        self.height = height
        self.width = width

    # Getter
    # allows reference to individual fields
    @property
    def height(self):
        print("Retrieving the Height")

        # use __ to show that information is private
        return self.__height

    # Setter
    # protect form putting in bad data
    @height.setter
    def height(self, value):

        if value.isdigit():
            self.__height = value
        else:
            print("Please only enter numbers for height")

    @property
    def width(self):
        print("Retrieving the Width")

        return self.__width

    @width.setter
    def width(self, value):

        if value.isdigit():
            self.__width = value
        else:
            print("Please only enter numbers for width")

    def getArea(self):
        self.__width = int(self.__width) * (int(self.__height))
        return int(self.__width) * (int(self.__height))

def main():
    aSquare = Square()

    height = input("Enter Height: ")
    width = input("Enter Width: ")

    # because we use @property and @height.setter, don't need height()
    aSquare.height = height
    aSquare.width = width

    print("Height: ", aSquare.height)
    print("Width: ", aSquare.width)
    print(aSquare.width)
    aSquare.width = str(aSquare.getArea())
    print(aSquare.width)

main()


"""
Alexandra Pawlak
TCSS 554
November 30, 2017
Homework #1

Description: Implementation of PageRank. Reads in an adjacency matrix (inputfile)
through a text file. The input file must be in the matrix format
with 3 columns (i j k).
Each row denotes that the matrix contains a value k at the row i, column j.
The value k=1 denotes that there is a link from the document (node) i to
document (node) j.
The dampening factorb (beta) is set to 0.85

The program outputs the original matrix, the original rank vector,
the converged rank vector, and the number of iterations it took to convergence.
"""

import pandas as pd
import numpy as np

beta = 0.85
epsilon = 0.0001
inputfile = 'graph.txt'

# Read in adjacency matrix
df = pd.read_table(inputfile, sep=' ', header=None)
del df[2]

if isinstance(df[0][0], str) == True:
    for i in range(len(df[0])):
        df[0][i] = ord(df[0][i])-96
        df[1][i] = ord(df[1][i])-96

# Store unique values (nodes) in adjacency matrix
inNode = df[0].unique()
outNode = df[1].unique()
nodes = np.concatenate((inNode, outNode), axis=0)
nodes = np.unique(nodes)

# Find total number of nodes
numNodes = len(nodes)

#Count edges leaving each node
inCount = df[0].value_counts()
inCount = inCount.to_dict()

# Create matrix in dimensions of number of nodes and zero out
matrix = np.zeros((numNodes, numNodes))

# Fill transition matrix
for i in range(len(df[0])):
    tempIn = df[0][i]
    tempOut = df[1][i]
    matrix[tempIn-1][tempOut-1] = 1/inCount.get(tempIn)

matrix = np.transpose(matrix)
matrix = np.round(matrix, decimals = 6)

print('Matrix M:')
print(matrix)

# Multiply transistion matrix by dampening and round
matrix = matrix*beta
matrix = np.round(matrix, decimals=6)

# Create matrix for page ranks
rv = np.ones((numNodes, 1)) * (1/numNodes)
rv = np.round(rv, decimals = 6)

print('Original Rank Vector:')
print(rv)

#Calculate random jump value
jump = (1-beta)/numNodes

# Compute page ranks until convergence
iterCount = 1
while True:
    prev_rv = rv
    rv = np.matmul(matrix, rv) + jump
    rv = np.round(rv, decimals = 6)
    if (abs(np.subtract(rv, prev_rv))<epsilon).all():
        break
    iterCount+=1

# Print page ranks and number of iterations
print('Converged Rank Vector:')
print(rv)
print('Number of Iterations to Convergence:')
print(iterCount)


# Encode a text to prevent "shoulder surfing"
import base64, sys
if len(sys.argv) != 2:
    print("Usage: " + sys.argv[0] + " text")
else:
    enc = []
    msg = "warning:"
    for i, ch in enumerate(sys.argv[1]):
        key_c = msg[i % len(msg)]
        enc_c = chr((ord(ch) + ord(key_c)) % 256)
        enc.append(enc_c)
    print ("HEX:" + base64.urlsafe_b64encode("".join(enc).encode('utf8')).hex())


from datetime import date
data_atual = date.today()
data_em_texto = "0{}/0{}/{}".format(data_atual.day, data_atual.month,data_atual.year)

listaNomes      = ['Andre','Joao','Luccas']
listaIdades     = [23,21,25]
listaNascimento = ['23/11/1998','05/07/2000','18/01/1996']
listaMesMenor = ['04', '06', '09', '11']

def menu():
    m = ''' \n
            0-  Finalizar
            1-  Cadastrar dados nas listas
            2-  Listar somente os nomes
            3-  Listar os dados completos das pessoas
            4-  Localizar o nome de alguém e mostrar todos seus dados
            5-  Alterar a idade ou a data de nascimento
            6-  Excluir alguém do cadastro
            Escolha: '''
    return input(m)

def verificarIdade(idade):
    try:
        if int(idade) > 0 and int(idade) < 115:
            return idade
        else:
            print("Digite uma maior que zero")
    except:
        print("Digite uma idade válida")

    return verificarIdade(input("Digite a idade: "))

def verificarDataNasc(data):
    try:
        if data[2:3] == '/' and data[5:6] == '/':
            if int(data[:2]) > 00 and int(data[:2]) <= 31:
                if int(data[3:5]) > 00 and int(data[3:5]) < 12:
                    if data[3:5] in listaMesMenor and int(data[:2]) <= 30:
                        pass
                    elif data[3:5] == '02' and int(data[:2]) <= 28:
                        pass
                    elif data[3:5] not in listaMesMenor:
                        pass
            if data[6:] <= data_em_texto[6:]:
                listaNascimento.append(data)
        else:
            print("Digite uma data valida")
            verificarDataNasc(input("Digite a data de nascimento no formato dd/mm/aaaa: : "))
    except:
        print("Digite uma data valida")
        verificarDataNasc(input("Digite a data de nascimento no formato dd/mm/aaaa: : "))

def cadastro():
    listaNomes.append(input("Digite o nome: "))
    listaIdades.append(verificarIdade(input("Digite a idade: ")))
    listaNascimento.append(verificarDataNasc(input("Digite a data de nascimento no formato dd/mm/aaaa: : ")))

def listarNomes():
    for nome in range(len(listaNomes)):
        print("Nome: %s"%listaNomes[nome])

def listarDados():
    for i in range(len(listaNomes)):
        printar(i)

def localizarDados():
    while True:
        nome = input("Digite o nome que deseja buscar ou 0 para sair: ")
        if nome in listaNomes:
            i = listaNomes.index(nome)
            printar(i)
        elif nome == '0':
            break
        print("Nome não encontrado")

def attDado():
    nome = input("Digite o nome de quem deseja alterar: ")
    if nome in listaNomes:
        i = listaNomes.index(nome)
        while True:
            n = input("Digite 1 para alterar a idade ou 2 para data de nascimento ou 0 para sair: ")
            if n == '1':
                novaIdade = verificarIdade(input("Digite a nova idade: "))
                listaIdades[i] = novaIdade
                break
            elif n == '2':
                novaData = verificarDataNasc(input("Digite a data de nascimento no formato dd/mm/aaaa: : "))
                listaNascimento[i] = novaData
                break
            elif n == '0':
                break
            else:
                print("Digite 1 para alterar a idade ou 2 para data de nascimento ou 0 para sair: ")

def excluir():
    nome = input("Digite o nome de quem deseja excluir: ")
    if nome in listaNomes:

        i = listaNomes.index(nome)
        printar(i),
        print("\n     ---------Excluido com sucesso---------\n")
        listaNomes.pop(i)
        listaIdades.pop(i)
        listaNascimento.pop(i)
    else:
        print("Nome nao localizado")

#Funçao para printar dados completos
def printar(i):
    print(f"Nome: {listaNomes[i]}, Idade: {listaIdades[i]}, Data de nascimento: {listaNascimento[i]}\n", end="")

#PROGRAMA PRINCIPAL

while True:
    escolha = menu()
    if escolha == '0':
        break
    elif escolha == '1':
        cadastro()
    elif escolha == '2':
        listarNomes()
    elif escolha == '3':
        listarDados()
    elif escolha == '4':
        localizarDados()
    elif escolha == '5':
        attDado()
    elif escolha == '6':
        excluir()


#!/usr/bin/env python3
import sys
sys.setrecursionlimit(10000)

def paco(data, base):
  N, M, X, K, XCa,YCa, XCo,YCo = data
  dst = (XCo-1, YCo-1)
  thr = int(X*K/2)
  themap = [base[i*M:(i+1)*M] for i in range(N)]

  def trace(path):
    return sum(themap[x][y] for x,y in path)

  invalid = (M*N+1,6666)
  cache = [invalid for x in base]
  def visit(x,y, length=0, risk=0):
    idx = x+N*y
    # out of map
    if not (0 <= x < N and 0 <= y < M):
      return invalid
    # too brigh square
    k = base[idx]
    if k > K:
      return invalid
    risk += k
    # area already cached
    if cache[idx] < (length, risk):
      return invalid
    cache[idx] = (length, risk)
    if (x,y) == dst:
      print("dst", length, risk)
      return length, risk
    r = min(visit(x+1, y, length+1, risk),
            visit(x-1, y, length+1, risk),
            visit(x,y+1, length+1, risk),
            visit(x, y-1, length+1, risk))
    return r
  print(visit(XCa-1,YCa-1))

if __name__ == '__main__':
  data = [4,4,3,7,1,1,4,4]
  base = [1,1,4,4,0,4,4,4,7,3,2,3,14,9,8,3]
  from pacodata import data, base
  #data = [2,2, 10, 10, 1,1, 2,2]
  #base = [0,0,0,0]
  paco(data, base)


from server.db.db import db
from server.db.domain import Organisation, CollaborationRequest, CollaborationMembership, Collaboration
from server.test.abstract_test import AbstractTest
from server.test.seed import schac_home_organisation, amsterdam_uva_name, collaboration_request_name, uuc_name, \
    schac_home_organisation_uuc

class TestCollaborationRequest(AbstractTest):

    def test_collaboration_request_by_id(self):
        collaboration_request = self.find_entity_by_name(CollaborationRequest, collaboration_request_name)
        res = self.get(f"/api/collaboration_requests/{collaboration_request.id}")

        self.assertEqual("urn:peter", res["requester"]["uid"])
        self.assertEqual(uuc_name, res["organisation"]["name"])

    def test_request_collaboration(self):
        organisation = self.find_entity_by_name(Organisation, amsterdam_uva_name)
        self.login("urn:roger", schac_home_organisation)
        data = {
            "name": "New Collaboration",
            "short_name": "new_collaboration_short",
            "message": "pretty please",
            "organisation_id": organisation.id
        }
        with self.app.mail.record_messages() as outbox:
            res = self.post("/api/collaboration_requests", body=data, with_basic_auth=False)
            collaboration_request = db.session.get(CollaborationRequest, res["id"])
            self.assertEqual("urn:roger", collaboration_request.requester.uid)
            mail_msg = outbox[0]
            self.assertEqual("Request for new collaboration New Collaboration (local)", mail_msg.subject)

    def test_request_collaboration_collaboration_creation_allowed(self):
        self.login("urn:roger", schac_home_organisation_uuc)
        organisation = self.find_entity_by_name(Organisation, uuc_name)
        data = {
            "name": "New Collaboration",
            "description": "new_collaboration",
            "short_name": "new_COLLABORATION_short_but_still_to_long_for_not_getting_trimmed",
            "message": "pretty please",
            "organisation_id": organisation.id
        }
        with self.app.mail.record_messages() as outbox:
            self.post("/api/collaboration_requests", body=data, with_basic_auth=False)
            collaboration = self.find_entity_by_name(Collaboration, data["name"])
            # Max length short_name
            self.assertEqual("new_collaboratio", collaboration.short_name)
            mail_msg = outbox[0]
            organisation = self.find_entity_by_name(Organisation, uuc_name)
            self.assertEqual(f"New collaboration {collaboration.name} created in {organisation.name} (local)", mail_msg.subject)
            self.assertTrue("automatically approve collaboration requests" in mail_msg.html)

    def test_request_collaboration_collaboration_creation_allowed_entitlement(self):
        self.login("urn:harry",
                   schac_home_organisation,
                   {"eduperson_entitlement": ["urn:example:sbs:allow-create-co"]})
        organisation = self.find_entity_by_name(Organisation, amsterdam_uva_name)
        data = {
            "name": "New Collaboration",
            "description": "new_collaboration",
            "short_name": "NEW_COLLABORATION_SHORT",
            "message": "pretty please",
            "organisation_id": organisation.id
        }
        with self.app.mail.record_messages() as outbox:
            self.post("/api/collaboration_requests", body=data, with_basic_auth=False)
            collaboration = self.find_entity_by_name(Collaboration, data["name"])

            self.assertEqual("new_collaboratio", collaboration.short_name)
            mail_msg = outbox[0]
            organisation = self.find_entity_by_name(Organisation, amsterdam_uva_name)
            self.assertEqual(f"New collaboration {collaboration.name} created in {organisation.name} (local)", mail_msg.subject)

    def test_request_collaboration_no_schachome(self):
        self.login("urn:user_suspend_warning", schac_home_organisation=None)
        self.post("/api/collaboration_requests", body={}, response_status_code=400, with_basic_auth=False)

    def test_request_collaboration_approve(self):
        collaboration_request = self.find_entity_by_name(CollaborationRequest, collaboration_request_name)
        collaboration_request_requester_uid = collaboration_request.requester.uid
        with self.app.mail.record_messages() as outbox:
            self.login("urn:mary")
            res = self.put(f"/api/collaboration_requests/approve/{collaboration_request.id}",
                           body={
                               "name": collaboration_request.name,
                               "description": "new_collaboration",
                               "short_name": collaboration_request.short_name,
                               "organisation_id": collaboration_request.organisation_id
                           }, with_basic_auth=False)

            members = CollaborationMembership.query.filter(CollaborationMembership.collaboration_id == res["id"]).all()
            self.assertEqual(1, len(members))

            membership = members[0]
            self.assertEqual("admin", membership.role)
            self.assertEqual(collaboration_request_requester_uid, membership.user.uid)

            mail_msg = outbox[0]
            self.assertEqual("Collaboration request for collaboration New Collaboration has been accepted (local)",
                             mail_msg.subject)

    def test_request_collaboration_approve_logo_url(self):
        collaboration_request = self.find_entity_by_name(CollaborationRequest, collaboration_request_name)
        collaboration_request_id = collaboration_request.id
        res = self.get(f"/api/collaboration_requests/{collaboration_request_id}")

        self.login("urn:john")
        self.put(f"/api/collaboration_requests/approve/{collaboration_request_id}",
                       body={
                           "name": res["name"],
                           "logo": res["logo"],
                           "description": "new_collaboration",
                           "short_name": res["short_name"],
                           "organisation_id": res["organisation_id"]
                       }, with_basic_auth=False)
        collaboration_request = self.find_entity_by_name(CollaborationRequest, collaboration_request_name)
        raw_logo = collaboration_request.raw_logo()
        self.assertFalse(raw_logo.startswith("http"))

    def test_request_collaboration_deny(self):
        collaboration_request = self.find_entity_by_name(CollaborationRequest, collaboration_request_name)

        with self.app.mail.record_messages() as outbox:
            self.login("urn:mary")
            reason = "Prerogative of admins"
            self.put(f"/api/collaboration_requests/deny/{collaboration_request.id}",
                     body={"rejection_reason": reason},
                     with_basic_auth=False)

            mail_msg = outbox[0]
            self.assertEqual("Collaboration request for collaboration New Collaboration has been declined (local)",
                             mail_msg.subject)
            self.assertTrue(reason in mail_msg.html)

    def test_delete(self):
        collaboration_request = self.find_entity_by_name(CollaborationRequest, collaboration_request_name)
        self.login("urn:harry")
        self.delete("/api/collaboration_requests", primary_key=collaboration_request.id, with_basic_auth=False,
                    response_status_code=400)

    def test_delete_with_status_open(self):
        pre_count = CollaborationRequest.query.count()
        collaboration_request = self.find_entity_by_name(CollaborationRequest, collaboration_request_name)
        collaboration_request_id = collaboration_request.id
        self.login("urn:harry")
        self.put(f"/api/collaboration_requests/approve/{collaboration_request_id}",
                 body={
                     "name": collaboration_request.name,
                     "description": "new_collaboration",
                     "short_name": collaboration_request.short_name,
                     "organisation_id": collaboration_request.organisation_id
                 }, with_basic_auth=False)
        self.delete("/api/collaboration_requests", primary_key=collaboration_request_id, with_basic_auth=False)
        self.assertEqual(pre_count - 1, CollaborationRequest.query.count())


import base58
import json
import time

from Crypto.Hash import SHA3_256, SHA3_512, RIPEMD160
from Crypto.Signature import PKCS1_v1_5

from transaction import Transaction, TransactionMerkleTree
from wallet import Wallet

class Block:
    def __init__(self, index, transactions, timestamp, previous_hash, nonce=0):
        self.index = index
        self.transactions = None
        if len(transactions) > 0:
            TransactionMerkleTree(transactions)
        self.timestamp = timestamp
        self.previous_hash = previous_hash
        self.nonce = nonce

    def __str__(self):
        return str(self.__dict__)

    def compute_hash(self):
        block_string = json.dumps(self, sort_keys=True, cls=Block.MyJsonEncoder)
        return SHA3_512.new(block_string.encode()).hexdigest()

    class MyJsonEncoder(json.JSONEncoder):
        def default(self, o):
            return o.__dict__

class Blockchain:
    def __init__(self, difficulty=3):
        self.unconfirmed_transactions = []
        self.chain = []
        self.create_genesis_block()
        self.difficulty = difficulty

    def __str__(self):
        return str([str(x) for x in self.chain])

    def create_genesis_block(self):
        genesis_block = Block(0, [], time.time(), "0")
        genesis_block.hash = genesis_block.compute_hash()
        self.chain.append(genesis_block)

    @property
    def last_block(self):
        return self.chain[-1]

    def proof_of_work(self, block):
        block.nonce = 0
        computed_hash = block.compute_hash()
        while not computed_hash.startswith('0' * self.difficulty):
            block.nonce += 1
            computed_hash = block.compute_hash()
        return computed_hash

    def is_valid_proof(self, block, block_hash):
        return (block_hash.startswith('0' * self.difficulty) and
                block_hash == block.compute_hash())

    def add_block(self, block, proof):
        previous_hash = self.last_block.hash
        if previous_hash != block.previous_hash:
            return False
        if not self.is_valid_proof(block, proof):
            return False
        block.hash = proof
        self.chain.append(block)
        return True

    def add_new_transaction(self, public_key, signed_transaction):
        try:
            Blockchain.validate_signature(public_key, signed_transaction)
        except AddressKeyMismatch:
            print("Wrong key")
        except ValueError:
            print("Invalid Signature")
        else:
            self.unconfirmed_transactions.append(signed_transaction)

    def mine(self):
        if not self.unconfirmed_transactions:
            return False
        last_block = self.last_block
        new_block = Block(index=last_block.index + 1,
                          transactions=self.unconfirmed_transactions,
                          timestamp=time.time(),
                          previous_hash=last_block.hash)
        proof = self.proof_of_work(new_block)
        self.add_block(new_block, proof)
        self.unconfirmed_transactions = []
        return new_block.index

    @staticmethod
    def validate_signature(public_key, signed_transaction):
        address = public_key
        h = RIPEMD160.new(SHA3_256.new(public_key.export_key()).hexdigest().encode())
        address = base58.b58encode(h.hexdigest()).decode("utf-8")
        if address != signed_transaction.transaction.sender:
            raise AddressKeyMismatch
        PKCS1_v1_5.new(public_key).verify(signed_transaction.transaction.compute_hash(), signed_transaction.signature)

class AddressKeyMismatch(Exception):
    pass

if __name__ == '__main__':
    wallet1 = Wallet()
    wallet2 = Wallet()

    wallet1.generate_new_wallet()
    wallet1.save_wallet()
    wallet2.generate_new_wallet()
    myBlockchain = Blockchain(difficulty=4)

    myTransaction01 = Transaction(wallet1.address, wallet2.address, 10.05)
    mySignedTransaction01 = myTransaction01.sign(wallet1.private_key)
    myBlockchain.add_new_transaction(wallet1.public_key, mySignedTransaction01)

    myTransaction02 = Transaction(wallet1.address, wallet2.address, 22.40)
    mySignedTransaction02 = myTransaction02.sign(wallet1.private_key)
    myBlockchain.add_new_transaction(wallet1.public_key, mySignedTransaction02)

    myTransaction03 = Transaction(wallet1.address, wallet2.address, 11.55)
    mySignedTransaction03 = myTransaction03.sign(wallet1.private_key)
    myBlockchain.add_new_transaction(wallet1.public_key, mySignedTransaction03)

    myTransaction04 = Transaction(wallet1.address, wallet2.address, 100.05)
    mySignedTransaction04 = myTransaction04.sign(wallet1.private_key)
    myBlockchain.add_new_transaction(wallet1.public_key, mySignedTransaction04)

    myBlockchain.mine()
    print(myBlockchain)


import yaml
import logging

settings = dict()

log_levels = {
    'DEBUG': logging.DEBUG,
    'INFO': logging.INFO,
    'WARNING': logging.WARNING,
    'ERROR': logging.ERROR,
    'CRITICAL': logging.CRITICAL,
}

with open("../config.yaml", 'r') as stream:
    try:
        settings = yaml.safe_load(stream)
        settings['log_level'] = log_levels[settings['log_level']]
    except yaml.YAMLError as exc:
        print(exc)


import numpy as np

import backend
import nn

class Model(object):
    """Base model class for the different applications"""
    def __init__(self):
        self.get_data_and_monitor = None
        self.learning_rate = 0.0

    def run(self, x, y=None):
        raise NotImplementedError("Model.run must be overriden by subclasses")

    def train(self):
        """
        Train the model.

        `get_data_and_monitor` will yield data points one at a time. In between
        yielding data points, it will also monitor performance, draw graphics,
        and assist with automated grading. The model (self) is passed as an
        argument to `get_data_and_monitor`, which allows the monitoring code to
        evaluate the model on examples from the validation set.
        """
        for x, y in self.get_data_and_monitor(self):
            graph = self.run(x, y)
            graph.backprop()
            graph.step(self.learning_rate)

class RegressionModel(Model):
    """
    A neural network model for approximating a function that maps from real
    numbers to real numbers. The network should be sufficiently large to be able
    to approximate sin(x) on the interval [-2pi, 2pi] to reasonable precision.
    """
    def __init__(self):
        Model.__init__(self)
        self.get_data_and_monitor = backend.get_data_and_monitor_regression

        # Remember to set self.learning_rate!
        # You may use any learning rate that works well for your architecture
        "*** YOUR CODE HERE ***"
        self.learning_rate = .01
        self.w1 = []
        self.w2 = []
        self.b1 = []
        self.b2 = []

    def run(self, x, y=None):
        """
        Runs the model for a batch of examples.

        The correct outputs `y` are known during training, but not at test time.
        If correct outputs `y` are provided, this method must construct and
        return a nn.Graph for computing the training loss. If `y` is None, this
        method must instead return predicted y-values.

        Inputs:
            x: a (batch_size x 1) numpy array
            y: a (batch_size x 1) numpy array, or None
        Output:
            (if y is not None) A nn.Graph instance, where the last added node is
                the loss
            (if y is None) A (batch_size x 1) numpy array of predicted y-values

        Note: DO NOT call backprop() or step() inside this method!
        """
        "*** YOUR CODE HERE ***"

        #function nodes are, multiply, add vector, relu, matrix multiply, add vector
        #variables are w1, w2, b1, b2
        #size of the input vector
        i = x.shape[1]
        #to test and modify
        h = 100

        if not self.w1:
            self.w1 = nn.Variable(i, h)
        if not self.w2:
            self.w2 = nn.Variable(h, i)
        if not self.b1:
            self.b1 = nn.Variable(h)
        if not self.b2:
            self.b2 = nn.Variable(i)

        graph = nn.Graph([self.w1, self.w2, self.b1, self.b2])

        input_nodeX = nn.Input(graph, x)
        # print x.shape

        # xm = MatrixMultiply(graph, input_x, m)
        # xm_plus_b = MatrixVectorAdd(graph, xm, b)

        multiply1 = nn.MatrixMultiply(graph, input_nodeX, self.w1)
        add1 = nn.MatrixVectorAdd(graph, multiply1, self.b1)
        relu = nn.ReLU(graph, add1)
        multiply2 = nn.MatrixMultiply(graph, relu, self.w2)
        add2 = nn.MatrixVectorAdd(graph, multiply2, self.b2)

        if y is not None:
            # At training time, the correct output `y` is known.
            # Here, you should construct a loss node, and return the nn.Graph
            # that the node belongs to. The loss node must be the last node
            # added to the graph.
            input_nodeY = nn.Input(graph, y)
            loss_node = nn.SquareLoss(graph, add2, input_nodeY)
            graph.add(loss_node)

            return graph

            "*** YOUR CODE HERE ***"
        else:
            return graph.get_output(add2)
            # At test time, the correct output is unknown.
            # You should instead return your model's prediction as a numpy array
            "*** YOUR CODE HERE ***"

class OddRegressionModel(Model):
    """
    A neural network model for approximating a function that maps from real
    numbers to real numbers.

    Unlike RegressionModel, the OddRegressionModel must be structurally
    constrained to represent an odd function, i.e. it must always satisfy the
    property f(x) = -f(-x) at all points during training.
    """
    def __init__(self):
        Model.__init__(self)
        self.get_data_and_monitor = backend.get_data_and_monitor_regression

        # Remember to set self.learning_rate!
        # You may use any learning rate that works well for your architecture
        "*** YOUR CODE HERE ***"
        self.learning_rate = .01
        self.w1 = []
        self.w2 = []
        self.b1 = []
        self.b2 = []
    def run(self, x, y=None):
        """
        Runs the model for a batch of examples.

        The correct outputs `y` are known during training, but not at test time.
        If correct outputs `y` are provided, this method must construct and
        return a nn.Graph for computing the training loss. If `y` is None, this
        method must instead return predicted y-values.

        Inputs:
            x: a (batch_size x 1) numpy array
            y: a (batch_size x 1) numpy array, or None
        Output:
            (if y is not None) A nn.Graph instance, where the last added node is
                the loss
            (if y is None) A (batch_size x 1) numpy array of predicted y-values

        Note: DO NOT call backprop() or step() inside this method!
        """
        "*** YOUR CODE HERE ***"

        #function nodes are, multiply, add vector, relu, matrix multiply, add vector
        #variables are w1, w2, b1, b2
        #size of the input vector
        i = x.shape[1]
        #to test and modify
        h = 100

        if not self.w1:
            self.w1 = nn.Variable(i, h)
        if not self.w2:
            self.w2 = nn.Variable(h, i)
        if not self.b1:
            self.b1 = nn.Variable(h)
        if not self.b2:
            self.b2 = nn.Variable(i)

        graph = nn.Graph([self.w1, self.w2, self.b1, self.b2])

        input_nodeX = nn.Input(graph, x)
        neg_X = np.negative(x)
        neg_inputX = nn.Input(graph, neg_X)
        # print x.shape

        # xm = MatrixMultiply(graph, input_x, m)
        # xm_plus_b = MatrixVectorAdd(graph, xm, b)

        multiply1 = nn.MatrixMultiply(graph, input_nodeX, self.w1)
        add1 = nn.MatrixVectorAdd(graph, multiply1, self.b1)
        relu = nn.ReLU(graph, add1)
        multiply2 = nn.MatrixMultiply(graph, relu, self.w2)
        add2 = nn.MatrixVectorAdd(graph, multiply2, self.b2)

        #for the f(-x)
        neg_multiply1 = nn.MatrixMultiply(graph, neg_inputX, self.w1)
        neg_add1 = nn.MatrixVectorAdd(graph, neg_multiply1, self.b1)
        neg_relu = nn.ReLU(graph, neg_add1)
        neg_multiply2 = nn.MatrixMultiply(graph, neg_relu, self.w2)
        neg_add2 = nn.MatrixVectorAdd(graph, neg_multiply2, self.b2)

        ones = np.ones((1, 1))
        ones = np.negative(ones)
        neg_one = nn.Input(graph, ones)

        neg_negate = nn.MatrixMultiply(graph, neg_add2, neg_one)

        final_add = nn.Add(graph,neg_negate, add2)

        if y is not None:
            # At training time, the correct output `y` is known.
            # Here, you should construct a loss node, and return the nn.Graph
            # that the node belongs to. The loss node must be the last node
            # added to the graph.
            input_nodeY = nn.Input(graph, y)
            loss_node = nn.SquareLoss(graph, final_add, input_nodeY)
            graph.add(loss_node)

            return graph

            "*** YOUR CODE HERE ***"
        else:
            # print graph.get_output(add2).shape
            return graph.get_output(final_add)
            # At test time, the correct output is unknown.
            # You should instead return your model's prediction as a numpy array
            "*** YOUR CODE HERE ***"

class DigitClassificationModel(Model):
    """
    A model for handwritten digit classification using the MNIST dataset.

    Each handwritten digit is a 28x28 pixel grayscale image, which is flattened
    into a 784-dimensional vector for the purposes of this model. Each entry in
    the vector is a floating point number between 0 and 1.

    The goal is to sort each digit into one of 10 classes (number 0 through 9).

    (See RegressionModel for more information about the APIs of different
    methods here. We recommend that you implement the RegressionModel before
    working on this part of the project.)
    """
    def __init__(self):
        Model.__init__(self)
        self.get_data_and_monitor = backend.get_data_and_monitor_digit_classification

        # Remember to set self.learning_rate!
        # You may use any learning rate that works well for your architecture
        self.learning_rate = .3
        self.w1 = []
        self.w2 = []
        self.b1 = []
        self.b2 = []

    def run(self, x, y=None):
        """
        Runs the model for a batch of examples.

        The correct labels are known during training, but not at test time.
        When correct labels are available, `y` is a (batch_size x 10) numpy
        array. Each row in the array is a one-hot vector encoding the correct
        class.

        Your model should predict a (batch_size x 10) numpy array of scores,
        where higher scores correspond to greater probability of the image
        belonging to a particular class. You should use `nn.SoftmaxLoss` as your
        training loss.

        Inputs:
            x: a (batch_size x 784) numpy array
            y: a (batch_size x 10) numpy array, or None
        Output:
            (if y is not None) A nn.Graph instance, where the last added node is
                the loss
            (if y is None) A (batch_size x 10) numpy array of scores (aka logits)
        """
        i = x.shape[1]
        # j = x.shape[0]
        #to test and modify
        h = 200

        if not self.w1:
            self.w1 = nn.Variable(i, h)
        if not self.w2:
            self.w2 = nn.Variable(h, 10)
        if not self.b1:
            self.b1 = nn.Variable(h)
        if not self.b2:
            self.b2 = nn.Variable(10)

        graph = nn.Graph([self.w1, self.w2, self.b1, self.b2])

        input_nodeX = nn.Input(graph, x)
        multiply1 = nn.MatrixMultiply(graph, input_nodeX, self.w1)
        add1 = nn.MatrixVectorAdd(graph, multiply1, self.b1)
        relu = nn.ReLU(graph, add1)
        multiply2 = nn.MatrixMultiply(graph, relu, self.w2)
        add2 = nn.MatrixVectorAdd(graph, multiply2, self.b2)

        if y is not None:
            # At training time, the correct output `y` is known.
            # Here, you should construct a loss node, and return the nn.Graph
            # that the node belongs to. The loss node must be the last node
            # added to the graph.
            input_nodeY = nn.Input(graph, y)
            loss_node = nn.SoftmaxLoss(graph, add2, input_nodeY)
            graph.add(loss_node)

            return graph

            "*** YOUR CODE HERE ***"
        else:
            # print graph.get_output(add2).shape
            return graph.get_output(add2)
            # At test time, the correct output is unknown.
            # You should instead return your model's prediction as a numpy array
            "*** YOUR CODE HERE ***"

class DeepQModel(Model):
    """
    A model that uses a Deep Q-value Network (DQN) to approximate Q(s,a) as part
    of reinforcement learning.

    (We recommend that you implement the RegressionModel before working on this
    part of the project.)
    """
    def __init__(self):
        Model.__init__(self)
        self.get_data_and_monitor = backend.get_data_and_monitor_rl

        self.num_actions = 2
        self.state_size = 4

        # Remember to set self.learning_rate!
        # You may use any learning rate that works well for your architecture
        self.learning_rate = .01
        self.w1 = []
        self.w2 = []
        self.b1 = []
        self.b2 = []

    def run(self, states, Q_target=None):
        """
        Runs the DQN for a batch of states.

        The DQN takes the state and computes Q-values for all possible actions
        that can be taken. That is, if there are two actions, the network takes
        as input the state s and computes the vector [Q(s, a_1), Q(s, a_2)]

        When Q_target == None, return the matrix of Q-values currently computed
        by the network for the input states.

        When Q_target is passed, it will contain the Q-values which the network
        should be producing for the current states. You must return a nn.Graph
        which computes the training loss between your current Q-value
        predictions and these target values, using nn.SquareLoss.

        Inputs:
            states: a (batch_size x 4) numpy array
            Q_target: a (batch_size x 2) numpy array, or None
        Output:
            (if Q_target is not None) A nn.Graph instance, where the last added
                node is the loss
            (if Q_target is None) A (batch_size x 2) numpy array of Q-value
                scores, for the two actions
        """
        "*** YOUR CODE HERE ***"
        #size of the input vector
        i = states.shape[1] * 4
        #to test and modify
        h = 200

        if not self.w1:
            self.w1 = nn.Variable(self.state_size, h)
        if not self.w2:
            self.w2 = nn.Variable(h, self.num_actions)
        if not self.b1:
            self.b1 = nn.Variable(h)
        if not self.b2:
            self.b2 = nn.Variable(self.num_actions)

        graph = nn.Graph([self.w1, self.w2, self.b1, self.b2])

        inputNodeX = nn.Input(graph, states)

        mult1 = nn.MatrixMultiply(graph, inputNodeX, self.w1)
        add1 = nn.MatrixVectorAdd(graph, mult1, self.b1)
        relu = nn.ReLU(graph, add1)
        mult2 = nn.MatrixMultiply(graph, relu, self.w2)
        add2 = nn.MatrixVectorAdd(graph, mult2, self.b2)

        if Q_target is not None:
            inputNodeY = nn.Input(graph, Q_target)
            lossNode = nn.SquareLoss(graph, add2, inputNodeY)
            graph.add(lossNode)
            # print("q target is not none")
            return graph
        else:
            # return [get_action(state, .5),
            # print("q target is none")
            return graph.get_output(add2)

    def get_action(self, state, eps):
        """
        Select an action for a single state using epsilon-greedy.

        Inputs:
            state: a (1 x 4) numpy array
            eps: a float, epsilon to use in epsilon greedy
        Output:
            the index of the action to take (either 0 or 1, for 2 actions)
        """
        if np.random.rand() < eps:
            return np.random.choice(self.num_actions)
        else:
            scores = self.run(state)
            return int(np.argmax(scores))

class LanguageIDModel(Model):
    """
    A model for language identification at a single-word granularity.

    (See RegressionModel for more information about the APIs of different
    methods here. We recommend that you implement the RegressionModel before
    working on this part of the project.)
    """
    def __init__(self):
        Model.__init__(self)
        self.get_data_and_monitor = backend.get_data_and_monitor_lang_id

        # Our dataset contains words from five different languages, and the
        # combined alphabets of the five languages contain a total of 47 unique
        # characters.
        # You can refer to self.num_chars or len(self.languages) in your code
        self.num_chars = 47
        self.languages = ["English", "Spanish", "Finnish", "Dutch", "Polish"]

        # Remember to set self.learning_rate!
        # You may use any learning rate that works well for your architecture
        "*** YOUR CODE HERE ***"
        self.learning_rate = .007
        self.w1 = []
        self.w2 = []
        self.w3 = []
        self.b1 = []
        self.output = []
        self.hidden_size = 0
        c = self.num_chars

        #size of the input vector
        # i = x.shape[1]
        #to test and modify
        d = 160

        if not self.w1:
            self.w1 = nn.Variable(d, c)
        if not self.w2:
            self.w2 = nn.Variable(c, c)
        if not self.w3:
            self.w3 = nn.Variable(c, d)
        if not self.b1:
            self.b1 = nn.Variable(d)
        if not self.output:
            self.output = nn.Variable(d, 5)

        graph = nn.Graph([self.w1, self.w2, self.w3, self.b1, self.output])
        h0 = np.zeros((batch_size, d), dtype = np.float)

        input_nodeH = nn.Input(graph, h0)
        # print x.shape
        #array of zeros

        # multiply1 = nn.MatrixMultiply(graph, input_nodeX, self.w1)
        # add1 = nn.MatrixVectorAdd(graph, multiply1, self.b1)
        # relu = nn.ReLU(graph, add1)
        # multiply2 = nn.MatrixMultiply(graph, relu, self.w2)
        # add2 = nn.MatrixVectorAdd(graph, multiply2, self.b2)
        i = 0
        while i < len(xs):
            input_nodeC = nn.Input(graph, xs[i])
            multiply1 = nn.MatrixMultiply(graph, input_nodeH, self.w1)
            multiply2 = nn.MatrixMultiply(graph, input_nodeC, self.w2)
            combine = nn.MatrixVectorAdd(graph, multiply1, multiply2)
            multiply3 = nn.MatrixMultiply(graph, combine, self.w3)
            add1 = nn.MatrixVectorAdd(graph, multiply3, self.b1)
            relu = nn.ReLU(graph, add1)
            input_nodeH = relu
            i = i + 1
        final = nn.MatrixMultiply(graph, relu, self.output)
        if y is not None:
            # At training time, the correct output `y` is known.
            # Here, you should construct a loss node, and return the nn.Graph
            # that the node belongs to. The loss node must be the last node
            # added to the graph.
            input_nodeY = nn.Input(graph, y)
            loss_node = nn.SoftmaxLoss(graph, final, input_nodeY)
            graph.add(loss_node)

            return graph

            "*** YOUR CODE HERE ***"
        else:
            # print graph.get_output(add2).shape
            return graph.get_output(final)
            # At test time, the correct output is unknown.
            # You should instead return your model's prediction as a numpy array
            "*** YOUR CODE HERE ***"