"""
Class for reading and writing CSV files in MAG format.
"""

import csv
from csv import QUOTE_NONE
import logging

import numpy
import pandas
from scipy import sparse

import wsdmcup.logging as wsdmlog

__author__ = 'damirah'
__email__ = 'damirah@live.com'

class Mag(object):
    """
    CSV dialect class with settings for reading and writing
    the Microsoft Academic Graph TSV files.
    When creating a CSV reader of writer, pass this
    to the reader/writer as dialect= parameter.
    E.g.
    from wsdmcup.data.csv_dialect import Mag
    csv_reader = csv.reader(file_path, dialect=Mag)
    """
    delimiter = '\t'
    quotechar = None
    escapechar = None
    doublequote = False
    skipinitialspace = False
    lineterminator = '\n'
    quoting = QUOTE_NONE

class CsvDatastore(object):
    """
    Class for reading MAG data files
    """

    def __init__(self):
        self.logger = logging.getLogger(__name__)

    def read_csv(self, csv_path):
        """
        Read CSV (TSV) using MAG dialect
        :param csv_path: path to CSV to be read
        :return: generator
        """
        self.logger.info('Reading file %s', csv_path)
        with open(csv_path, 'r') as csv_file:
            csv_reader = csv.reader(csv_file, dialect=Mag)
            for csv_row in csv_reader:
                yield csv_row

    def load_dataframe(self, fpath, index_cols):
        """
        Load DataFrame from specified CSV file
        :param fpath: path to the file to be loaded
        :param index_cols: list of indexes of columns to be used as index
        :return: pandas.DataFrame
        """
        return pandas.DataFrame.from_csv(fpath, sep=Mag.delimiter,
                                         index_col=index_cols)

    def store_dataframe(self, data, fpath, columns):
        """
        Store pandas DataFrame in CSV in temp_files directory
        :param data: the data frame to be stored
        :param fpath: path to the output CSV file
        :param columns: which columns to store in the file
        :return: None
        """
        self.logger.info('Storing DataFrame in %s', fpath)
        data.to_csv(fpath, sep=Mag.delimiter, columns=columns, header=True,
                    index=True, line_terminator=Mag.lineterminator,
                    quoting=Mag.quoting)

    def store_results(self, data, fpath, columns):
        """
        Store DataFrame in results format
        :param data: pandas.DataFrame
        :param fpath:
        :param columns:
        :return:
        """
        self.logger.info('Storing results in %s', fpath)
        data.to_csv(fpath, sep=Mag.delimiter, header=False, index=False,
                    float_format='%.5e', columns=columns,
                    line_terminator=Mag.lineterminator, quoting=Mag.quoting,
                    quotechar=Mag.quotechar, doublequote=Mag.doublequote,
                    escapechar=Mag.escapechar)

    def csv_to_dataframe(self, csv_path, csv_mapping, load_cols,
                         index_col, id_col):
        """
        Load MAG TSV file into DataFrame
        :param csv_path:
        :param csv_mapping:
        :param load_cols:
        :param index_col:
        :param id_col:
        :return: pandas.DataFrame
        """
        self.logger.info('Loading data from %s', csv_path)
        self.logger.debug('Columns to be loaded: %s', load_cols)

        # for printing progress
        processed = 0
        self.logger.debug('Checking the number of rows to be loaded')
        total = wsdmlog.get_total(csv_path)
        self.logger.debug('Total: %s', total)
        how_often = wsdmlog.how_often(total)

        data = []
        self.logger.info('Processing CSV')
        for csv_row in self.read_csv(csv_path):
            data.append({col: csv_row[csv_mapping[col].value]
                         if csv_row[csv_mapping[col].value].isdigit() or
                            not csv_row[csv_mapping[col].value]
                         else csv_row[csv_mapping[col].value].encode()
                         for col in load_cols})
            processed += 1
            if processed % how_often == 0:
                self.logger.debug(wsdmlog.get_progress(processed, total))

        self.logger.info('Converting to DataFrame')
        df = pandas.DataFrame(data)

        self.logger.info('Adding index to DataFrame')
        df[index_col] = df.index
        df.index = [numpy.array(df[id_col]), numpy.array(df[index_col])]
        df.index.names = [id_col, index_col]
        self.logger.info('Indexing done')
        return df

    def csv_to_relation_matrix(self, fpath, row_id_csv_col, row_map,
                               col_id_csv_col, col_map,
                               data_csv_col=None, data_map=None):
        """
        Build authorship matrix from list of edges in PaperReferences.txt file
        :return: scipy.sparse.csr_matrix
        """
        self.logger.info('Got list of %s row indices and %s column indices',
                         len(row_map), len(col_map))

        # for updating progress
        processed = 0
        self.logger.debug('Checking the number of rows to be loaded')
        total = wsdmlog.get_total(fpath)
        self.logger.debug('Total: %s', total)
        how_often = wsdmlog.how_often(total)

        append_data = data_csv_col is not None

        row_indices = []
        col_indices = []
        data = []

        self.logger.info('Loading data from %s', fpath)
        for line in self.read_csv(fpath):
            row_id = line[row_id_csv_col]
            col_id = line[col_id_csv_col]
            if not row_id or not col_id:
                processed += 1
                if processed % how_often == 0:
                    self.logger.debug(wsdmlog.get_progress(processed, total))
                continue

            # appending data ===================================================

            if append_data:
                data_value = line[data_csv_col]
                if not data_value:
                    processed += 1
                    if processed % how_often == 0:
                        self.logger.debug(
                            wsdmlog.get_progress(processed, total))
                    continue
                if data_map:
                    data.append(data_map[data_value])
                else:
                    data.append(data_value)

            # not appending data ===============================================

            else:
                data.append(1)

            # both cases =======================================================

            row_indices.append(row_map[row_id])
            col_indices.append(col_map[col_id])
            processed += 1
            if processed % how_often == 0:
                self.logger.debug(wsdmlog.get_progress(processed, total))

        self.logger.info('Loaded {0}, {1} references'
                         .format(len(row_indices), len(col_indices)))
        self.logger.info('Constructing sparse matrix from the reference list')
        rel_matrix = sparse.coo_matrix((data, (row_indices, col_indices)),
                                       shape=(len(row_map), len(col_map)),
                                       dtype=numpy.uint32)
        self.logger.info('Relation matrix filled!')
        self.logger.debug('Number of items %s', rel_matrix.nnz)
        self.logger.info('Converting to CSR format')
        csr_m = rel_matrix.tocsr()
        # the previous line makes a copy, so for saving memory
        del rel_matrix
        self.logger.info('Done converting')
        return csr_m


def eqa(n):
    ones_counter = 0
    zeros_counter = 0

    for i in range(len(n)):
        if n[i] == "1":
            ones_counter += 1
        else:
            zeros_counter += 1

    if ones_counter == zeros_counter:
        return True

    return False

def main():
    n = input()
    if eqa(n):
        print("si")
    else:
        print("no")

if __name__ == "__main__":
    main()


#!/usr/bin/python
import psycopg2 as psql

def create_tables():
    """ create tables in the PostgreSQL database"""
    commands = (
        """
        DROP TABLE users CASCADE;
        """,
        """
        DROP TABLE items;
        """,
        """
        CREATE TABLE users (
            user_id SERIAL PRIMARY KEY,
            username VARCHAR(16) NOT NULL,
            user_type INTEGER NOT NULL,
            password_hash VARCHAR,
            token VARCHAR
        );
        """,
        """
        CREATE TABLE items (
            item_id SERIAL PRIMARY KEY,
            item_name TEXT NOT NULL,
            item_desc TEXT NOT NULL,
            item_image TEXT NOT NULL,
            poster_id INTEGER REFERENCES users(user_id)
        );
        """)
    conn = None
    try:
        connection = psql.connect("dbname=item_catalog")
        # connect to the PostgreSQL server
        cur = connection.cursor()
        # create table one by one
        for command in commands:
            cur.execute(command)
        # close communication with the PostgreSQL database server
        cur.close()
        # commit the changes
        connection.commit()
    except (Exception, psql.DatabaseError) as error:
        print(error)
    finally:
        if conn is not None:
            conn.close()

if __name__ == "__main__":
    create_tables()


# -*- coding: utf-8 -*-
# __author__ = 'zoujiaxun'

"""表格筛选"""

import os
from biocluster.workflow import Workflow
import datetime
import unittest
import types
from bson.objectid import ObjectId
import pandas as pd

class HclusterWorkflow(Workflow):
    """
    处理表格
    """
    def __init__(self, wsheet_object):
        self._sheet = wsheet_object
        super(HclusterWorkflow, self).__init__(wsheet_object)
        options = [
            {"name": "method", "type": "string", "default": "bray_curtis"},
            {"name": "otutable", "type": "infile",
             "format": "meta.otu.otu_table"},
            {"name": "linkage", "type": 'string', "default": "average"},
            {"name": "group", "type": 'infile', "format": "ref_rna_v2.common"},
            {"name": "sep", "type": 'string', "default": "tab"},
            {'name': 'main_title', 'type': 'string'},
            {'name': 'main_id', 'type': 'string'},
            {'name': 'update_info', 'type': 'string'}
        ]
        self.add_option(options)
        self.revise_infiles()
        # self.tool = self.add_tool("tool_lab.table_standard")
        self.set_options(self._sheet.options())

    def run(self):
        self.run_hcluster()
        super(HclusterWorkflow, self).run()

    def run_hcluster(self):

        self.hcluster = self.add_module('tool_lab.hcluster')

        self.hcluster.set_options({
            "method": self.option("method").lower(),
            "otutable": self.option("otutable"),
            "linkage": self.option('linkage').lower(),
            "sep": self.option('sep')
        })
        self.hcluster.on('end', self.set_db)
        self.hcluster.run()

    def set_db(self):
        """
        保存结果表到mongo数据库中
        """

        hcluster = self.api.api("tool_lab.hcluster")
        # add result info
        hcluster_tre = os.path.join(self.hcluster.output_dir, 'hcluster.tre')
        hcluster.add_hcluster(hcluster_tre, self.option('group').path, main_id=self.option('main_id'), main_title=self.option('main_title'))
        self.set_output()
        self.end()
    # def set_db(self):
    #     """
    #     保存结果标准化数据到mongo数据库中
    #     """
    #     # record_id = self.option("standard_id")
    #     # if isinstance(record_id, types.StringTypes):
    #     #     record_id = ObjectId(record_id)
    #     # elif isinstance(record_id, ObjectId):
    #     #     record_id = record_id
    #     # else:
    #     #     self.set_error("main_id参数必须为字符串或者ObjectId类型!", code="13701601")
    #     standard = self.api.api("tool_lab.table_kit")
    #     # add result info
    #     print self.option('transposed_table').path
    #     standard.add_table_standard()
    #     self.end()

    def end(self):
        result_dir = self.add_upload_dir(self.output_dir)
        result_dir.add_relpath_rules([
             [".", "", "层级聚类文件",0],
             ["hcluster.tre", "tre", "层级聚类树文件",0],
             ["otutable.txt", "xls", "样本距离矩阵文件", 0]
        ])
        super(HclusterWorkflow, self).end()

    def set_output(self):
        for file in os.listdir(self.hcluster.output_dir):
            os.link(os.path.join(self.hcluster.output_dir, file), os.path.join(self.output_dir, file))
class TestFunction(unittest.TestCase):
    '''
    This is test for the workflow. Just run this script to do test.
    '''

    def test(self):
        from mbio.workflows.tool_lab.hcluster import HclusterWorkflow
        from biocluster.wsheet import Sheet
        import random
        data = {
            'id': 'hcluster_{}_{}'.format(random.randint(1000, 9999), random.randint(1000, 9999)),
            'type': 'workflow',
            'name': 'tool_lab.hcluster',
            'options': {
                "method" : "bray_curtis",
                "otutable" : "/mnt/ilustre/users/sanger-dev/sg-users/zoujiaxun/otutable.txt",
                "linkage" : "average",
                'group':"/mnt/ilustre/users/sanger-dev/sg-users/zoujiaxun/GROUP.txt",
                "sep": 'tab'
            }
        }
        wsheet = Sheet(data=data)
        wf =HclusterWorkflow(wsheet)
        wf.sheet.id = 'cluster'
        wf.sheet.project_sn = 'cluster'
        wf.IMPORT_REPORT_DATA = False
        wf.IMPORT_REPORT_AFTER_DATA = False
        wf.run()

if __name__ == '__main__':
    suite = unittest.TestSuite()
    suite.addTests([TestFunction('test')])
    unittest.TextTestRunner(verbosity=2).run(suite)


# coding=utf-8

# 2018-06-03 00:27
# 2018-06-03 00:29

class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        result = []
        self.helper(root, result)
        return result

    def helper(self, root, result):
        if root is None:
            return

        self.helper(root.left, result)
        result.append(root.val)
        self.helper(root.right, result)

# 2018-06-02 19:17
# 2018-06-02 19:28

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if root is None:
            return []

        ret = []
        visited = set()

        stack = [root]
        while stack:
            l = stack[-1].left
            r = stack[-1].right
            if l not in visited and l is not None:
                stack.append(l)
            else:
                ret.append(stack[-1].val)
                visited.add(stack[-1])
                stack.pop()
                if r is not None:
                    stack.append(r)

        return ret


#app.py for Homework 10 SQLAlchemy challenge
from flask import Flask, jsonify
import numpy as np

import sqlalchemy
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session
from sqlalchemy import create_engine, func

#################################################
# Database Setup
#################################################
engine = create_engine("sqlite:///Resources/hawaii.sqlite")

# reflect an existing database into a new model
Base = automap_base()
# reflect the tables
Base.prepare(engine, reflect=True)

# Save reference to the table
Measurement = Base.classes.measurement
Station=Base.classes.station

# Create our session (link) from Python to the DB
session = Session(engine)

#################################################
# Flask Setup
#################################################
app = Flask(__name__)

#Define what to do when the user hits the index route
@app.route("/")
def home():
    print("Server recieved request for 'About' page...")
    return (
        f"Welcome to my 'About' page!
"
        f"Avaliable Routes:
"
        f"/api/v1.0/precipitation
"
        f"/api/v1.0/stations
"
        f"/api/v1.0/tobs
"
        "/api/v1.0/temp/start/end"
    )

@app.route('/api/v1.0/precipitation')
def precipitation():
    print("Server recieved request for 'Precipitation' page...")
    #Convert the query results to a Dictionary using date as the key and prcp as the value.
    #Return the JSON representation of your dictionary.

    # Query all precipitation date one year from last date it the sqlite file
    lastdate_query=session.query(Measurement.date, Measurement.prcp).\
        filter(Measurement.date >= '2016-08-23').all()

    session.close()

    precipitation={date:\
         prcp for date, prcp in lastdate_query}

    return jsonify(precipitation)

@app.route('/api/v1.0/stations')
def stations():
    print("Server recieved request for 'Stations' page...")
    #Return a JSON list of stations from the dataset.
    results=session.query(Station.station).all()

    #convert to a list
    stations=list(np.ravel(results))
    return jsonify(stations)

@app.route('/api/v1.0/tobs')
def tobs():
    print("Server recieved request for 'Jobs' page...")
    #query for the dates and temperature observations from a year from the last data point.
    #Return a JSON list of Temperature Observations (tobs) for the previous year.

    results=session.query(Measurement.tobs).\
        filter(Measurement.date >= '2016-08-23').\
        filter(Measurement.station == "USC00519281").all()

    #convert to list
    temps=list(np.ravel(results))

    return jsonify(temps)

@app.route('/api/v1.0/temp/<start>')
@app.route('/api/v1.0/temp/<start>/<end>')
def tempstats(start=None, end=None):
    print("Server recieved request for 'start temp' page...")
    #Return a JSON list of the minimum temperature, the average temperature, and the max temperature for a given start or start-end range.
    #When given the start only, calculate TMIN, TAVG, and TMAX for all dates greater than and equal to the start date.
    #When given the start and the end date, calculate the TMIN, TAVG, and TMAX for dates between the start and end date inclusive.
    sel = [func.min(Measurement.tobs),\
            func.avg(Measurement.tobs),\
            func.max(Measurement.tobs)\
          ]

    #query if only given a start date
    if not end:
        results = session.query(*sel).\
            filter(Measurement.date >= start).all()
        temps = list(np.ravel(results))
        return jsonify(temps)

    #query if given a start and end date
    results = session.query(*sel).\
        filter(Measurement.date >= start).\
        filter(Measurement.date <= end).all()
    temps = list(np.ravel(results))
    return jsonify(temps)

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


import shutil
import tempfile
from django.contrib.auth import get_user_model
from django.test import Client, TestCase, override_settings
from django.urls import reverse
from django.conf import settings
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.cache import cache

from posts.models import Group, Post, Follow
from posts.forms import PostForm, Comment

User = get_user_model()

TEMP_MEDIA_ROOT = tempfile.mkdtemp(dir=settings.BASE_DIR)

@override_settings(MEDIA_ROOT=TEMP_MEDIA_ROOT)
class PostsViewsTest(TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        small_gif = (
            b'\x47\x49\x46\x38\x39\x61\x02\x00'
            b'\x01\x00\x80\x00\x00\x00\x00\x00'
            b'\xFF\xFF\xFF\x21\xF9\x04\x00\x00'
            b'\x00\x00\x00\x2C\x00\x00\x00\x00'
            b'\x02\x00\x01\x00\x00\x02\x02\x0C'
            b'\x0A\x00\x3B'
        )
        uploaded = SimpleUploadedFile(
            name='small.gif',
            content=small_gif,
            content_type='image/gif'
        )
        cls.user = User.objects.create_user(username='TestUser')
        cls.another_user = User.objects.create_user(username='tiger')
        cls.group = Group.objects.create(
            title='Тестовая группа',
            slug='test_slug',
            description='Тестовое описание',
        )

        cls.post = Post.objects.create(
            author=cls.user,
            text='Тестовый текст',
            group=cls.group,
            image=uploaded
        )
        cls.context_test = {
            reverse('posts:index'): 'Главная страница',
            reverse(
                'posts:group_list',
                kwargs={'slug': cls.group.slug}
            ): 'Страница групп',
            reverse(
                'posts:profile',
                kwargs={'username': cls.post.author}
            ): 'Страница профиля',
            reverse(
                'posts:post_detail',
                kwargs={'post_id': cls.post.id}
            ): 'Страница деталей поста',
            reverse(
                'posts:post_edit',
                kwargs={'post_id': cls.post.id}
            ): 'Страница создания поста',
        }
        cls.post_with_views = {
            reverse('posts:index'): 'Главная страница',
            reverse(
                'posts:group_list',
                kwargs={'slug': cls.group.slug}
            ): 'Страница групп',
            reverse(
                'posts:profile',
                kwargs={'username': cls.post.author}
            ): 'Страница профиля',
        }
        cls.templates_pages_names = {
            'posts/index.html': reverse('posts:index'),
            'posts/group_list.html': reverse(
                'posts:group_list',
                kwargs={'slug': cls.group.slug}
            ),
            'posts/profile.html': reverse(
                'posts:profile',
                kwargs={'username': cls.post.author}
            ),
            'posts/post_detail.html': reverse(
                'posts:post_detail',
                kwargs={'post_id': cls.post.id}
            ),
            'posts/create_post.html': reverse(
                'posts:post_edit',
                kwargs={'post_id': cls.post.id}
            ),
            'posts/follow.html': reverse(
                'posts:follow_index'
            )
        }
        cls.form = PostForm()

    @classmethod
    def tearDownClass(cls):
        super().tearDownClass()
        shutil.rmtree(TEMP_MEDIA_ROOT, ignore_errors=True)

    def setUp(self):
        self.quest_client = Client()
        self.authorized_client = Client()
        self.authorized_client.force_login(PostsViewsTest.post.author)
        self.another_authorized_client = Client()
        self.another_authorized_client.force_login(self.another_user)

    def test_pages_uses_correct_template(self):
        """URL-адрес использует соответствующий шаблон."""
        for template, reverse_name in self.templates_pages_names.items():
            with self.subTest(reverse_name=reverse_name):
                response = self.authorized_client.get(reverse_name)
                self.assertTemplateUsed(response, template)

    def test_pages_uses_correct_template_for_guest(self):
        """URL-адрес не использует шаблон для
         не авторизованного пользователя"""
        response = self.quest_client.get(
            reverse(
                'posts:post_edit',
                kwargs={'post_id': self.post.id}
            )
        )
        self.assertTemplateNotUsed(response, 'posts/create_post.html')

    def test_all_views_page_show_correct_context(self):
        """Шаблоны views сформированы с правильным контекстом."""
        cache.clear()
        for address, temp in self.context_test.items():
            with self.subTest(temp=temp):
                danger_message = f'Шаблон {temp} сформирован не верно'
                response = (self.authorized_client.get(address))
                post = response.context['post']
                self.assertEqual(post.author, self.post.author, danger_message)
                self.assertEqual(post.text, self.post.text, danger_message)
                self.assertEqual(post.group, self.post.group, danger_message)
                self.assertEqual(post.image, self.post.image, danger_message)

    def test_post_with_group_index_show_correct_context(self):
        """Пост с группой есть на главной странице."""
        post_2 = Post.objects.create(
            author=self.user,
            text='Тестовый точно текст?',
            group=self.group,
            pub_date='2022-08-14 00:00:00',
        )
        for address, temp in self.post_with_views.items():
            with self.subTest(temp=temp):
                danger_message = f'Пост {temp} не найден на странице'
                response = (self.authorized_client.get(address))
                post = response.context['page_obj'][0]
                self.assertEqual(post.pk, post_2.pk, danger_message)

    def test_authorized_client_can_comment(self):
        """Авторизованный пользователь может комментировать посты."""
        comments_initial = Comment.objects.count()
        self.authorized_client.post(
            reverse(
                'posts:add_comment',
                kwargs={'post_id': self.post.id}
            ),
            data={'text': 'Комментарий для поста 2'}
        )
        comments_finally = Comment.objects.count()
        comments_text = Comment.objects.all()[0].text
        self.assertEqual(comments_initial + 1, comments_finally)
        self.assertEqual('Комментарий для поста 2', comments_text)

    def test_guest_client_cant_comment(self):
        """Неавторизованный пользователь не может комментировать посты."""
        comments_initial = Comment.objects.count()
        self.quest_client.post(
            reverse(
                'posts:add_comment',
                kwargs={'post_id': self.post.id}
            ),
            data={'text': 'Комментарий для поста 1'}
        )
        comments_finally = Comment.objects.count()
        self.assertNotEqual(comments_initial + 1, comments_finally)

    def test_comment_in_page_detail(self):
        """После успешной отправки комментарий появляется на странице поста."""
        self.authorized_client.post(
            reverse(
                'posts:add_comment',
                kwargs={'post_id': self.post.id}
            ),
            data={'text': 'Комментарий для поста 2'}
        )
        response = self.authorized_client.get(
            reverse(
                'posts:post_detail',
                kwargs={'post_id': self.post.id}
            )
        )
        comments_text = response.context['comments'][0].text
        self.assertEqual('Комментарий для поста 2', comments_text)

    def test_cache_home_page(self):
        """Проверка работы кеша главной страницы."""
        cache.clear()
        post_del_cache = Post.objects.create(
            text='Текст для проверки',
            author=self.user,
        )

        def response():
            return self.quest_client.get(reverse('posts:index'))

        response_primary = response().content
        post_del_cache.delete()
        response_secondary = response().content
        self.assertEqual(response_primary, response_secondary)
        cache.clear()
        response_cache_clear = response().content
        self.assertNotEqual(response_secondary, response_cache_clear)

    def test_create_follow_authorized(self):
        """Тест создания подписок авторизованным пользователем."""
        self.authorized_client.get(
            reverse('posts:profile_follow',
                    kwargs={'username': self.another_user.username}
                    )
        )
        self.assertTrue(Follow.objects.filter(author=self.another_user,
                                              user=self.user))

    def test_create_follow_non_authorized(self):
        """Тест создания подписок неавторизованным пользователем."""
        self.quest_client.get(
            reverse('posts:profile_follow',
                    kwargs={'username': self.another_user.username}
                    )
        )
        self.assertFalse(Follow.objects.filter(author=self.another_user,
                                               user=self.user))

    def test_create_follow_author(self):
        """Тест автор подписки не может подписаться сам на себя."""
        self.authorized_client.get(
            reverse('posts:profile_follow',
                    kwargs={'username': self.user.username}
                    )
        )
        self.assertFalse(Follow.objects.filter(author=self.user,
                                               user=self.user))

    def test_delete_follow_authorized(self):
        """Тест удаления подписок авторизованным пользователем."""
        self.authorized_client.get(
            reverse('posts:profile_unfollow',
                    kwargs={'username': self.another_user.username}
                    )
        )
        self.assertFalse(Follow.objects.filter(author=self.another_user,
                                               user=self.user))

    def test_new_post(self):
        """Тест новой записи пользователя появляется в ленте подписавшихся."""
        me = User.objects.create(username='me')
        self.authorized_client.get(
            reverse('posts:profile_follow',
                    kwargs={'username': me.username}
                    )
        )
        new_post = Post.objects.create(author=me, text='Test 1')
        response = self.authorized_client.get(
            reverse('posts:follow_index')
        )
        self.assertEqual(new_post, response.context['page_obj'][0])
        response = self.another_authorized_client.get(
            reverse('posts:follow_index')
        )
        self.assertEqual(len(response.context['page_obj']), 0)


import argparse
import glob
import numpy as np
import torch
import torch.nn as nn
from torch.autograd import Variable
from models import *
from utils import *
import torchvision.utils as utils
from matplotlib import pyplot as plt
import torchvision.transforms as transforms
from imageio import imwrite
from testdataset import *
from datetime import datetime
from PIL import Image

os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = "0"

parser = argparse.ArgumentParser(description="NTIRE DeBlur Challenge")
parser.add_argument("--num_of_layers", type=int, default=16, help="Number of total layers")
parser.add_argument("--logdir", type=str, default="logs", help='path of log files')
parser.add_argument("--test_data", type=str, default='val_blur', help='test on Set12 or Set68')
parser.add_argument("--test_noiseL", type=float, default=15, help='noise level used on test set')
opt = parser.parse_args()

def normalize(data):
    return data/255.

def main():
    toTensor = transforms.Compose([transforms.ToTensor()])
    toPILImg = transforms.ToPILImage()

    # Build model
    print('Loading model ...\n')
    net = EACD(channels=3)
    # device_ids = [0]
    # model = nn.DataParallel(net, device_ids=device_ids).cuda()
    model = net.cuda()
    load = torch.load(os.path.join(opt.logdir, 'EACD_348_0.0328.pth'))
    model.load_state_dict(load)
    model.eval()
    # load data info
    print('Loading data info ...\n')
    dataset_val = Dataset(train=False).data
    files_source = glob.glob(os.path.join('data/val_submit', opt.test_data, '*.jpg'))
    files_source.sort()

    print('Model Test Start!')

    for f in files_source:
        # image
        blur = Image.open(f)
        # blur = cv2.imread(f)
        blur = np.transpose(blur, (2, 0, 1))
        blur = normalize(np.float32(blur))
        blur = np.expand_dims(blur, 0)
        blurimg = torch.Tensor(blur)

        with torch.no_grad():  # this can save much memory
            blurimg = Variable(blurimg.cuda())
            out, edge = model(blurimg)
            Out = torch.clamp(out, 0., 1.)

        # Tensor to Image.
        blur_img = utils.make_grid(blurimg.data, nrow=8, normalize=True, scale_each=True)
        deblur_img = utils.make_grid(Out.data, nrow=8, normalize=True, scale_each=True)

        result_img = torch.clamp(deblur_img * 255, 0, 255)
        result_img = np.uint8(result_img.cpu())
        name = f.split('/')[-1]
        name = name.split('.')[0]
        name = name + '.png'
        imwrite('./data/val_out/' + name , np.transpose(result_img, (1,2,0)))
        print(name + ' saved!!')

if __name__ == "__main__":
    main()


from flask.views import MethodView
from trusthouse.models.review import Review
from trusthouse.utils.validate_location import validate_location_request
from trusthouse.utils.request_messages import error_message, ok_message
from flask import jsonify
from ..extensions import app

class FilterByLocationAPI(MethodView):
    def get(self, location):
        user_location_request = location
        response = validate_location_request(user_location_request)
        if response == False:
            data = {
                'Search by location': error_message()[1],
                'Status': error_message()[2],
            }
            return jsonify(data)
        user_location_result = []
        get_reviews = Review.query.all()
        for review in get_reviews:
            if user_location_request == review.address.location:
                result = {
                    'id': review.id,
                    'Rating': review.rating,
                    'Review': review.review,
                    'Type': review.type,
                    'Date': review.date,
                    'Address ID': review.address_id,
                    'Address': {
                        'id': review.address.id,
                        'Door Number': review.address.street,
                        'Street': review.address.street,
                        'Postode': review.address.postcode,
                    },
                }
                user_location_result.append(result)
        data = {
            'Search by loction': ok_message()[2],
            'Reviews by location': user_location_result,
            'Status': ok_message()[3],
        }
        return jsonify(data)

app.add_url_rule(
    '/api/location/<location>',
    view_func=FilterByLocationAPI.as_view(
        name='filter_location_API'
    ),
)


# flask packages
from flask import (
    Blueprint, flash, g, redirect, render_template, request, url_for, session
)
from werkzeug.exceptions import abort
from flaskr.auth import login_required
from flaskr.db import get_db
# json file extraction packages
import urllib, json
import urllib.request, json
# blockchain packages
from web3 import Web3, HTTPProvider

from datetime import datetime, date, timedelta
import calendar
# timezone package needed for prediction
from pytz import timezone
bp = Blueprint('satellite', __name__)

# N2yo API key
api_key = 'KQ9N7M-XWZL5A-NV4CAK-4NG8'
# Skyfield API prediction API
from skyfield.api import load, EarthSatellite, wgs84
#   Smart Contract data set up

# source: https://dev.to/gcrsaldanha/deploy-a-smart-contract-on-ethereum-with-python-truffle-and-web3py-5on
# blockchain smart contract code, possible to do it on this

# ganache address (EVM local blockchain network)
blockchain_address = 'http://127.0.0.1:7545'
# Client instance to interact with the blockchain
web3 = Web3(Web3.HTTPProvider(blockchain_address))
# Set the default account (so we don't need to set the "from" for every transaction call)
web3.eth.defaultAccount = web3.eth.accounts[0]
# Path to the compiled contract Satellites JSON file
compiled_contract_path = '/Users/jordanlloyd/Satellite/Code/flaskr/artifacts/Satellites.json'
# Deployed contract address (changes if I migrate --reset the contract)
deployed_contract_address = '0x26aDB61B71Dfe8eE3d9AA1Dd1eE6Ba0BE6bB9238'

# retrieves the smart contract data
with open(compiled_contract_path) as file:
    contract_json = json.load(file)  # load contract info as JSON
    contract_abi = contract_json['abi']  # fetch contract's abi - necessary to call its functions

# Fetch deployed contract reference
contract = web3.eth.contract(address=deployed_contract_address, abi=contract_abi)

# satellite home page route
@bp.route('/satelliteindex', methods=('GET', 'POST'))
def index():
    # near satellite retrieval
    nearsats = get_near()
    if nearsats is None:
        nearsats = ['NO SATELLITES', 'NEAR']
    # arrays of popular satellite details
    popnames = ['Space Station', 'SES 1', 'NOAA 19', 'GOES 13', 'TERRA', 'AQUA']
    popids = [25544, 36516, 25338, 29155, 25994, 27424]

    if request.method == 'POST':
        # NORAD ID track verification
        satelliteid = request.form['satelliteid']
        error = None
        if not satelliteid:
            error = 'Satellite ID is required.'
            flash(error)

        elif (check_sat(get_info(satelliteid)) == False):
            error = 'Satellite ID is invalid.'
            flash(error)
        elif (check_sat(get_info(satelliteid)) == True):
            session.clear()
            # redirects to the satellite tracking page
            return redirect(url_for('satellite.track', satelliteid=satelliteid))

    return render_template('satellites/index.html', nearsats=nearsats, popnames=popnames, popids=popids)

# about page template route
@bp.route('/about')
def about():
    return render_template('satellites/About.html')

# track page route with get and post methods
@bp.route('/track', methods=('GET', 'POST'))
def track():
    # retrieves the satid variable passed from the home page
    satid = request.args['satelliteid']
    # retrieves the satellite data for the satid variable
    satdata = get_info(satid)
    # presents the current time in the current time zone instead of the timestamp
    utc = getUTC(satdata['positions'][0]['timestamp'])

    if request.method == 'POST':
        satid = request.args['satelliteid']
        satdata = get_info(satid)
        # if the save button for the blockchain is selected; saves the satdata to the blockchain network

        if request.form['submit'] == 'save':

            #variables of the satellite data
            satname = satdata['info']['satname']
            satlon = satdata['positions'][0]['satlongitude']
            satlat = satdata['positions'][0]['satlatitude']
            satelev = satdata['positions'][0]['elevation']
            sataz = satdata['positions'][0]['azimuth']
            satdate = satdata['positions'][0]['timestamp']

            # save the data to the smart contract
            tx_hash = saveSat(satdata)
            # retrieves the latest/ current block number
            blockNo = web3.eth.blockNumber
            satComment = request.form['satComment']
            cdate = datetime.now()

            # save the block number and comment into the database
            # we can access the satdata using the block number
            db = get_db()
            db.execute(
                'INSERT INTO block (tx_hash, block_no, date, comment, satname, satid, longitude, latitude, elevation, azimuth, timestamp)'
                ' VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
                (tx_hash, blockNo, cdate.strftime("%d/%m/%Y %H:%M:%S"), satComment, satname, satid, satlon, satlat, satelev, sataz, getUTC(satdate))
            )
            db.commit()
            # redirects to the blockchain page
            return redirect(url_for('satellite.blockchain', satdata=satdata ))

        # if the predict button is selected; it will request the time frame and calculate the longitude and latitude
        elif request.form['submit'] == 'predict':
            satid = request.args['satelliteid']
            # retrieves the satellites TLE (two line elements)
            tle = get_tle(satid)

            # stores the timeframe selected
            period = request.form['predict']

            # retrieves the longitude and latitude of the current tle
            lon, lat = pred_longlat(tle, period)

            satelliteid = satid

            return render_template('satellites/Track.html',lon=lon, lat=lat, utc=utc, satelliteid=satelliteid, satdata=satdata )

    #  redirected from the home page, displays the desired satellites data and the location on the map
    if request.method == 'GET':
        satelliteid = request.args['satelliteid']

        satdata = get_info(satelliteid)

        return render_template('satellites/Track.html', satdata=satdata, utc=utc, satelliteid=satelliteid)

# blockchain page route; retrieves the blockchain database
@bp.route('/blocks')
def blockchain():
    db = get_db()
    blocks = db.execute(
        'SELECT tx_hash, block_no, date, comment, satname, satid, longitude, latitude, elevation, azimuth, timestamp'
        ' FROM block'
    ).fetchall()
    # passes the database information to the html page
    return render_template('satellites/viewBlocks.html', blocks=blocks)

# API requires the long and latitude of the user;
# To avoid data security concerns; I will assume the user is using the website from manchester
# Manchester coordinates
#longitude = -2.23743
#latitude = 53.48095

# function retrieves the satellite data to a python dictionary
def get_info(satelliteid):
    #formats the satellite id and the api key into the link
    positionurl = "https://api.n2yo.com/rest/v1/satellite/positions/{}/53.48095/-2.23743/38/1/&apiKey={}".format(satelliteid, api_key)

    # json data parsed into python dictionary
    with urllib.request.urlopen(positionurl) as responsepos:
        data = json.loads(responsepos.read())

    return data

# function verifies the existance of the satellite
def check_sat(satdata):
    #get value of a key and checks the satname attribute has a value
    # the url always returns a json
    if satdata['info']['satname'] == None:
        return False
    else:
        return True

# function changes the variable types of the satellite data to type string
def satToStr(testsat):
    satarray = [str(testsat['info']['satname']), str(testsat['positions'][0]['satlongitude']),
    str(testsat['positions'][0]['satlatitude']), str(testsat['positions'][0]['elevation']) , str(testsat['positions'][0]['azimuth']), str(testsat['positions'][0]['timestamp'])]
    return satarray

# corrects the time to UTC form, use when displaying result
def getUTC(timestamp: int):
    utc = datetime.utcfromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
    return utc

# saves the current satellite info to the smart contract state memory, thus creating a new block
def saveSat(testsat):
    #sets the satellite data and creates the hash of the save
    tx_hash = contract.functions.set(0 ,testsat['info']['satid'], str(testsat['info']['satname']), str(testsat['positions'][0]['satlongitude']), str(testsat['positions'][0]['satlatitude']),
    str(testsat['positions'][0]['elevation']), str(testsat['positions'][0]['azimuth']), str(testsat['positions'][0]['timestamp'])).transact()
    #provides a waiting time for the transacation to be complete and mined
    # i.e stops executing any code until the block's been developed
    web3.eth.waitForTransactionReceipt(tx_hash)
    return tx_hash

# calls the smart contract get function to read the current blocks variable states, returns an array
def callSat():
    satinfo = contract.functions.get().call()
    return satinfo

# function retrieves the tle (two line elements) of a satellite
def get_tle(satid):
    #formats the tle into a json
    tlejson = "https://api.n2yo.com/rest/v1/satellite/tle/25544&apiKey={}".format(api_key)
    with urllib.request.urlopen(tlejson) as responsepos:
        data = json.loads(responsepos.read())
    tle = data['tle']
    return(tle)

def pred_longlat(tle, period):
    #time abstraction
    ts = load.timescale()
    # splits the TLE elements into their lines
    line1, line2 = tle.splitlines()
    # represents the tle data as the satellite
    satellite = EarthSatellite(line1, line2)
    #utc(year, month=1, day=1, hour=0, minute=0, second=0.0)
    #time = ts.utc(year, month, day, hour)
    # retrieves the correct timezone
    uk = timezone('Europe/London')

    # adds time or dates to the current datetime
    if period == 1 :
        dt = datetime.now() + timedelta(hours=1)
    elif period == 2:
        dt = datetime.now() + timedelta(hours=2)
    elif period == 4:
        dt = datetime.now() + timedelta(hours=4)
    elif period == 6:
        dt = datetime.now() + timedelta(hours=6)
    elif period == 12:
        dt = datetime.now() + timedelta(hours=12)
    elif period == 24:
        dt = datetime.now() + timedelta(days=1)
    elif period == 40:
        dt = datetime.now() + timedelta(days=4)
    else: # period == 70
        dt = datetime.now() + timedelta(days=7)

    predTime = uk.localize(dt)
    time = ts.from_datetime(predTime)

    # gets the satellite data at the predicted time
    #t1 = ts.utc(2014, 1, 24)
    predloc = satellite.at(time)

    #stores the values of the satellites positions printed onto the earths surface (directly below it)
    subsat = wgs84.subpoint(predloc)
    # rounds the results to 8 decimal places for the google map location
    lon = round(subsat.longitude.degrees, 6)
    lat = round(subsat.latitude.degrees, 6)
    return(lon, lat)

# function to retrieve nearby satellite names and information to manchester within 4degrees above
def get_near():
    # json data parsed into python dictionary
    nearjson = "https://api.n2yo.com/rest/v1/satellite/above/53.48095/-2.23743/38/4/0/&apiKey={}".format(api_key)

    with urllib.request.urlopen(nearjson) as responsepos:
        data = json.loads(responsepos.read())
    # retreives the list of satellites and their data
    # validates there are some satellites, to prevent errors
    if data is None:
        return None
    else:
        nearsat = data['above']
        return nearsat

def setPredtime(period):
    day = date.today().day
    month = date.today().month
    year = date.today().year
    now = datetime.now()
    hour = now.hour
    # make shift 'switch' and validation to ensure the time is correct for prediction

    # 1hr
    if(period == 1):
        hour = hour + 1
        if (hour >= 24 ):
            day = day + 1
            hour = hour - 24
            if (day > calendar.monthrange(year, month)[1] ):
                day = day - calendar.monthrange(year, month)[1]
                month = month + 1
                if (month >= 13):
                    month = 1
                    year = year + 1
    # 2hrs
    elif (period == 2):
        hour = hour + 2
        if (hour >= 24 ):
            day = day + 1
            hour = hour - 24
            if (day > calendar.monthrange(year, month)[1] ):
                day = day - calendar.monthrange(year, month)[1]
                month = month + 1
                if (month >= 13):
                    month = 1
                    year = year + 1
    # 4hrs
    elif(period == 4):
        hour = hour + 4
        if (hour >= 24 ):
            day = day + 1
            hour = hour - 24
            if (day > calendar.monthrange(year, month)[1] ):
                day = day - calendar.monthrange(year, month)[1]
                month = month + 1
                if (month >= 13):
                    month = 1
                    year = year + 1
    # 6hrs
    elif(period == 6):
        hour = hour + 6
        if (hour >= 24 ):
            day = day + 1
            hour = hour - 24
            if (day > calendar.monthrange(year, month)[1]):
                day = day - calendar.monthrange(year, month)[1]
                month = month + 1
                if (month >= 13):
                    month = 1
                    year = year + 1
    # 12hrs
    elif(period == 12):
        hour = hour + 12
        if (hour >= 24 ):
            day = day + 1
            hour = hour - 24
            if (day > calendar.monthrange(year, month)[1] ):
                day = day - calendar.monthrange(year, month)[1]
                month = month + 1
                if (month >= 13):
                    month = 1
                    year = year + 1
    # 1day
    elif(period == 24):
        day = day + 1
        if (day > calendar.monthrange(year, month)[1] ):
            day = day - calendar.monthrange(year, month)[1]
            month = month + 1
            if (month >= 13):
                month = 1
                year = year + 1
    # 4days
    elif(period == 40):
        day = day + 4
        if (day > calendar.monthrange(year, month)[1] ):
            day = day - calendar.monthrange(year, month)[1]
            month = month + 1
            if (month >= 13):
                month = 1
                year = year + 1
    # 7days
    elif(period == 70):
        day = day + 7
        if (day > calendar.monthrange(year, month)[1] ):
            day = day - calendar.monthrange(year, month)[1]
            month = month + 1
            if (month >= 13):
                month = 1
                year = year + 1

    return (year, month, day, hour)


#############PERSPECTIVE TRANSFORM: BIRDS' EYE VIEW###################

#We will detect lane lines from normal (front facing) perspective but our ultimate goal here is to
#detect the curvature of the lane as this can be used to decide on the steering angle.
#This requires us to fit a polynomial curve to the lane lines and this is easier from a birds' eye view.
#Once we have the polynomial equations, it's simple calculus to find curvature.

#Perspective is the phenomenon where objects appear smaller the farther away they are.
#Depending on your perspective, parallel lines will converge to different points.

#A perspective transform changes this by dragging points away from or towards the camera.

#Why much easier to fit polynomial from birds' eye view? Well more just that it's really hard from front
#facing view: left line looks bending to right and right line looks bending to left. From birds' eye view, it
#is clear the lines are parallel and it is clear the direction they are bending in.
#Birds' eye view also allows easy comparison with maps which is good for establishing location.

#How does it work? Well we want to preserve straight lines whilst dragging points about the image. The perspective
#transform itself will be an affine transformation (2x2 matrix). This has 4 elements so we'll need 4 simultaneous eqns.
#To construct these, we pick 4 points that we know lie on a rectangle in the original image and we then supply coords
#for 4 points in the warped image for where we want these to end up (will lie on standard rectangle i.e. vertical and horizontal
#edges). Then use cv2 functions to find the required matrix (solve the system of 4 simultaneous eqns for us).

#We will again work with chessboard images for this as they are easy to establish rectangular regions on. Once we find the
#warp matrix, this can then be applied to any image passing through the lens - providing we can approximate a rectangular region on it
#This will require us to draw a kind of trapezoidal bounding box around the visible portion of the lane line (more on that later)

import numpy as np
import glob
import cv2
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import pickle

mtx=pickle.load(open("mtx.p", "rb"))
dist=pickle.load(open("dist.p", "rb"))

def undistort_image(img, mtx=mtx, dist=dist):
	undist = cv2.undistort(img, mtx, dist, None, mtx)
	return undist

#ONLY NEED 4 POINTS FOR 2X2 WARP MATRIX SO USE OUTERMOST CORNERS

def corners_unwarp(img, nx=9, ny=6, mtx=mtx, dist=dist):
    undist = undistort_image(img)
    # Convert undistorted image to grayscale
    gray = cv2.cvtColor(undist, cv2.COLOR_BGR2GRAY)
    # Search for corners in the grayscaled image
    ret, corners = cv2.findChessboardCorners(gray, (nx, ny), None)

    if ret == True:
        # If we found corners, draw them! (just for fun)
        cv2.drawChessboardCorners(undist, (nx, ny), corners, ret)
        # Choose offset from image corners to plot detected corners
        # This should be chosen to present the result at the proper aspect ratio
        # My choice of 100 pixels is not exact, but close enough for our purpose here
        offset = 100 # offset for dst points
        # Grab the image shape
        img_size = (gray.shape[1], gray.shape[0])

        # For source points I'm grabbing the outer four detected corners
        src = np.float32([corners[0], corners[nx-1], corners[-1], corners[-nx]])
        # For destination points, I'm arbitrarily choosing some points to be
        # a nice fit for displaying our warped result
        # again, not exact, but close enough for our purposes
        dst = np.float32([[offset, offset], [img_size[0]-offset, offset],
                                     [img_size[0]-offset, img_size[1]-offset],
                                     [offset, img_size[1]-offset]])
        # Given src and dst points, calculate the perspective transform matrix
        M_warp = cv2.getPerspectiveTransform(src, dst)
        # Warp the image using OpenCV warpPerspective()
        warped = cv2.warpPerspective(undist, M_warp, img_size)

        return warped, M_warp

#image = cv2.imread('./camera_cal/calibration20.jpg')
#warped, M_warp = corners_unwarp(image)
#pickle.dump(M_warp, open("M_warp.p", "wb"))
#print("Warp matrix has been pickle dumped.")

def birds_eye_new_matrix(image, already_undistorted, source_vert):
    assert len(source_vert) == 4
    print("Vertices of rectangular region have been loaded")
    if already_undistorted == False:
        undist = undistort_image(image)
        print("Lens distortion removed from image")
    else:
        undist = image
    gray = cv2.cvtColor(undist, cv2.COLOR_BGR2GRAY)
    img_size = (gray.shape[1], gray.shape[0])
    offset = 300
    #destination_vert = np.float32( [[offset, img_size[1]], [offset, 0], [img_size[0]-offset, 0], [img_size[0]-offset, img_size[1]] ])
    destination_vert = np.float32([[(img_size[0]/4),0], [(img_size[0]/4), img_size[1]], [(img_size[0]*3/4), img_size[1]], [(img_size[0]*3/4), 0]])
    M_warp = cv2.getPerspectiveTransform(source_vert, destination_vert)
    M_inv = cv2.getPerspectiveTransform(destination_vert, source_vert)
    pickle.dump(M_warp, open("M_warp.p", "wb"))
    pickle.dump(M_inv, open("M_inv.p", "wb"))
    print("Warp matrix and its inverse created and dumped to pickle file")
    warped = cv2.warpPerspective(undist, M_warp, img_size)
    cv2.polylines(warped, [destination_vert.astype(int).reshape((-1,1,2))], True, (255,0,0), 6)
    print("Perpsective changed to bird's eye view")
    return warped, M_warp

def birds_eye_existing_matrix(image, already_undistorted, source_vert):
    assert len(source_vert) == 4
    print("Vertices of rectangular region have been loaded")
    if already_undistorted == False:
        undist = undistort_image(image)
        print("Lens distortion removed from image")
    else:
        undist = image
    gray = cv2.cvtColor(undist, cv2.COLOR_BGR2GRAY)
    img_size = (gray.shape[1], gray.shape[0])
    offset = 300
    #destination_vert = np.float32( [[offset, img_size[1]], [offset, 0], [img_size[0]-offset, 0], [img_size[0]-offset, img_size[1]] ])
    destination_vert = np.float32([[(img_size[0]/4),0], [(img_size[0]/4), img_size[1]], [(img_size[0]*3/4), img_size[1]], [(img_size[0]*3/4), 0]])
    print(source_vert)
    print(destination_vert)
    M_warp = pickle.load(open("M_warp.p", "rb"))
    print("Warp matrix loaded from existing pickle file")
    warped = cv2.warpPerspective(undist, M_warp, img_size)
    cv2.polylines(warped, [destination_vert.astype(int).reshape((-1,1,2))], True, (255,0,0), 6)
    print("Perpsective changed to bird's eye view")
    return warped, M_warp

image = cv2.imread('./test_images/straight_lines1.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
img_size = (gray.shape[1], gray.shape[0])
src_vert = np.float32([[(img_size[0]/2)-55, (img_size[1]/2)+100], [(img_size[0]/6)-10, img_size[1]], [(img_size[0]*5/6)+40, img_size[1]], [(img_size[0]/2)+60, (img_size[1]/2)+100] ])
print("test1 image loaded from disc")
#warped = birds_eye(image, already_undistorted = False, source_vert = np.float32([ [300, 675], [600, 460], [720, 460], [1085, 675] ]))[0]
warped = birds_eye_existing_matrix(image, already_undistorted = False, source_vert = src_vert)[0]
print("Image warp takes place before polygon drawn on original image thus avoiding blurred box in bird's eye image")
cv2.polylines(image, [src_vert.astype(int).reshape((-1,1,2))], True, (255,0,0), 6)
print("Lane line polygon drawn on original image after warped image completed")
#Plot original camera image (distorted) next to the calibrated (undistorted) image
f, (ax1, ax2) = plt.subplots(1, 2, figsize = (24, 9))
f.tight_layout()
ax1.imshow(image)
ax1.set_title('Original Image', fontsize = 50)
ax2.imshow(warped)
ax2.set_title('Undistorted and Warped Image', fontsize = 50)
plt.subplots_adjust(left=0., right = 1, top=0.9, bottom=0.)
plt.savefig('test1_undistorted_and_warped.png')
plt.close()
print('You can observe the undistorted and warped image in test1_undistorted_and_warped.png')


import pygame
import utils.constants as consts

def draw_window(window, birds, pipes, base, score=None, generation_number=None):
    window.blit(consts.BG_IMG, (0, 0))

    for bird in birds:
        bird.draw(window)

    for pipe in pipes:
        pipe.draw(window)

    if score != None:
        score_text = consts.STAT_FONT.render(
            f"Score: {score}", 1, consts.WHITE_RGB)
        window.blit(score_text, (consts.WIN_WIDTH -
                    10 - score_text.get_width(), 10))

    if generation_number != None:
        generation_number_text = consts.STAT_FONT.render(
            f"Generation: {generation_number}", 1, consts.WHITE_RGB)
        window.blit(generation_number_text, (10, 10))

    base.draw(window)

    pygame.display.update()


"""
作者：Mr.Feng
功能：定时发送wechat消息,需要先打开聊天窗口
版本：V1.0
日期：2019/07/18
"""
# coding=utf-8
import requests
from threading import Timer
import win32gui
import win32con
import win32api
import time
from pynput.mouse import Button, Controller as mController
from pynput.keyboard import Key, Controller as kController

def get_news():
    """获取金山词霸每日一句，英文和翻译"""
    url = r"http://open.iciba.com/dsapi/"
    r = requests.get(url)
    content = r.json()['content']
    note = r.json()['note']
    return content + '\n' + note

def find_window(classname,titlename):
    """使用按键精灵找到句柄"""
    handle = win32gui.FindWindow(classname,titlename)
    if handle != 0:
        win32gui.ShowWindow(handle, win32con.SW_SHOWNORMAL)  # 将窗口显示出来
        win32gui.SetForegroundWindow(handle)  # 将窗口调到前端
        left, top, right, bottom = win32gui.GetWindowRect(handle)
        print({'handle': handle, 'left': left, 'top': top, 'right': right, 'bottom': bottom})
        return {'handle': handle, 'left': left, 'top': top, 'right': right, 'bottom': bottom}
    else:
        print("找不到[%s]这个人,请尝试打开独立的聊天窗口并核对窗口名称！" % titlename)
        return False

def click_send(msg):
    """模拟鼠标点击"""
    mouse = mController()
    keyboard = kController()
    mouse.press(Button.left)
    mouse.release(Button.left)
    keyboard.type(msg) # 聊天窗口在英文状态下输出文字
    # 发送消息的快捷键是 Alt+s
    with keyboard.pressed(Key.alt):
        keyboard.press('s')
        keyboard.release('s')

def main():
    # 发送的消息内容
    msg = get_news()
    print(msg)
    classname = "ChatWnd"
    titlename = "晓涵"
    try:
        wechat_win = find_window(classname,titlename)
        if wechat_win:
            time.sleep(0.01)
            input_pos = [wechat_win['right']-50,wechat_win['bottom']-50]
            win32api.SetCursorPos(input_pos)  # 定位鼠标到输入位置
            time.sleep(1)  # 等待20秒发出
            click_send(msg)
        # t = Timer(10, main)  # 每隔5秒发送一次
        # t.start()
    except Exception as e:
        print("发送给[%s]的消息失败" % titlename, e)

if __name__ == '__main__':
    main()


from nltk import word_tokenize, pos_tag, ne_chunk
from nltk.stem import PorterStemmer
from nltk.tag import untag, str2tuple, tuple2str
from nltk.chunk import tree2conllstr, conllstr2tree, conlltags2tree, tree2conlltags
import nltk

class FlightChecker(object):
    @staticmethod
    def DetectRoute(text, debugging=False):
        # Morphology - tagging the words
        tokens = word_tokenize(text)

        # Part of speech tagging
        tagged_tokens = pos_tag(tokens)

        # Create named entity tree of tagged tokens
        ner_tree = ne_chunk(tagged_tokens)
        #print( ner_tree )

        # Get tag structure
        # # IoB = inside, outside, beginning - sometimes followed with type of entity
        iob_tagged = tree2conlltags(ner_tree)
        in_chunk = False
        current_chunck = ""
        geo_locations = []
        for word, tag, iob in iob_tagged:
            if(debugging): print(word, "(",tag,"):",":", iob)
            #Detecting if we are in a GeoPolitical chunk
            in_chunk = (iob.startswith("B") or iob.startswith("I")) and (iob.endswith('GPE'))
            if in_chunk:
                current_chunck += word + " "
            if (not(in_chunk) and current_chunck):
                # We just left the chunk as the boolean is false and the chunk has value
                geo_locations.append(current_chunck.strip())
                current_chunck = ""

        if(len(geo_locations)!=2):
            raise Exception('There are two geopolitical chunks expected, but we found', len(geo_locations))
        return geo_locations[0], geo_locations[1]

def DownloadDictionary(dictionaryname):
    import ssl
    try:
        _create_unverified_https_context = ssl._create_unverified_context
    except AttributeError:
        pass
    else:
        ssl._create_default_https_context = _create_unverified_https_context
    nltk.download(dictionaryname)

def main():
    DownloadDictionary('maxent_ne_chunker')
    DownloadDictionary('words')
    statement = "I want to make a flight from Seattle to New York."
    source, destination = FlightChecker.DetectRoute(statement, True)
    print(source, ">>", destination)

if __name__ == "__main__": main()


import os
import time
import datetime as dt
from pathlib import Path
from dataclasses import dataclass, asdict

from colorama import Fore, Style

from utils import math as m
from utils import logger
from data import store as store

try:
    TERMINAL_SIZE = os.get_terminal_size()
except:
    TERMINAL_SIZE = 30

DATE_FORMAT_YMD = '%Y-%m-%d'
DATE_FORMAT_MDY = '%m-%d-%Y'
TABULATE_FORMAT = 'simple'
CHART_STYLE = 'seaborn-v0_8-bright'
CHART_SIZE = (17, 10)
PROGRESS_SLEEP = 0.20

LOG_DIR = './log'
LOG_SUFFIX = 'log'

_logger = logger.get_logger()

class RangeValue:
    def __init__(self, value, minimum, maximum):
        self.value: int | float = value
        self.minimum: int | float = minimum
        self.maximum: int | float = maximum

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

def menu(menu_items: dict, header: str, minvalue: int, maxvalue: int, prompt: str = 'Select operation', cancel: str = 'Quit') -> int:
    print(f'\n{header}')
    print('-' * 50)

    if cancel:
        menu_items['0'] = cancel

    entry: str
    for entry in menu_items.keys():
        if entry.isnumeric():
            print(f'{entry:>2})\t{menu_items[entry]}')
        else:
            print(f'\t{menu_items[entry]}')

    print()
    return input_integer(f'{prompt}', minvalue, maxvalue)

def menu_from_dataclass(items: dataclass, header: str, prompt: str = 'Select Parameter', cancel: str = 'Quit') -> tuple[str, str, RangeValue]:
    f = asdict(items)
    keys = f.keys()
    names = [key.replace('_', ' ').title() for key in keys]
    values = [f[key] for key in keys]
    pairs = list(zip(keys, names, values))
    menu_items = {f'{i+1}': f'{name} ({value.value})' for i, (key, name, value) in enumerate(pairs)}
    item = menu(menu_items, header, 0, len(names), prompt=prompt)
    return pairs[item-1] if item > 0 else ('', '', RangeValue(0, 0, 0))

def delimeter(message, pre_creturn: int, post_creturn: int) -> str:
    output = ''
    if pre_creturn > 0:
        output = '\n' * pre_creturn

    if len(message) > 0:
        output += f'***** {message} *****'
    else:
        output += '*****'

    if post_creturn > 0:
        output += '\n' * post_creturn

    return output

def print_message(message: str, pre_creturn: int = 1, post_creturn: int = 0) -> None:
    print(delimeter(message, pre_creturn, post_creturn))

def print_warning(message: str, pre_creturn: int = 1, post_creturn: int = 0) -> None:
    print(Fore.RED, end='')
    print(delimeter(f'Warning: {message}', pre_creturn, post_creturn))
    print(Style.RESET_ALL, end='')

def print_error(message: str, pre_creturn: int = 1, post_creturn: int = 0) -> None:
    print(Fore.RED, end='')
    print(delimeter(f'Error: {message}', pre_creturn, post_creturn))
    print(Style.RESET_ALL, end='')

def print_tickers(tickers: list[str], group: int = 15) -> None:
    if group < 2:
        raise ValueError('Invalid grouping value')

    index = 0
    if len(tickers) > 0:
        for ticker in tickers:
            print(f'{ticker} ', end='')
            index += 1
            if index % group == 0:
                print()
        print()

def erase_line() -> None:
    global _position, _forward

    _position = 0
    _forward = True
    erase = TERMINAL_SIZE.columns * ' '
    print(f'{erase}', end='\r')

def format_headers(columns: str, case: str = 'title'):
    if case == 'upper':
        header = [header.replace('_', '\n').upper() for header in columns]
    elif case == 'lower':
        header = [header.replace('_', '\n').lower() for header in columns]
    else:
        header = [header.replace('_', '\n').title() for header in columns]

    return header

def input_integer(message: str, min_: int, max_: int, default: int | None = None) -> int:
    value = min_ - 1
    while value < min_:
        text = input(f'{message}: ')

        if m.isnumeric(text):
            value = int(text)
            if value < min_:
                print_error(f'Invalid value. Enter an integer between {min_} and {max_}')
                value = min_ - 1
            elif value > max_:
                print_error(f'Invalid value. Enter an integer between {min_} and {max_}')
                value = min_ - 1
            else:
                value = value
        elif default is not None:
            value = default
        else:
            print_error(f'Invalid value. Enter an integer between {min_} and {max_}')
            value = min_ - 1

    return value

def input_float(message: str, min_: float, max_: float, default: float | None = None) -> float:
    value = min_ - 1.0
    while value < min_:
        text = input(f'{message}: ')
        if m.isnumeric(text):
            value = int(text)
            if float(value) < min_:
                print_error(f'Invalid value. Enter a value between {min_:.2f} and {max_:.2f}')
                value = min_ - 1.0
            elif float(value) > max_:
                print_error(f'Invalid value. Enter a value between {min_:.2f} and {max_:.2f}')
                value = min_ - 1.0
            else:
                value = float(value)
        elif default is not None:
            value = default
        else:
            print_error(f'Invalid value. Enter a value between {min_:.2f} and {max_:.2f}')
            value = min_ - 1.0

    return value

def input_text(message: str, valids: list[str] = [], default: str | None = None) -> str:
    value = ''
    while not value:
        value = input(f'{message}: ')
        if not all(char.isalpha() for char in value):
            value = ''
            print_error('Value must be all letters')
        elif not value and default is not None:
            value = default
        elif valids and value not in valids:
            value = ''
            print_error('Value not valid')

    return value

def input_list(message: str, separator: str = ',') -> str:
    value = input(f'{message}: ').replace(' ', '')
    if not all(char.isalpha() or char == separator for char in value):
        value = ''
        print_error('Symbol value must be all letters')

    return value

def input_alphanum(message: str) -> str:
    value = input(f'{message}: ')
    if not all(char.isalnum() for char in value):
        value = ''
        print_error('Symbol value must be all letters')

    return value

def input_yesno(message: str) -> bool:
    return input(f'{message} (y/n)? ').lower() == 'y'

def input_table(exchange: bool = False, index: bool = False, ticker: bool = False, all: bool = False) -> str:
    if exchange and index and ticker:
        prompt = 'Enter an exchange, an index or a ticker'
    elif exchange and index and not ticker:
        prompt = 'Enter an exchange or an index'
    elif exchange and not index and ticker:
        prompt = 'Enter an exchange or a ticker'
    elif not exchange and index and ticker:
        prompt = 'Enter an index or a ticker'
    elif exchange and not index and not ticker:
        prompt = 'Enter an exchange'
    elif not exchange and index and not ticker:
        prompt = 'Enter an index'
    elif not exchange and not index and ticker:
        prompt = 'Enter a ticker'
    else:
        assert ValueError('Invalid options')

    prompt += ' (or \'every\')' if all else ''

    while True:
        table = input_alphanum(prompt).upper()

        if not table:
            break
        elif all and table == 'EVERY':
            break
        elif all and table == 'BOGUS':
            break
        elif exchange and store.is_exchange(table):
            break
        elif index and store.is_index(table):
            break
        elif ticker and store.is_ticker(table):
            break
        else:
            print_error('Table not found. Enter a valid table, or return to exit')

    return table

def input_float_range(message: str, middle: float, percent: float) -> float:
    if percent < 1.0:
        percent = 1.0
    elif percent > 100.0:
        percent = 100.0

    percent /= 100.0
    min_ = middle * (1.0 - percent)
    max_ = middle * (1.0 + percent)

    return input_float(message, min_, max_)

def write_tickers_log(tickers: list[str], filename: str = '') -> str:
    if tickers:
        date_time = dt.datetime.now().strftime(DATE_FORMAT_YMD)

        if filename:
            filename = f'{LOG_DIR}/{filename}.{LOG_SUFFIX}'
        else:
            filename = f'{LOG_DIR}/{date_time}.{LOG_SUFFIX}'

        with open(filename, 'w') as f:
            for ticker in tickers:
                f.write(ticker + '\n')

    return filename

def read_tickers_log(filename: str) -> list[str]:
    tickers = ['error']
    path = Path(filename)
    if path.is_file():
        try:
            with open(path) as f:
                tickers = f.readlines()

            tickers = [s.replace('\n', '') for s in tickers]
            tickers.sort()
        except:
            _logger.error('File format error')
    else:
        _logger.error(f'File "{filename}" not found')

    return tickers

# Globals for progress bar
_completed = 0
_position = 0
_forward = True
_start = 0.0

def progress_bar(iteration, total: int, prefix: str = 'Working', suffix: str = '', ticker: str = '',
                 length: int = 50, fill='█', success: int = -1, tasks: int = 0, reset: bool = False) -> None:

    global _completed, _position, _forward, _start

    if reset:
        _completed = 0
        _position = 0
        _forward = True
        _start = time.perf_counter()
        erase_line()

    if total > 0:
        filled = int(length * iteration // total)
        bar = (fill * filled) + ('-' * (length - filled))

        elapsed = time.perf_counter() - _start
        if _completed > 5:
            per = elapsed / _completed
            remaining = per * (total - iteration)
            minutes, seconds = divmod(remaining, 60)
            hours, minutes = divmod(minutes, 60)
        else:
            hours = 0.0
            minutes = 0.0
            seconds = 0.0

        if iteration == _completed:
            pass  # Nothing new to show
        elif success < 0:
            print(f'{prefix:<13} |{bar}| {iteration}/{total} {suffix} {ticker}     ', end='\r')
        elif tasks > 0:
            print(f'{prefix:<13} |{bar}| {success}/{iteration}/{total} [{tasks}] {ticker:<5} {hours:02.0f}:{minutes:02.0f}:{seconds:02.0f} {suffix}     ', end='\r')
        else:
            print(f'{prefix:<13} |{bar}| {success}/{iteration}/{total} {ticker:<5} {hours:02.0f}:{minutes:02.0f}:{seconds:02.0f} {suffix}     ', end='\r')

        _completed = iteration

    else:  # Use oscillating marker when the total is not known
        if _forward:
            if _position < length:
                _position += 1
            else:
                _position -= 1
                _forward = False
        elif _position > 1:
            _position -= 1
        else:
            _position = 2
            _forward = True

        front = _position - 1
        back = length - _position
        bar = ('-' * front) + fill + ('-' * back)

        print(f'{prefix:<13} |{bar}| {suffix}             ', end='\r')


import maya.api.OpenMaya as om
import maya.api.OpenMayaRender as omr
import maya.api.OpenMayaUI as omui

import maya.cmds as cmds

def maya_useNewAPI():
    """
    The presence of this function tells Maya that the plugin produces, and
    expects to be passed, objects created using the Maya Python API 2.0.
    """
    pass

class HelloWorldNode(omui.MPxLocatorNode):

    TYPE_NAME = "helloworld"
    TYPE_ID = om.MTypeId(0x0007f7f7)
    DRAW_CLASSIFICATION = "drawdb/geometry/helloworld"
    DRAW_REGISTRANT_ID = "HelloWorldNode"

    def __init__(self):
        super(HelloWorldNode, self).__init__()

    @classmethod
    def creator(cls):
        return HelloWorldNode()

    @classmethod
    def initialize(cls):
        pass

class HelloWorldDrawOverride(omr.MPxDrawOverride):

    NAME = "HelloWorldDrawOverride"

    def __init__(self, obj):
        super(HelloWorldDrawOverride, self).__init__(obj, None, False)

    def prepareForDraw(self, obj_path, camer_path, frame_context, old_data):
        pass

    def supportedDrawAPIs(self):
        return omr.MRenderer.kAllDevices

    def hasUIDrawables(self):
        return True

    def addUIDrawables(self, obj_path, draw_manager, frame_context, data):
        draw_manager.beginDrawable()
        draw_manager.text2d(om.MPoint(100,100), "Hello World")
        draw_manager.endDrawable()

    @classmethod
    def creator(cls, obj):
        return HelloWorldDrawOverride(obj)

def initializePlugin(plugin):
    """
    Entry point for a plugin. It is called once -- immediately after the plugin is loaded.
    This function registers all of the commands, nodes, contexts, etc... associated with the plugin.

    It is required by all plugins.

    :param plugin: MObject used to register the plugin using an MFnPlugin function set
    """
    vendor = "Jay Elbourne"
    version = "1.0.0"

    plugin_fn = om.MFnPlugin(plugin, vendor, version)
    try:
        plugin_fn.registerNode(HelloWorldNode.TYPE_NAME,
                                HelloWorldNode.TYPE_ID,
                                HelloWorldNode.creator,
                                HelloWorldNode.initialize,
                                om.MPxNode.kLocatorNode,
                                HelloWorldNode.DRAW_CLASSIFICATION)
    except:
        om.MGlobal.displayError("Failed to register Node: {0}".format(HelloWorldNode.TYPE_NAME))

    try:
        omr.MDrawRegistry.registerDrawOverrideCreator(HelloWorldNode.DRAW_CLASSIFICATION,
                                                        HelloWorldNode.DRAW_REGISTRANT_ID,
                                                        HelloWorldDrawOverride.creator)
    except:
        om.MGlobal.displayError("Failed to register Node: {0}".format(HelloWorldDrawOverride.NAME))

def uninitializePlugin(plugin):
    """
    Exit point for a plugin. It is called once -- when the plugin is unloaded.
    This function de-registers everything that was registered in the initializePlugin function.

    It is required by all plugins.

    :param plugin: MObject used to de-register the plugin using an MFnPlugin function set
    """
    plugin_fn = om.MFnPlugin(plugin)

    try:
        omr.MDrawRegistry.deregisterDrawOverrideCreator(HelloWorldDrawOverride.DRAW_CLASSIFICATION,
                                                        HelloWorldNode.DRAW_REGISTRANT_ID)
    except:
        om.MGlobal.displayError("Failed to deregister Node: {0}".format(HelloWorldDrawOverride.NAME))

    try:
        plugin_fn.deregisterNode(HelloWorldNode.TYPE_ID)
    except:
        om.MGlobal.displayError("Failed to deregister Node: {0}".format(HelloWorldNode.TYPE_NAME))

if __name__ == "__main__":
    """
    For Development Only

    Specialized code that can be executed through the script editor to speed up the development process.

    For example: scene cleanup, reloading the plugin, loading a test scene
    """

    # Any code required before unloading the plug-in (e.g. creating a new scene)

    # Reload the plugin
    cmds.file(new=True, force=True)

    plugin_name = "HelloWorld_Node.py"
    cmds.evalDeferred('if cmds.pluginInfo("{0}", q=True, loaded=True): cmds.unloadPlugin("{0}")'.format(plugin_name))
    cmds.evalDeferred('if not cmds.pluginInfo("{0}", q=True, loaded=True): cmds.loadPlugin("{0}")'.format(plugin_name))

    cmds.evalDeferred('cmds.createNode("helloworld")')

    # Any setup code to help speed up testing (e.g. loading a test scene)


"""
/******************************************************************************
 *   Performs a series of computational experiments.
 *  Execution:    -
 *  Dependencies: -
 ******************************************************************************/
"""
from Percolation import Percolation
import random
import math

class PercolationStats:
    """
    :param T: The number of times a computation experiment runs.
    :type T: int.
    :param N: elements {0} through {N-1} for an N-by-N grid.
    :type N: int.
    """

    def __init__(self, N: int, T: int):
        """
        Perform T independent experiments on an N-by-N grid.
        :param T: The number of times a computation experiment runs.
        :type T: int.
        :param N: elements {0} through {N-1} for an N-by-N grid.
        :type N: int.
        """
        if N < 1 or T < 1: raise ValueError('N and T must be > 0.')
        self.t = T
        self.N = N
        self.threshold = [self.calc_threshold(N) for _ in range(self.t)]

    def calc_threshold(self, n: int) -> float:
        """
        Find threshold value p*, probability the system will percolate.
        :param n: n the value.
        :return: threshold value.
        :rtype: float.
        """
        counter = 0
        i, j = None, None
        perc = Percolation(n)
        while not perc.percolates():
            i = random.randint(0, n-1)+1
            j = random.randint(0, n-1)+1
            print(f'i: {i}\nj: {j}')
            if not perc.is_open(i, j):
                counter += 1
                perc.open(i, j)
        return counter / (n * n)

    def mean(self) -> float:
        """
        Sample mean of percolation threshold.
        :return: mean.
        :rtype: float.
        """
        _sum = 0
        for i in range(len(self.threshold)):
            _sum += self.threshold[i]
        return _sum / self.t

    def stddev(self) -> float:
        """
        Sample standard deviation of percolation threshold.
        :return: standard deviation.
        :rtype: float.
        """

        m = self.mean()
        _sum = 0
        for i in range(len(self.threshold)):
            _sum += (self.threshold[i] - m) * (self.threshold[i] - m)
        if self.t == 1:
            return float('nan')
        return _sum / (self.t - 1)

    def confidence_low(self) -> float:
        """
        Low endpoint of 95% confidence interval.
        :return: low endpoint.
        :rtype: float.
        """
        return self.mean() - (1.96 * self.stddev()) / (math.sqrt(self.t))

    def confidence_high(self) -> float:
        """
        High endpoint of 95% confidence interval.
        :return: high endpoint.
        :rtype: float.
        """
        return self.mean() + (1.96 * self.stddev()) / (math.sqrt(self.t))

    def __repr__(self):
        return f'<PercolationStats(threshold={self.threshold}, T={self.t}, N={self.N})>'

def main():
    stats = PercolationStats(4, 20)
    print(stats)
    print(f'mean = {stats.mean()}')
    print(f'stddev = {stats.stddev()}')
    print(f'95% confidence interval = {stats.confidence_low()}, {stats.confidence_high()}')

if __name__ == '__main__':
    main()


import os
import json
import math
from flask import (
    Flask, session, Blueprint, flash, g, redirect, render_template, request, url_for
)
from flask_socketio import SocketIO, send, join_room, leave_room, emit

from werkzeug.exceptions import abort

# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app.config['SECRET_KEY'] = 'secret'
socketio = SocketIO(app)
#socketio = SocketIO(app, async_mode="eventlet")

# ensure the instance folder exists
try:
    os.makedirs(app.instance_path)
except OSError:
    pass

#Contains list of existing rooms and their respective users
# 'room' contains
room_list = {}

@app.route('/', methods=('GET', 'POST'))
def index():
    if request.method == 'POST':
        room_name = request.form['room_name']
        #Make Room
        if request.form['action'] == 'make':
            if room_name not in room_list:
                room_list[room_name] = { "Users": [], "Curr_Vid": "", "Queue": [], "Votes": 0, "Curr_Time": 0}
                session['room'] = room_name
                return redirect(url_for('room', room=session.get('room')))
            else:
                print('Room already exists')
                return render_template('index.html')
        #Join Room
        if request.form['action'] == 'join':
            if room_name in room_list:
                session['room'] = room_name
                return redirect(url_for('room', room=session.get('room')))
            else:
                print('Room does not exist')
                return render_template('index.html')
    else:
        room_name = session.get('room', '')
        return render_template('index.html')

@app.route('/<string:room>')
def room(room):
    if(room in room_list):
        session['room'] = room
        return render_template('room.html')
    else:
        return redirect(url_for('index'))

@socketio.on('join')
def joined():
    session['id'] = request.sid
    room = session.get('room')
    join_room(room)
    print('User has entered : ' + room)
    print(room_list[room])
    emit('user init', room_list[room], room=room)

    @socketio.on('disconnect')
    def leave():
        disconnect()

@socketio.on('leave')
def left():
    disconnect()

@socketio.on('text')
def text(message):
    room = session.get('room')
    print('User has entered '+message+ ' in ' +session.get('room'))
    emit('message', {'message':message, 'username':session.get('username')}, room=room)

@socketio.on('add user')
def adduser(username):
    room = session.get('room')
    session['username'] = username
    room_list[room]["Users"].append(username)
    print(session.get('username') + ' has been added to room ' + room)
    print(room_list[room])
    emit('user added', username, room=room)
    emit('update users', room_list[room]["Users"], room=room)
    emit('load playlist', room_list[room]["Queue"], room=room)

@socketio.on('update curr time')
def updateCurrTime(time):
    room = session.get('room')
    room_list[room]["Curr_Time"] = time
    print(room_list[room])
    emit('set curr time', time, room=room)

@socketio.on('video paused')
def pausevideo():
    room = session.get('room')
    print('video has been paused')
    emit('pause video', room=room)

@socketio.on('video played')
def playvideo():
    room = session.get('room')
    print('video playing')
    emit('play video', room=room)

@socketio.on('video buffering')
def buffervideo(time):
    room = session.get('room')
    print('video buffering')
    emit('buffer video', time, room=room)

@socketio.on('queue video')
def queuevideo(url):
    room = session.get('room')
    room_list[room]["Queue"].append(url)
    print(room_list[room])
    emit('add to queue', room_list[room]["Queue"], room=room)

@socketio.on('nextvideo')
def nextvideo():
    room = session.get('room')
    if len(room_list[room]["Queue"]) > 0:
        next_vid = room_list[room]["Queue"][0]
        del room_list[room]["Queue"][0]
        room_list[room]["Votes"] = 0
        print(room_list[room])
        emit('load next video', next_vid, room=room)
        emit('update curr vid client', next_vid, room=room)
        emit('update queue', room_list[room]["Queue"], room=room)
        emit('update votes', room_list[room]["Votes"], room=room)

@socketio.on('update curr vid')
def updateCurrVid(url):
    room = session.get('room')
    room_list[room]["Curr_Vid"] = url
    print(room_list[room])
    emit('update curr vid client', url, room=room)

@socketio.on('load video')
def loadvideo(url):
    room = session.get('room')
    emit('load new video', url, room=room)

@socketio.on('vote')
def vote():
    room = session.get('room')
    room_list[room]["Votes"] += 1
    votes = room_list[room]["Votes"]
    numusers = len(room_list[room]["Users"])
    if votes == math.ceil(numusers/2):
        if len(room_list[room]["Queue"]) > 0:
            next_vid = room_list[room]["Queue"][0]
            del room_list[room]["Queue"][0]
            room_list[room]["Votes"] = 0
            room_list[room]["Curr_Vid"] = next_vid
            print(room_list[room])
            emit('load next video', next_vid, room=room)
            emit('update curr vid client', next_vid, room=room)
            emit('update queue', room_list[room]["Queue"], room=room)
    emit('update votes', room_list[room]["Votes"], room=room)

def disconnect():
    room = session.get('room')
    if session.get('username') is not None:
        room_list[room]["Users"].remove(session.get('username'))
        print('User has left')
        print(room_list[room])
        leave_room(room)
        emit('user left', session.get('username'), room=room)
        emit('update users', room_list[room]["Users"], room=room)
        if len(room_list[room]["Users"]) <= 0:
            del room_list[room]
            print(room_list)

if __name__ == "__main__":
    #app.run(host='0.0.0.0')
    socketio.run(app)


#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

import subprocess
import re
import datetime
import logging
import io
import os.path

logging.basicConfig(level=logging.ERROR)

class DVD(object):
    def __init__(self):
        self.titles=[]
        self.name=''
        self.title=''
    def __str__(self):
        formatted="DVD filename is: "+self.name+'\n'+\
        "DVD Title is: "+self.title+'\n'
        for i in self.titles:
            formatted=formatted+str(i)+'\n'
        return formatted

class Title(object):
    def __init__(self):
        self.title_number=''
        self.duration=datetime.timedelta(hours=0)
        self.audio_tracks=[]
        self.subtitles=[]
    def __str__(self):
        formatted="Title number "+self.title_number+":" + '\n'+\
        "    Duration: "+str(self.duration)+'\n'
        for i in self.audio_tracks:
            formatted=formatted+str(i)
        for i in self.subtitles:
            formatted=formatted+str(i)
        return formatted

class AudioTrack(object):
    def __init__(self):
        self.track_number=''
        self.language=''
        self.language_code=''
        self.codec=''
        self.channels=''
        self.sample_rate=''
        self.bitrate=''
    def __str__(self):
        formatted="Audio Track number "+self.track_number+":" +'\n'+\
        "    Language: "+self.language +'\n'+\
        "    Language Code: "+self.language_code +'\n'+\
        "    Codec: "+self.codec +'\n'+\
        "    Channels: "+self.channels +'\n'+\
        "    Sample Rate: "+self.sample_rate+"Hz" +'\n'+\
        "    Bitrate: "+self.bitrate+"bps" +'\n'
        return formatted

class Subtitle(object):
    def __init__(self):
        self.track_number=''
        self.language=''
        self.language_code=''
        self.type=''

    def __str__(self):
        formatted="Subtitle track "+self.track_number+":" +'\n'+\
        "    Language: "+self.language +'\n'+\
        "    Language_code: "+self.language_code +'\n'+\
        "    Type: " + self.type +'\n'
        return formatted

def isAudioTrack(line):
    if re.match('\+ ([0-9][0-9]*), ([A-Za-z0-9,_]*) \(([a-zA-Z0-9_ ]*)\) \(([a-zA-Z0-9_. ]*)\)',line) is None:
        return False
    else:
        return True

def parseAudioTrack(current_line):
    current_track=AudioTrack()
    trackinfo=re.match('\+ ([0-9][0-9]*), ([A-Za-z0-9,_]*) \(([a-zA-Z0-9_ ]*)\) \(([a-zA-Z0-9_. ]*)\)',current_line)
    iso639_2=re.search('iso639-2: ([a-zA-Z]*)\)',current_line)
    samples=re.search('([0-9]*)Hz',current_line)
    bitrate=re.search('([0-9]*)bps',current_line)

    current_track.track_number=trackinfo.group(1)
    current_track.language=trackinfo.group(2)
    current_track.codec=trackinfo.group(3)
    current_track.channels=trackinfo.group(4)
    if iso639_2 is not None:
        current_track.language_code=iso639_2.group(1)
    if samples is not None:
        current_track.sample_rate=samples.group(1)
    if bitrate is not None:
        current_track.bitrate=bitrate.group(1)

    return current_track

def isSubtitleTrack(current_line):
    if re.match('\+ ([0-9][0-9]*), ([A-Za-z0-9,]*) \([a-zA-Z0-9\-: ]*\) \(([a-zA-Z]*)\)\(([a-zA-Z0-9\-]*)\)',current_line) is None:
        return False
    else:
        return True

def parseSubtitleTrack(current_line):
    current_subtitle=Subtitle()
    m=re.match('\+ ([0-9][0-9]*), ([A-Za-z0-9, ]*) \(.*\) \(([a-zA-Z]*)\)\(([a-zA-Z0-9\-]*)\)',current_line)
    iso639_2=re.search('\(iso639-2: ([a-zA-Z]*)\)',current_line)

    current_subtitle.track_number=m.group(1)
    current_subtitle.language=m.group(2)
    current_subtitle.type=m.group(4)
    if iso639_2 is not None:
        current_subtitle.language_code=iso639_2.group(1)

    return current_subtitle

def parseDVD(filename):
    current_dvd=DVD()
    current_dvd.name=filename

    p = subprocess.Popen( ['HandBrakeCLI','-i',filename,'-t','0'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    (output,_)=p.communicate()

    output_file=io.StringIO(output)
    output_file.seek(0)
    current_line=output_file.readline().strip()

    while current_line.startswith('+')==False and current_line!='HandBrake has exited.':        #Advance through output until we reach summary section
        m = re.match('libdvdnav: DVD Title: (.*)',current_line)
        if m != None:
            current_dvd.title=m.group(1)
        current_line=output_file.readline().strip()

    if current_dvd.title=='':
        (_,lone_filename)=os.path.split(filename)
        (current_dvd.title,_)=os.path.splitext(lone_filename)

    while current_line!='HandBrake has exited.':
        current_title=Title()
        #Have a line in the format '+ title #:'
        m = re.match('\+ title ([0-9][0-9]*)',current_line)
        if m is None:
            current_line=output_file.readline().strip()
            continue
        else:
            current_title.title_number=m.group(1)

        current_line=output_file.readline().strip()
        while re.match('\+ duration: ([0-9][0-9]):([0-9][0-9]):([0-9][0-9])',current_line) is None:
            current_line=output_file.readline().strip()
        m = re.match('\+ duration: ([0-9][0-9]):([0-9][0-9]):([0-9][0-9])',current_line)
        current_title.duration=datetime.timedelta(hours=int(m.group(1)),minutes=int(m.group(2)),seconds=int(m.group(3)))

        current_line=output_file.readline().strip() #Skip forward to audio tracks section
        while re.match('\+ audio tracks:',current_line) is None:
            current_line=output_file.readline().strip()
        current_line=output_file.readline().strip() #Defines the first audio track, presumably

        while isAudioTrack(current_line) is True:
            current_track=parseAudioTrack(current_line)
            current_title.audio_tracks.append(current_track)
            current_line=output_file.readline().strip()

        #When we get here we have gone through all this title's audio tracks and current_line
        #will have the value '+ subtitle tracks:'
        current_line=output_file.readline().strip() #Read either the first subtitle or the next title

        while isSubtitleTrack(current_line) is True:
            current_subtitle=parseSubtitleTrack(current_line)
            current_title.subtitles.append(current_subtitle)
            current_line=output_file.readline().strip()

        #When we get to here we have processed all subtitle tracks.  This title is done.
        #current_line is either '+ title #:' or 'HandBrake has exited.'
        current_dvd.titles.append(current_title)

    return current_dvd

if __name__ == '__main__':
    g=parseDVD('/mnt/cluster-programs/handbrake/jobs/tmp')
    print(g)


#!/usr/bin/env python3

from setuptools import find_packages
from setuptools import setup

# Long description
with open("README.md", encoding="utf-8") as f:
    readme = f.read()

# Requirements
with open("requirements.txt", encoding="utf-8") as f:
    requirements = [
        x for x in map(str.strip,
                       f.read().splitlines()) if x and not x.startswith("#")
    ]

setup(
    name='ar',
    version='1.0',
    author='Guillem Orellana Trullols',
    author_email='guillem.orellana@gmail.com',
    url='https://github.com/Guillem96/activity-recognition',
    description='PyTorch utilities to democratize human activity recognition '
    'on videos',
    long_description=readme,
    keywords='activity-recognition 3d-conv c3d human pytorch deep-learning',
    install_requires=requirements,
    packages=find_packages(),
    zip_safe=True,
    classifiers=[
        'Development Status :: 3 - Alpha',
        'Intended Audience :: Developers',
        'Intended Audience :: Science/Research',
        'Natural Language :: English',
        'Programming Language :: Python :: 3',
        'Operating System :: OS Independent',
        'Topic :: Scientific/Engineering',
        'Topic :: Scientific/Engineering :: Artificial Intelligence',
    ],
)


#输入一个整数数组，实现一个函数来调整该数组中数字的顺序，使得所有的奇数位于数组的前半部分，所有的偶数位于数组的后半部分，
# 并保证奇数和奇数，偶数和偶数之间的相对位置不变。
def reOrderArray(array):
    new_array_1 = []
    new_array_2 = []
    for item in array:
        if item%2 == 0:
            new_array_1.append(item)
        else:
            new_array_2.append(item)

    return new_array_1+new_array_2

if __name__ == '__main__':
    list_data1 = [2, 3, 4, 5, 5, 6, 6, 662, 200]
    array = reOrderArray(list_data1)
    print(array)

剑指Offer/调整数组顺序使奇数位于偶数前面.py

调整数组顺序使奇数位于偶数前面.py