import os

from django.conf import settings
from django.conf.urls import patterns, url
from django.contrib.admin import ModelAdmin
from django.contrib.admin.options import csrf_protect_m
from django.contrib.admin.util import unquote
from django.contrib.admin.views.main import IS_POPUP_VAR
from django.contrib.staticfiles.templatetags.staticfiles import static
from django.core.exceptions import PermissionDenied, ViewDoesNotExist
from django.core.urlresolvers import reverse
from django.db import transaction
from django.http import Http404, HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render_to_response
from django.utils.translation import ugettext, ugettext_lazy as _

from media_tree import settings as app_settings
from media_tree.admin.actions import core_actions, maintenance_actions
from media_tree.admin.actions.utils import execute_empty_queryset_action
from media_tree.admin.utils import (set_current_request,
                                    get_request_attr, set_request_attr)
from media_tree.admin.views.change_list import SimpleFileNodeChangeList

from ..forms import SimpleFileForm
from ..models import FileNode

def mt_static(url):
    return static(app_settings.MEDIA_TREE_STATIC_SUBDIR + '/' + url)

class BaseFileNodeAdmin(ModelAdmin):
    change_list_template = 'admin/media_tree/filenode/base_change_list.html'

    list_display = app_settings.MEDIA_TREE_LIST_DISPLAY
    list_filter = app_settings.MEDIA_TREE_LIST_FILTER
    #list_display_links = app_settings.MEDIA_TREE_LIST_DISPLAY_LINKS
    search_fields = app_settings.MEDIA_TREE_SEARCH_FIELDS
    ordering = app_settings.MEDIA_TREE_ORDERING_DEFAULT

    _registered_actions = []

    class Media:
        js = [mt_static('lib/jquery/jquery-1.7.1.min.js'),
              mt_static('lib/jquery/jquery.ui.js'),
              mt_static('lib/jquery/jquery.cookie.js'),

              mt_static('lib/fileuploader.js'),
              mt_static('js/admin_enhancements.js'),
              mt_static('js/django_admin_fileuploader.js')]
        css = {'all': (mt_static('css/swfupload.css'),
                       mt_static('css/ui.css'))}

    # URLs

    def get_urls(self):
        urls = super(BaseFileNodeAdmin, self).get_urls()
        info = self.model._meta.app_label, self.model._meta.model_name

        mt_static = os.path.join(settings.STATIC_ROOT,
                                 app_settings.MEDIA_TREE_STATIC_SUBDIR)

        url_patterns = patterns('',

            url(r'^jsi18n/',
                self.admin_site.admin_view(self.i18n_javascript),
                name='media_tree_jsi18n'),

            url(r'^upload/$',
                self.admin_site.admin_view(self.upload_file_view),
                name='%s_%s_upload' % info),

            # Since Flash Player enforces a same-domain policy, the upload
            # will break if static files are served from another domain. So
            # the built-in static file view is used for the uploader SWF:
            url(r'^static/swfupload\.swf$',
                'django.views.static.serve',
                {'document_root': mt_static,
                 'path': 'lib/swfupload/swfupload_fp10/swfupload.swf'},
                name='%s_%s_static_swfupload_swf' % info))
        url_patterns.extend(urls)
        return url_patterns

    # Actions

    @staticmethod
    def register_action(func, required_perms=None):
        BaseFileNodeAdmin._registered_actions.append({
            'action': func,
            'required_perms': required_perms})

    def get_actions(self, request):
        # In ModelAdmin.get_actions(), actions are disabled if the popup var
        # is present. Since BaseFileNodeAdmin always needs a checkbox, this
        # is circumvented here:

        is_popup_var = request.GET.get(IS_POPUP_VAR, None)
        if IS_POPUP_VAR in request.GET:
            request.GET = request.GET.copy()
            del request.GET[IS_POPUP_VAR]

        # get all actions from parent
        actions = super(BaseFileNodeAdmin, self).get_actions(request)

        # and restore popup var
        if is_popup_var:
            request.GET[IS_POPUP_VAR] = is_popup_var

        return actions

    # Misc getters

    def get_changelist(self, request, **kwargs):
        """ Returns the ChangeList class for use on the changelist page. """
        return SimpleFileNodeChangeList

    def get_form(self, request, *args, **kwargs):
        self.fields = self.form.Meta.fields
        return super(BaseFileNodeAdmin, self).get_form(
            request, *args, **kwargs)

    # Add view

    @csrf_protect_m
    @transaction.commit_on_success
    def add_view(self, request, form_url='', extra_context=None):
        if not extra_context:
            extra_context = {}
        extra_context.update({'breadcrumbs_title': _('Add')})

        response = super(BaseFileNodeAdmin, self).add_view(
            request, form_url, extra_context)
        return response

    # Change view

    def change_view(self, request, object_id, extra_context=None):
        try:
            object_id = str(object_id)
            node = get_object_or_404(FileNode, pk=unquote(object_id))
        except ValueError:
            raise Http404
        set_request_attr(request, 'save_node', node)
        if not extra_context:
            extra_context = {}
        extra_context.update({'node': node,})
        return super(BaseFileNodeAdmin, self).change_view(\
            request, object_id, extra_context=extra_context)

    # Changelist view

    def get_changelist_view_options(self, request):
        extra_context = {}

        if app_settings.MEDIA_TREE_SWFUPLOAD:
            app, model = \
                self.model._meta.app_label, self.model._meta.model_name

            extra_context.update({
                'file_types': app_settings.MEDIA_TREE_ALLOWED_FILE_TYPES,
                'file_size_limit': app_settings.MEDIA_TREE_FILE_SIZE_LIMIT,
                'swfupload_flash_url': reverse(
                    'admin:%s_%s_upload' % (app, model)),
                'swfupload_upload_url': reverse(
                    'admin:%s_%s_static_swfupload_swf' % (app, model))})

        return extra_context

    def changelist_view(self, request, extra_context=None):
        response = execute_empty_queryset_action(self, request)
        if response:
            return response

        set_current_request(request)

        if not extra_context:
            extra_context = {}
        extra_context.update(self.get_changelist_view_options(request))

        if request.GET.get(IS_POPUP_VAR, None):
            extra_context.update({'select_button': True})

        response = super(BaseFileNodeAdmin, self) \
            .changelist_view(request, extra_context)
        return response

    # Upload view

    @csrf_protect_m
    @transaction.commit_on_success
    def upload_file_view(self, request):
        """ The upload view is exempted from CSRF protection since SWFUpload
            cannot send cookies (i.e. it can only send cookie values as POST
            values, but that would render this check useless anyway). However,
            Flash Player should already be enforcing a same-domain policy. """

        try:
            if not self.has_add_permission(request):
                raise PermissionDenied

            FILE_PARAM_NAME = 'qqfile'
            self.init_parent_folder(request)

            if request.method == 'POST':

                if request.is_ajax() and request.GET.get(FILE_PARAM_NAME, None):
                    content_file = ContentFile(request.body)
                    uploaded_file = UploadedFile(
                        content_file, request.GET.get(FILE_PARAM_NAME), None,
                        content_file.size)
                    form = UploadForm(request.POST, {'file': uploaded_file})
                else:
                    form = UploadForm(request.POST, request.FILES)

                if form.is_valid():
                    node = FileNode(file=form.cleaned_data['file'],
                                    node_type=media_types.FILE)
                    parent_folder = self.get_parent_folder(request)
                    if not parent_folder.is_top_node():
                        node.parent = parent_folder
                    self.save_model(request, node, None, False)
                    # Respond with 'ok' for the client to verify that the
                    # upload was successful, since sometimes a failed request
                    # would not result in a HTTP error and look like a
                    # successful upload. For instance: When requesting the
                    # admin view without authentication, there is a redirect
                    # to the login form, which to SWFUpload looks like a
                    # successful upload request.
                    if request.is_ajax():
                        return HttpResponse(
                            '{"success": true}',
                            content_type="application/json")
                    else:
                        messages.info(
                            request,
                            _('Successfully uploaded file %s.') % node.name)
                        return HttpResponseRedirect(
                            reverse('admin:%s_%s_changelist' % (
                                self.model._meta.app_label,
                                self.model._meta.model_name)))
                else:
                    # invalid form data
                    if request.is_ajax():
                        return HttpResponse('{"error": "%s"}' % ' '.join(
                            [item for sublist in
                             form.errors.values() for item in sublist]),
                            content_type="application/json")

            # Form is rendered for troubleshooting SWFUpload. If this form
            # works, the problem is not server-side.
            if not settings.DEBUG:
                raise ViewDoesNotExist
            if request.method == 'GET':
                form = UploadForm()
            return render_to_response(
                'admin/media_tree/filenode/upload_form.html', {'form': form})

        except Exception as e:
            if request.is_ajax():
                return HttpResponse('{"error": "%s"}' % ugettext('Server Error'),
                    content_type="application/json")
            else:
                raise

    def i18n_javascript(self, request):
        """ Displays the i18n JavaScript that the Django admin requires.

            This takes into account the USE_I18N setting. If it's set to False,
            the generated JavaScript will be leaner and faster. """
        return javascript_catalog(request, packages=['media_tree'])

BaseFileNodeAdmin.register_action(core_actions.copy_selected)
BaseFileNodeAdmin.register_action(maintenance_actions.delete_orphaned_files,
                                  ('media_tree.manage_filenode',))
BaseFileNodeAdmin.register_action(maintenance_actions.clear_cache,
                                  ('media_tree.manage_filenode',))


from elasticsearch import Elasticsearch
import json
import string

def strip_punctuation(s):
    """Remove special characters and digits
    from a string.
    """
    sub1 = ''.join(c for c in s if c not in string.punctuation )
    return ''.join(c for c in sub1 if not c.isdigit())

# Set-up and define elasticsearch
es = Elasticsearch([{'host': 'localhost', 'port': 9200}])

# Get the query through system input
query = input()

def getAnswers(query):
    """Process a query in several steps and layers.
    Return a question to the user.
    """
    # An array with all unnecessary terms to be removed
    # from a query/answer
    stupidwords = ["och", "det", "att", "i", "en",
            "jag", "hon", "som", "han", "på", "den", "med", "var", "sig",
            "för", "så", "till", "är", "men", "ett", "om", "hade", "de", "av",
            "icke", "mig", "du", "henne", "då", "sin", "nu", "har", "inte",
            "hans", "honom", "skulle", "hennes", "där", "min", "man", "ej",
            "vid", "kunde", "något", "från", "ut", "när", "efter", "upp", "vi",
            "dem", "vara", "vad", "över", "än", "dig", "kan", "sina", "här",
            "ha", "mot", "alla", "under", "någon", "eller", "allt", "mycket",
            "sedan", "ju", "denna", "själv", "detta", "åt", "utan", "varit",
            "hur", "ingen", "mitt", "ni", "bli", "blev", "oss", "din", "dessa",
            "några", "deras", "blir", "mina", "samma", "vilken", "er", "sådan",
            "vår", "blivit", "dess", "inom", "mellan", "sådant", "varför",
            "varje", "vilka", "ditt", "vem", "vilket", "sitta", "sådana",
            "vart", "dina", "vars", "vårt", "våra", "ert", "era", "vilkas",
            "hej","hallå","tja","tjena","tjenare","dvs","osv","etc","","inkl","få","komma",
            "kommer"]

    # --- Pre-process the original query ---
    query = strip_punctuation(query)
    query = query.lower().split(" ")
    query = [word for word in query if word not in stupidwords]
    query = ' '.join(query)
    print(query)
    # -----------------------------

    # --- First search and post-search processing ---
    result = es.search(index="familjeliv", body={"query": {"match": {'question':query}}})
    interest = result['hits']['hits']
    newquery = query
    # Merge original query with at most top 5 questions
    # returned by elasticsearch
    for i in range(len(interest) if len(interest) < 5 else 5):
        score = interest[i]['_score']
        if(score > 1): #Filter-out terribly bad results
            newquery = newquery + ' '+interest[i]['_source']['question']
    # -----------------------------------------------

    # --- Pre-process the extended query ---
    newquery = strip_punctuation(newquery)
    newquery = newquery.lower().split(' ')
    finalresult = [word for word in newquery if word not in stupidwords]
    finalresult = ' '.join(finalresult)
    # --------------------------------------

    # --- Second search and extraction ---
    result1 = es.search(index="familjeliv", body={"query": {"match": {'question': finalresult}}})
    interest = result1['hits']['hits']
    #newquery = query
    final_answers = interest[0]['_source']['answers']
    # ------------------------------------

    # --- Create weights-system for terms ---
    finalresultarray = finalresult.split(" ") # Split extended query
    minHaspmap = {}
    for word in finalresultarray:
        if word in minHaspmap:
            minHaspmap[word] = minHaspmap[word] +1
        else:
            minHaspmap[word] = 1

    for word in query.lower().split(' '): #Split original query
        if word not in stupidwords:
            minHaspmap[word] = minHaspmap[word] + 1000
    # --------------------------------------

    # --- Answer processing ---
    score = -1
    ans = ""
    for answer in final_answers:
        answerlist = answer.lower().split(' ')
        tempscore = 0
        relevantwords = 0
        for word in answerlist:
            if word in minHaspmap:
                tempscore = tempscore + minHaspmap[word]
                relevantwords = relevantwords + 1
            if "?" in word: # Punish question marks
                tempscore = -999999
        tempscore = tempscore/len(answerlist) # Normalize score
        if score < tempscore: # Keep track of best answer
            ans = answer
            score = tempscore
    # --------------------------

    # --- Flagging and return ---
    finalans = {"answer":ans,"confidence":1 if score>=1 else 0} # Signal if good/bad answer
    return finalans
    # ---------------------------
out = getAnswers(query)
print(out)


# -*- coding:utf-8 -*-
#创作漫画单篇--》小铅笔--》漫画--》画漫画--》新增单篇--》添加角色--》改变角色方向--》添加素材--》保存
import unittest
from ddt import ddt, data, unpack
from base import base_desired_caps,public_choice,interrupt
from page import createComicPage

@ddt
class MyTestCase(unittest.TestCase):
    def setUp(self):
        base_desired_caps.base_desired_caps(self)
        interrupt.interrupt(self)

    # @data(
    #     ('public', True),
    #     ('draft', True),
    #     ('draft', True),
    #     ('serials',True)
    # )
    @data(
        ('draft', True)
    )
    @unpack
    # 画漫画流程
    def test_creation(self, input,expectedresult):
        exist=createComicPage.createComic(self)
        if input=='draft':
            public_choice.publicAsDraft(self)
        elif input=='public':
            public_choice.publicAsOffice(self)
        elif input == 'serials':
            public_choice.addComicSerials(self)

        try:
            return exist == True
        except Exception:
            print("ERROR")
        self.assertEqual(exist, expectedresult)

    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    unittest.main()


#!/usr/local/bin/python3
# -*- coding: UTF-8 -*-

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import sys
import threading
import random
from datetime import datetime

import numpy as np
from six.moves import xrange
import xml.etree.ElementTree as xml_parser

import tensorflow as tf

# 设置日志级别。
tf.logging.set_verbosity(tf.logging.INFO)

def convert2_int64_feature(value):
    """ 将 int64 类型值，包装成训练样本的格式 """
    if not isinstance(value, list):
        value = [value]
    return tf.train.Feature(int64_list=tf.train.Int64List(value=value))

def convert2_float_feature(value):
    """ 将 float 类型值，包装成训练样本的格式 """
    if not isinstance(value, list):
        value = [value]
    return tf.train.Feature(float_list=tf.train.FloatList(value=value))

def convert2_bytes_feature(value):
    """ 将 bytes 类型值，包装成训练样本的格式 """
    return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))

def convert2_train_example(filename, image_buffer, label, synset, human, bbox,
                           height, width):
    """
    将一个图像转换成一个训练样本。

    @param filenames: 字符串列表。每个字符串代表一个图片文件。
    @param image_buffer: 字符串。JPEG编码的RGB图像。
    @param labels: 整数列表。每个整数代表一个图片的类别。
    @param synsets: 字符串列表。每个字符串代表一个同义词标识（WordNet ID）。
    @param humans: 字符串列表。每个字符串代表一个可读的类别名称。
    @param bbox: 边界框列表，每个图像有0个或者多个边界框，每个边界框都由
      [xmin, ymin, xmax, ymax]组成
    @param height: 整型, 图像的高度（像素）
    @param width: 整型, 图像的宽度（像素）

    @Returns: proto格式的样本数据
    """

    xmin = []
    ymin = []
    xmax = []
    ymax = []
    for b in bbox:
        [l.append(point) for l, point in zip([xmin, ymin, xmax, ymax], b)]

    # 如果没有读取到对象边界框，那么，返回None
    if len(xmin) == 0:
        return None

    colorspace = 'RGB'
    channels = 3
    image_format = 'JPG'

    example = tf.train.Example(features=tf.train.Features(feature={
        'image/height': convert2_int64_feature(height),
        'image/width': convert2_int64_feature(width),
        'image/colorspace': convert2_bytes_feature(colorspace.encode()),
        'image/channels': convert2_int64_feature(channels),
        'image/class/label': convert2_int64_feature(label),
        'image/class/synset': convert2_bytes_feature(synset.encode()),
        'image/class/text': convert2_bytes_feature(human.encode()),

        # 一个图片中，包含多个对象边界框时，是将所有的 xmin 放在一个列表中，同理，
        # 将所有的 xmax、ymin、ymax 也放在一个列表内
        'image/object/bbox/xmin': convert2_int64_feature(xmin),
        'image/object/bbox/xmax': convert2_int64_feature(xmax),
        'image/object/bbox/ymin': convert2_int64_feature(ymin),
        'image/object/bbox/ymax': convert2_int64_feature(ymax),

        # 每个对象边界框，都对应一个 label，
        'image/object/bbox/label': convert2_int64_feature([label] * len(xmin)),
        'image/format': convert2_bytes_feature(image_format.encode()),
        'image/filename': convert2_bytes_feature(
            os.path.basename(filename).encode()),
        'image/encoded': convert2_bytes_feature(image_buffer)}
    ))
    return example

class JpegImageCoder(object):
    """ ImageNet数据读取时解码用工具类 """

    def __init__(self):
        # 为图像编码单独创建一个会话
        self._sess = tf.Session()

        # 将PNG图像转换成JPEG格式图片的功能函数
        self._png_data = tf.placeholder(dtype=tf.string)
        image = tf.image.decode_png(self._png_data, channels=3)
        self._png_to_jpeg = tf.image.encode_jpeg(
            image, format='rgb', quality=100)

        # 将 CMYK 图像转换成 RGB JPEG 格式图片的功能函数
        self._cmyk_data = tf.placeholder(dtype=tf.string)
        image = tf.image.decode_jpeg(self._cmyk_data, channels=0)
        self._cmyk_to_rgb = tf.image.encode_jpeg(
            image, format='rgb', quality=100)

        # 初始化解码 RGB JPEG 图像函数
        self._decode_jpeg_data = tf.placeholder(dtype=tf.string)
        self._decode_jpeg = tf.image.decode_jpeg(
            self._decode_jpeg_data,
            # 有时候，JPEG图片没有完全下载，无法完美解析，所以，
            # 让 decode_jpeg 容忍一定程度的异常和错误，提高适应性
            # 代价是，会降低最终的模型识别准确率降低。
            try_recover_truncated=True,
            acceptable_fraction=0.75,
            channels=3)

    # 将 PNG 格式转换成 JPEG 格式
    def png_to_jpeg(self, image_data):
        return self._sess.run(self._png_to_jpeg,
                              feed_dict={self._png_data: image_data})

    # 将 CMYK 格式转换成 JPEG 格式
    def cmyk_to_rgb(self, image_data):
        return self._sess.run(self._cmyk_to_rgb,
                              feed_dict={self._cmyk_data: image_data})

    # 将 JPEG 图像文件编码成二进制格式
    def decode_jpeg(self, image_data):
        image = self._sess.run(self._decode_jpeg,
                               feed_dict={self._decode_jpeg_data: image_data})
        assert len(image.shape) == 3
        assert image.shape[2] == 3
        return image

def _is_png(filename):
    """
    检测一个图像文件是否是 PNG 格式。

    @param filenames: 字符串列表。每个字符串代表一个图片文件。

    @Returns: 布尔值，表明该图标是否是 PNG 格式的图像。
    """

    # 文件列表来源自:
    # https://groups.google.com/forum/embed/?place=forum/torch7#!topic/torch7/fOSTXHIESSU
    # 请注意：文件名后缀的大小写。'jpeg' vs 'jpg'
    return 'n02105855_2933.jpg' in filename

def _is_cmyk(filename):
    """
    检测图像文件是否使用一个CMYK 色彩看空间的 JPEG 图像。

    @param filenames: 字符串列表。每个字符串代表一个图片文件。

    @Returns: 布尔值，表明该图标是否是 采用 CMYK 色彩看空间的 JPEG 图像编码。
    """

    # 文件列表来源自:
    # https://github.com/cytsai/ilsvrc-cmyk-image-list
    # 请注意：文件名后缀的大小写。
    blacklist = ['n01739381_1309.jpg', 'n02077923_14822.jpg',
                 'n02447366_23489.jpg', 'n02492035_15739.jpg',
                 'n02747177_10752.jpg', 'n03018349_4028.jpg',
                 'n03062245_4620.jpg', 'n03347037_9675.jpg',
                 'n03467068_12171.jpg', 'n03529860_11437.jpg',
                 'n03544143_17228.jpg', 'n03633091_5218.jpg',
                 'n03710637_5125.jpg', 'n03961711_5286.jpg',
                 'n04033995_2932.jpg', 'n04258138_17003.jpg',
                 'n04264628_27969.jpg', 'n04336792_7448.jpg',
                 'n04371774_5854.jpg', 'n04596742_4225.jpg',
                 'n07583066_647.jpg', 'n13037406_4650.jpg']
    return os.path.basename(filename) in blacklist

def process_single_image(filename, coder):
    """
    读取一个单一的图像文件，转换成 JPG 格式。

    @param filenames: 字符串列表。每个字符串代表一个图片文件。
    @param coder: ImageCoder的实例，用于读取图片、或者对图片进行解码。

    @Returns:
      image_buffer: 字符串。JPEG编码的RGB图像。
      height: 整型, 图像的高度（像素）。
      width: 整型, 图像的宽度（像素）。
    """
    # 读取图像文件
    image_data = tf.gfile.FastGFile(filename, 'rb').read()

    # 判断图像是否是 PNG 格式
    if _is_png(filename):
        # 1 将图像从 PNG 格式转换成 JPEG 格式
        print('将图像从 PNG 转换成 JPEG 格式 %s' % filename)
        image_data = coder.png_to_jpeg(image_data)

    # 判断图像是否是 CMYK 格式
    elif _is_cmyk(filename):
        # 22 将图像从 CMYK 格式转换成 JPEG 格式
        print('将图像从 CMYK 转换成 RGB 格式 %s' % filename)
        image_data = coder.cmyk_to_rgb(image_data)

    # 按照 RGB 格式，对图像数据进行解码
    image = coder.decode_jpeg(image_data)

    assert len(image.shape) == 3
    height = image.shape[0]
    width = image.shape[1]
    assert image.shape[2] == 3

    return image_data, height, width

def process_batch_images(coder, thread_index, ranges, name, filenames,
                         synsets, labels, humans, bboxes, num_shards):
    """
    处理图片并且将图片转换成为 TFRecord 的单个线程。

    @param coder: ImageCoder的实例，用于读取图片、或者对图片进行解码。
    @param thread_index: 整型，一个批次中的索引值，取值范围[0, len(ranges)).
    @param ranges: 两个整型数值，表示并行处理过程中一个批次的范围。
    @param name: 字符串，唯一标识数据集。
    @param filenames: 字符串列表。每个字符串代表一个图片文件。

    @param synsets: 字符串列表。每个字符串代表一个同义词标识（WordNet ID）。
    @param labels: 整数列表。每个整数代表一个图片的类别。
    @param humans: 字符串列表。每个字符串代表一个可读的类别名称。
    @param bboxes: 边界框列表，每个图像有0个或者多个边界框。
    @param num_shards: 数据分片，并行处理时每个批次处理的图片个数。
    """

    # 每个线程处理 N 份数据， 其中，N = int(num_shards / num_threads).
    # 例如，如果每个分片含128个图片（num_shards = 128），采用两个线程并行处理
    # （um_threads = 2），那么，第一个线程处理的分片范围 [0, 64)
    num_threads = len(ranges)
    num_shards_per_batch = int(num_shards / num_threads)

    # 每个分片的范围，在每个线程分得的任务内，再次分片
    # 对于 ImageNet 来说，训练集包含大约100万个样本图片，如果采用 10 个线程并行处理
    # 那么，每个线程大约分得10多万个图片数据，在线程内，需要将本线程获得的任务再次分片
    shard_ranges = np.linspace(ranges[thread_index][0],
                               ranges[thread_index][1],
                               num_shards_per_batch + 1).astype(int)
    # 每个线程处理的图片数量
    num_files_in_thread = ranges[thread_index][1] - ranges[thread_index][0]

    counter = 0

    # s 是图片文件的索引
    for idx in xrange(num_shards_per_batch):
        # 生成一个数据分片，将一个数据分片的中包含的图片数据、标签数据、对象边界框转换成TFRecord
        # 然后，保存到一个样本文件中，例如，'train-00002-of-00010'
        shard = thread_index * num_shards_per_batch + idx
        output_filename = '%s-%.5d-of-%.5d' % (name, shard, num_shards)

        # 根据不同的数据集名称，将结果文件保存到对应的文件夹
        output_file = os.path.join(data_dir, name, output_filename)

        # 将样本数据写入到对应的样本数据文件的句柄
        writer = tf.python_io.TFRecordWriter(output_file)

        shard_counter = 0
        files_in_shard = np.arange(
            shard_ranges[idx], shard_ranges[idx + 1], dtype=int)
        for i in files_in_shard:
            filename = filenames[i]
            label = labels[i]
            synset = synsets[i]
            human = humans[i]
            bbox = bboxes[i]

            # 读取图片的内容，一律转换成为 JPG 格式
            image_buffer, height, width = process_single_image(filename, coder)

            # 将图片转换成为训练样本，TFRecord
            example = convert2_train_example(
                filename, image_buffer, label, synset, human,
                bbox, height, width)

            if example is not None:
                # 写入 TFRecord 格式的训练样本中
                # 每个训练样本中包含 num_shards 个图片文件
                writer.write(example.SerializeToString())
                shard_counter += 1
                counter += 1

            # 每处理 1000 个图片文件，
            if not counter % 1000:
                msg = "{} [{}]: 正在处理第 {}/{} 个图像".format(
                    datetime.now(), thread_index, counter,
                    num_files_in_thread)
                print(msg)
                sys.stdout.flush()

            writer.close()

        print('%s [线程 %d]: 已经将 %d 个图片写入 %s' %
              (datetime.now(), thread_index, shard_counter, output_file))
        sys.stdout.flush()
        shard_counter = 0

    print('\n%s [线程 %d]: 已经将 %d 个图片写入 %d 数据分片中.' %
          (datetime.now(), thread_index, counter, num_files_in_thread))
    sys.stdout.flush()

def build_human_labels(synsets, human_readable_labels):
    """
    构建可读标签的列表。

    @param synsets: 字符串列表。每个字符串代表一个同义词标识（WordNet ID）。
    @param synset_to_human: 字典。从图片所属的类别到可读的类别映射，例如：
      'n02119022' --> 'red fox, Vulpes vulpes'

    @Returns: 与同义词一一对应的刻度标签列表。
    """
    humans = []
    for s in synsets:
        assert s in human_readable_labels, ('没有找到: %s的可读标签。' % s)
        humans.append(human_readable_labels[s])
    return humans

def build_bounding_boxes(filenames, image_to_bboxes):
    """
    给定一个图片，读取它所包含的对象边界框列表。

    @param filenames: 字符串列表。每个字符串代表一个图像的文件名称。
    @param image_to_bboxes: 字典，从图像文件名到对象边界框列表的映射，列表中
        可以包含0个或者多个对象边界框。

    @Returns:
      针对每一个图像的对象边界框列表，每一个图片都可以包含多个对象边界框。
    """
    num_image_bbox = 0
    bboxes = []
    for f in filenames:
        # 字典的 key， 本例中采用文件的 basename
        basename = os.path.basename(f)

        if basename in image_to_bboxes:
            bboxes.append(image_to_bboxes[basename])
            num_image_bbox += 1

        # 如果 image_to_bboxes 中没有该文件的对象边界框，那么，
        # 创建一个空的对象边界框列表（对应于该图像中没有对象边界框）
        # 或者 该图像中有对象，但是却没有为它创建对象边界框
        else:
            bboxes.append([])

    print('找到 %d 个图片的共计 %d 对象边界框' % (
        len(filenames), num_image_bbox))

    return bboxes

def process_imagenet_images(name, filenames, synsets, labels, humans,
                            bboxes, num_shards):
    """
    处理所有的图像，并且，将图像转换成为 TFRecord 格式，保存起来。

    @param name: 字符串。数据集的唯一标识。
    @param filenames: 字符串列表。每个字符串代表一个图像的文件名称。
    @param synsets: 字符串列表。每个字符串代表一个同义词标识（WordNet ID）。
    @param labels: 整数列表。每个整数代表一个图片的类别。
    @param humans: 字符串列表。每个字符串代表一个可读的类别名称。
    @param bboxes: 边界框列表，每个图像有0个或者多个边界框。
    @param num_shards: 并行处理时每个形成处理的图片个数.
    """
    assert len(filenames) == len(synsets)
    assert len(filenames) == len(labels)
    assert len(filenames) == len(humans)
    assert len(filenames) == len(bboxes)

    # 按照并行线程的数量，将图像数据分成多个分片
    spacing = np.linspace(
        0, len(filenames), num_threads + 1).astype(np.int)
    ranges = []
    threads = []

    # 计算每个分片的起止范围
    # 每个批次的起止范围 [ranges[i][0], ranges[i][1]].
    # 例如，总样本数量是130万个，线程数量是10个，那么，每个线程处13万个图片
    # 因为, 线程数量是10个，所以，len(ranges) = 10。
    # 对应的，ranges[0][0] = 0, ranges[0][1] = 130000。
    # 对应的，ranges[1][0] = 130001, ranges[1][1] = 160000。
    #           ……
    #        åranges[9][0] = 1170001, ranges[9][1] = 1300000
    for i in xrange(len(spacing) - 1):
        ranges.append([spacing[i], spacing[i+1]])

    # 加载一个线程，处理一个批次数据
    print('启动第 {}个线程，处理 {} 批次数据'.format(num_threads, ranges))
    sys.stdout.flush()

    # 启动线程同步机制，监控等到所有的线程执行完毕
    coord = tf.train.Coordinator()

    # 创建一个图像编码器
    coder = JpegImageCoder()

    threads = []
    for thread_index in xrange(len(ranges)):
        # 每个线程的参数
        args = (coder, thread_index, ranges, name, filenames,
                synsets, labels, humans, bboxes, num_shards)
        # 创建线程，指定参数
        t = threading.Thread(target=process_batch_images, args=args)
        # 启动线程
        t.start()
        threads.append(t)

    # 将线程加入到同步机制中，确保所有线程执行完毕
    coord.join(threads)

    print('%s: 执行完毕，已经将所有的，共 %d 个图片保存到数据集中。' %
          (datetime.now(), len(filenames)))
    sys.stdout.flush()

def process_imagenet(name, num_shards, synset_to_human):
    """
    处理 ImageNet 数据集。

    @param name: 字符串。数据集名称，如 训练集train、验证集validation。
    @param num_shards: 数据集分成几个分片来处理，每个分片处理多少个图片.
    @param synset_to_human: 字典。从图片所属的类别到可读的类别映射，例如：
      'n02119022' --> 'red fox, Vulpes vulpes'
    """
    filenames, synsets, labels = find_image_files(
        data_dir, labels_file)
    image_to_bboxes = read_annotation_file(filenames)
    if len(image_to_bboxes) > 0:
        humans = build_human_labels(synsets, synset_to_human)
        bboxes = build_bounding_boxes(filenames, image_to_bboxes)
        process_imagenet_images(name, filenames, synsets, labels,
                                humans, bboxes, num_shards)
    else:
        print("没有找到对象边界框！")

def find_image_files(data_dir, labels_file):
    """
    读取 ImageNet 图片数据集。

    @param data_dir: 字符串. ImageNet图片集所在的本地目录。
    图片文件名称的格式如下所示：
        ${data_dir}/images/n02084071/n02084071_7.JPG
        ${data_dir}/images/n02084071/n02084071_60.JPG
    其中，n02084071 代表图片所属的类别（同义词 ID）

    一个图片中会包含多个对象，对象所在的位置大小、类别数据，保存在如下XML文件中：
        ${data_dir}/annotation/n02084071/n02084071_7.xml
        ${data_dir}/annotation/n02084071/n02084071_60.xml
    其中，n02084071 代表图片所属的类别（同义词 ID）

    @param labels_file: 字符串。包含类别名称的文本文件，每一行代表一个类别，如：
        n02084071
        n04067472
        n04540053

    @Returns:
      filenames: 字符串列表; 每个字符串代表一个图片文件的名称.
      synsets: 字符串列表; 每个字符串是一个同义词唯一标识（WordNet ID）.
      labels: 整数列表; 代表图片所属的类别.
    """

    labels_file = os.path.join(data_dir, labels_file)
    challenge_synsets = [l.strip() for l in
                         tf.gfile.FastGFile(labels_file, 'r').readlines()]

    labels = []
    filenames = []
    synsets = []

    # Label索引，索引0保留
    label_index = 1

    # 构建图片文件名称列表和对应的labels列表
    for synset in challenge_synsets:
        jpeg_file_path = os.path.join(data_dir, 'images', synset)
        # 如果，${data_dir}/images/${synset} 文件夹不存在
        # 说明该同义词对应的图片都不存在，略过
        if not os.path.exists(jpeg_file_path):
            print("路径：{} 不存在".format(jpeg_file_path))
            continue

        # 找到指定路径下的所有“*.jpg”图片
        jpeg_file_path = os.path.join(jpeg_file_path, '*.jpg')
        matching_files = tf.gfile.Glob(jpeg_file_path)

        labels.extend([label_index] * len(matching_files))
        synsets.extend([synset] * len(matching_files))
        filenames.extend(matching_files)

        if not label_index % 100:
            print('共找到 {} 个类别 {} 个文件.'.format(
                label_index, len(challenge_synsets)))
        label_index += 1

    # 对图片进行乱序操作，让模型训练保证足够的多样性
    shuffled_index = list(range(len(filenames)))
    random.seed(12345)
    random.shuffle(shuffled_index)

    filenames = [filenames[i] for i in shuffled_index]
    synsets = [synsets[i] for i in shuffled_index]
    labels = [labels[i] for i in shuffled_index]

    print('在 {} 文件夹下，查找 {} 类别图片，共找到 {} 个图片文件。'.format
          (data_dir, len(challenge_synsets), len(filenames)))
    return filenames, synsets, labels

def read_synset_map(synset_to_human_file):
    """
    生成图片 类别ID 与 所属类别名称的映射。

    @synset_to_human_file: 字符串。包含图片类别ID 与 类别映射数据的文件.
    文件内容如下所示:
          n02119247    black fox
          n02119359    silver fox
          n02119477    red fox, Vulpes fulva

    每行包含一个映射关系，格式如：
    <同义词标识>\t<可读的类别名称>.

    @Returns:
      类别ID 到 类别名称的字典
    """

    # 读取文件内容
    synset_to_human_file = os.path.join(data_dir, synset_to_human_file)
    lines = tf.gfile.FastGFile(synset_to_human_file, 'r').readlines()
    # 要返回的 { 类别标识 -> 类别名称的 } 字典
    synset_to_human = {}
    for line in lines:
        if line:
            parts = line.strip().split('\t')
            assert len(parts) == 2
            synset = parts[0]
            human = parts[1]
            synset_to_human[synset] = human

    return synset_to_human

def read_annotation_file(image_files):
    """
    读取各个图片中包含所有对象的框，返回根据文件名称到框的映射。

    @param image_files: 字符串列表。图片文件名称列表。
    每个文件名称形如：n02084071_79.jpg，每个图片对应的有一个annotation文件
    位于： ${data_dir}/annotation/${synset}/${synset}_*.xml

    该XML文件中包含0个或者多个对象，所包含的对象大小为：

    <object>
      <name>n02084071</name>
      <pose>Unspecified</pose>
      <truncated>0</truncated>
      <difficult>0</difficult>
      <bndbox>
        <xmin>0</xmin>
        <ymin>102</ymin>
        <xmax>182</xmax>
        <ymax>387</ymax>
      </bndbox>
    </object>

    @Returns:
      图片到该图片所包含的对象框列表的字典
    """
    images_to_bboxes = {}
    num_bbox = 0
    num_image = 0
    for image_filename in image_files:
        image_basename = os.path.basename(image_filename)
        tmp = os.path.splitext(image_basename)[0]
        synset = tmp[0:tmp.index('_')]
        xml_file = "./data/imagenet/annotation/{}/{}.xml".format(
            synset, tmp)
        if not tf.gfile.Exists(xml_file):
            print("图片 {} 对应的 annotation： {} 文件不存在".format(
                image_basename, xml_file))
            continue

        if xml_file:
            # 解析XML文件
            xmldoc = xml_parser.parse(xml_file)

            # 读取所有的对象列表
            object_list = xmldoc.findall('object')

            # 读取该对象坐标的对标位置（对应的像素）
            for object_element in object_list:
                xmin = int(object_element.find('bndbox/xmin').text)
                ymin = int(object_element.find('bndbox/ymin').text)
                xmax = int(object_element.find('bndbox/xmax').text)
                ymax = int(object_element.find('bndbox/ymax').text)

            # 对象所在的边界框
            box = [xmin, ymin, xmax, ymax]

            # 以图片文件的basename为主键，是包含'.jpg'的后缀的
            if image_basename not in images_to_bboxes:
                images_to_bboxes[image_basename] = []
                num_image += 1

            # 图片到 边界框的映射（Map）
            images_to_bboxes[image_basename].append(box)
            num_bbox += 1

        print('针对图片文件{}, 读取到 {} 个对象'.format(
            image_basename, len(images_to_bboxes[image_basename])))

    return images_to_bboxes

def process_imagenet_data():
    """

    @Returns:
      图片到该图片所包含的对象框列表的字典
    """

    # Build a map from synset to human-readable label.
    synset_to_human = read_synset_map(synset_to_human_file)

    # 数据分片大小，测试集每个分片包括1024个样本
    train_shards = 1024
    # 验证集中，每个数据分片的大小为128个图片
    validation_shards = 128
    process_imagenet('train', train_shards,
                     synset_to_human)
    process_imagenet('validation',
                     validation_shards, synset_to_human)

# 相关参数
data_dir = './data/imagenet/'
train_dir = './data/imagenet/train/'
validation_dir = './data/imagenet/validation/'
os.makedirs(train_dir, exist_ok=True)
os.makedirs(validation_dir, exist_ok=True)

labels_file = 'synset_list.txt'
synset_to_human_file = 'synset_to_human.txt'

# ImageNet 包含图片大约1.3万个，需要并行处理，本例中采用4个线程变形处理
num_threads = 4

# ImageNet图像数据集文件，生成 TFRecord 格式的训练样本
process_imagenet_data()


# byteplay: CPython assembler/disassembler
# Copyright (C) 2006 Noam Raphael | Version: http://code.google.com/p/byteplay
# Rewritten 2009 Demur Rumed | Version: http://github.com/serprex/byteplay
#                            Screwed the style over, modified stack logic to be more flexible, updated to Python 3
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

__version__ = '0.4'
__all__ = [
    'opmap',
    'opname',
    'opcodes',
    'hasflow',
    'stack_effect',
    'cmp_op',
    'hasarg',
    'hasname',
    'hasjrel',
    'hasjabs',
    'hasjump',
    'haslocal',
    'hascompare',
    'hasfree',
    'hascode',
    'hasconst',
    'Opcode',
    'SetLineno',
    'Label',
    'isopcode',
    'Code']

from sys import version_info
if version_info < (3, 4):
    raise NotImplementedError("Currently only Python versions 3.4 and 3.5 are supported!")

import opcode
from dis import findlabels
from types import CodeType
from enum import Enum

class Opcode(int):
    __str__ = __repr__ = lambda s: opname[s]

opmap = {name.replace('+', '_'): Opcode(code) for name, code in opcode.opmap.items()}
opname = {code: name for name, code in opmap.items()}
opcodes = set(opname)
for cmp_op, hasarg in opmap.items():
    globals()[cmp_op] = hasarg
    __all__.append(cmp_op)
cmp_op = opcode.cmp_op

hasarg = {x for x in opcodes if x >= opcode.HAVE_ARGUMENT}
hasconst = {Opcode(x) for x in opcode.hasconst}
hasname = {Opcode(x) for x in opcode.hasname}
hasjrel = {Opcode(x) for x in opcode.hasjrel}
hasjabs = {Opcode(x) for x in opcode.hasjabs}
hasjump = hasjabs | hasjrel
haslocal = {Opcode(x) for x in opcode.haslocal}
hascompare = {Opcode(x) for x in opcode.hascompare}
hasfree = {Opcode(x) for x in opcode.hasfree}
hascode = {MAKE_FUNCTION, MAKE_CLOSURE}

if version_info.minor > 2:
    STOP_CODE = -1
if version_info.minor < 4:
    _se = {
        IMPORT_FROM: 1,
        DUP_TOP: 1,
        LOAD_CONST: 1,
        LOAD_NAME: 1,
        LOAD_GLOBAL: 1,
        LOAD_FAST: 1,
        LOAD_CLOSURE: 1,
        LOAD_DEREF: 1,
        BUILD_MAP: 1,
        LOAD_BUILD_CLASS: 1,
        YIELD_VALUE: 0,
        UNARY_POSITIVE: 0,
        UNARY_NEGATIVE: 0,
        UNARY_NOT: 0,
        UNARY_INVERT: 0,
        GET_ITER: 0,
        LOAD_ATTR: 0,
        IMPORT_NAME: 0,
        ROT_TWO: 0,
        ROT_THREE: 0,
        NOP: 0,
        DELETE_GLOBAL: 0,
        DELETE_NAME: 0,
        DELETE_FAST: 0,
        STORE_LOCALS: 0,
        IMPORT_NAME: -1,
        POP_TOP: -1,
        PRINT_EXPR: -1,
        IMPORT_STAR: -1,
        DELETE_ATTR: -1,
        STORE_DEREF: -1,
        STORE_NAME: -1,
        STORE_GLOBAL: -1,
        STORE_FAST: -1,
        BINARY_POWER: -1,
        BINARY_MULTIPLY: -1,
        BINARY_FLOOR_DIVIDE: -1,
        BINARY_TRUE_DIVIDE: -1,
        BINARY_MODULO: -1,
        BINARY_ADD: -1,
        BINARY_SUBTRACT: -1,
        BINARY_SUBSCR: -1,
        BINARY_LSHIFT: -1,
        BINARY_RSHIFT: -1,
        BINARY_AND: -1,
        BINARY_XOR: -1,
        BINARY_OR: -1,
        COMPARE_OP: -1,
        INPLACE_POWER: -1,
        INPLACE_MULTIPLY: -1,
        INPLACE_FLOOR_DIVIDE: -1,
        INPLACE_TRUE_DIVIDE: -1,
        INPLACE_MODULO: -1,
        INPLACE_ADD: -1,
        INPLACE_SUBTRACT: -1,
        INPLACE_LSHIFT: -1,
        INPLACE_RSHIFT: -1,
        INPLACE_AND: -1,
        INPLACE_XOR: -1,
        INPLACE_OR: -1,
        LIST_APPEND: -1,
        SET_ADD: -1,
        DELETE_SUBSCR: -2,
        STORE_ATTR: -2,
        STORE_MAP: -2,
        MAP_ADD: -2,
        STORE_SUBSCR: -3}
    _rf = {CALL_FUNCTION: lambda x: -((x & 0xFF00) >> 7) - (x & 0xFF),
           CALL_FUNCTION_VAR_KW: lambda x: -((x & 0xFF00) >> 7) - (x & 0xFF) - 2,
           CALL_FUNCTION_VAR: lambda x: -((x & 0xFF00) >> 7 | 1) - (x & 0xFF),
           CALL_FUNCTION_KW: lambda x: -((x & 0xFF00) >> 7 | 1) - (x & 0xFF),
           RAISE_VARARGS: lambda x: x,
           MAKE_FUNCTION: lambda x: x,
           UNPACK_EX: lambda x: (x & 0xFF) + (x >> 8),
           UNPACK_SEQUENCE: lambda x: x - 1,
           MAKE_CLOSURE: lambda x: x - 1,
           BUILD_TUPLE: lambda x: 1 - x,
           BUILD_LIST: lambda x: 1 - x,
           BUILD_SET: lambda x: 1 - x,
           BUILD_SLICE: lambda x: 1 - x}
    if version_info.minor > 1:
        _se[DUP_TOP_TWO] = 2
        _se[DELETE_DEREF] = 0
    else:
        _se[ROT_FOUR] = 0
        _rf[DUP_TOPX] = lambda x: x

    def stack_effect(op, arg=None):
        if op in _se:
            return _se[op]
        if arg is None:
            raise ValueError("%s requires arg" % op)
        if op in _rf:
            return _rf[op](arg)
        raise ValueError("Unknown %s %s" % (op, arg))
else:
    from dis import stack_effect

hasflow = hasjump | {
    POP_BLOCK,
    END_FINALLY,
    BREAK_LOOP,
    RETURN_VALUE,
    RAISE_VARARGS,
    STOP_CODE,
    POP_EXCEPT}

if version_info < (3, 5):
    hasflow |= {WITH_CLEANUP}
else:
    hasflow |= {WITH_CLEANUP_START, WITH_CLEANUP_FINISH, SETUP_ASYNC_WITH}
    coroutine_opcodes = {GET_AWAITABLE, GET_AITER, GET_ANEXT, BEFORE_ASYNC_WITH, SETUP_ASYNC_WITH}

class Label:
    pass

class SetLinenoType:
    def __repr__(self):
        return 'SetLineno'
SetLineno = SetLinenoType()

def isopcode(x):
    return x is not SetLineno and not isinstance(x, Label)

# Flags for codeobject.co_flags, taken from Include/code.h, other flags are no longer used
CO_OPTIMIZED   = 0x0001
CO_NEWLOCALS   = 0x0002
CO_VARARGS     = 0x0004
CO_VARKEYWORDS = 0x0008
CO_NESTED      = 0x0010
CO_GENERATOR   = 0x0020
CO_NOFREE      = 0x0040

if version_info >= (3, 5):
    CO_COROUTINE          = 0x0080
    CO_ITERABLE_COROUTINE = 0x0100

CO_FUTURE_BARRY_AS_BDFL = 0x40000

if version_info >= (3, 5):
    CO_FUTURE_GENERATOR_STOP = 0x80000

class Code(object):
    """An object which holds all the information which a Python code object
    holds, but in an easy-to-play-with representation

    The attributes are:

    Affecting action
    code - list of 2-tuples: the code
    freevars - list of strings: the free vars of the code (those are names
               of variables created in outer functions and used in the function)
    args - list of strings: the arguments of the code
    kwonly - number of keyword only arguments
    varargs - boolean: Does args end with a '*args' argument
    varkwargs - boolean: Does args end with a '**kwargs' argument
    newlocals - boolean: Should a new local namespace be created
                (True in functions, False for module and exec code)

    force_generator - set CO_GENERATOR in co_flags for generator Code objects without generator-specific code
    Python 3.5:
        force_coroutine - set CO_COROUTINE in co_flags for coroutine Code objects (native coroutines) without coroutine-specific code
        force_iterable_coroutine - set CO_ITERABLE_COROUTINE in co_flags for generator-based coroutine Code objects
        future_generator_stop - set CO_FUTURE_GENERATOR_STOP flag (see PEP-479)

    Not affecting action
    name - string: the name of the code (co_name)
    filename - string: the file name of the code (co_filename)
    firstlineno - int: the first line number (co_firstlineno)
    docstring - string or None: the docstring (the first item of co_consts,
                if it's str)

    code is a list of 2-tuples. The first item is an opcode, or SetLineno, or a
    Label instance. The second item is the argument, if applicable, or None"""

    def __init__(self, code, freevars, args, kwonly, varargs, varkwargs, newlocals,
                 name, filename, firstlineno, docstring,
                 force_generator=False,
                 *, force_coroutine=None, force_iterable_coroutine=None, future_generator_stop=None):
        self.code = code
        self.freevars = freevars
        self.args = args
        self.kwonly = kwonly
        self.varargs = varargs
        self.varkwargs = varkwargs
        self.newlocals = newlocals
        self.name = name
        self.filename = filename
        self.firstlineno = firstlineno
        self.docstring = docstring
        self.force_generator = force_generator
        if version_info < (3, 5):
            # Flags unsupported in earlier versions
            assert force_coroutine is None and force_iterable_coroutine is None and future_generator_stop is None
        else:
            self.force_coroutine = force_coroutine
            self.force_iterable_coroutine = force_iterable_coroutine
            self.future_generator_stop = future_generator_stop

    @staticmethod
    def _findlinestarts(code):
        """Find the offsets in a byte code which are start of lines in the source
        Generate pairs offset,lineno as described in Python/compile.c
        This is a modified version of dis.findlinestarts, which allows multiplelinestarts
        with the same line number"""
        lineno = code.co_firstlineno
        addr = 0
        for byte_incr, line_incr in zip(code.co_lnotab[0::2], code.co_lnotab[1::2]):
            if byte_incr:
                yield addr, lineno
                addr += byte_incr
            lineno += line_incr
        yield addr, lineno

    @classmethod
    def from_code(cls, co):
        """Disassemble a Python code object into a Code object"""
        free_cell_isection = set(co.co_cellvars) & set(co.co_freevars)
        if free_cell_isection:
            print(co.co_name + ': has non-empty co.co_cellvars & co.co_freevars', free_cell_isection)
            return None

        co_code = co.co_code
        labels = {addr: Label() for addr in findlabels(co_code)}
        linestarts = dict(cls._findlinestarts(co))
        cellfree = co.co_cellvars + co.co_freevars
        code = []
        n = len(co_code)
        i = extended_arg = 0
        is_generator = False
        if version_info >= (3, 5):
            is_coroutine = False

        while i < n:
            op = Opcode(co_code[i])
            if i in labels:
                code.append((labels[i], None))
            if i in linestarts:
                code.append((SetLineno, linestarts[i]))
            i += 1
            if op in hascode:
                lastop, lastarg = code[-2]
                if lastop != LOAD_CONST:
                    raise ValueError("%s should be preceded by LOAD_CONST" % op)

                sub_code = Code.from_code(lastarg)
                if sub_code is None:
                    print(co.co_name + ': has unexpected subcode block')
                    return None

                code[-2] = (LOAD_CONST, sub_code)
            if op not in hasarg:
                code.append((op, None))
            else:
                arg = co_code[i] | co_code[i + 1] << 8 | extended_arg
                extended_arg = 0
                i += 2
                if op == opcode.EXTENDED_ARG:
                    extended_arg = arg << 16
                else:
                    byteplay_arg = co.co_consts[arg] if op in hasconst else \
                                   co.co_names[arg] if op in hasname else \
                                   labels[arg] if op in hasjabs else \
                                   labels[i + arg] if op in hasjrel else \
                                   co.co_varnames[arg] if op in haslocal else \
                                   cmp_op[arg] if op in hascompare else \
                                   cellfree[arg] if op in hasfree else \
                                   arg
                    code.append((op, byteplay_arg))

            if op == YIELD_VALUE or op == YIELD_FROM:
                is_generator = True

            if version_info >= (3, 5) and op in coroutine_opcodes:
                is_coroutine = True

        varargs = not not co.co_flags & CO_VARARGS
        varkwargs = not not co.co_flags & CO_VARKEYWORDS
        force_generator = not is_generator and (co.co_flags & CO_GENERATOR)

        if version_info >= (3, 5):
            force_coroutine = not is_coroutine and (co.co_flags & CO_COROUTINE)
            force_iterable_coroutine = co.co_flags & CO_ITERABLE_COROUTINE
            assert not (force_coroutine and force_iterable_coroutine)
            future_generator_stop = co.co_flags & CO_FUTURE_GENERATOR_STOP
        else:
            force_coroutine = None
            force_iterable_coroutine =None
            future_generator_stop = None

        return cls(code=code,
                   freevars=co.co_freevars,
                   args=co.co_varnames[:co.co_argcount + varargs + varkwargs + co.co_kwonlyargcount],
                   kwonly=co.co_kwonlyargcount,
                   varargs=varargs,
                   varkwargs=varkwargs,
                   newlocals=not not co.co_flags & CO_NEWLOCALS,
                   name=co.co_name,
                   filename=co.co_filename,
                   firstlineno=co.co_firstlineno,
                   docstring=co.co_consts[0] if co.co_consts and isinstance(co.co_consts[0], str) else None,
                   force_generator=force_generator,
                   force_coroutine=force_coroutine,
                   force_iterable_coroutine=force_iterable_coroutine,
                   future_generator_stop=future_generator_stop)

    def __eq__(self, other):
        try:
            if (self.freevars != other.freevars or
                    self.args != other.args or
                    self.kwonly != other.kwonly or
                    self.varargs != other.varargs or
                    self.varkwargs != other.varkwargs or
                    self.newlocals != other.newlocals or
                    self.name != other.name or
                    self.filename != other.filename or
                    self.firstlineno != other.firstlineno or
                    self.docstring != other.docstring or
                    self.force_generator != other.force_generator or
                    len(self.code) != len(other.code)):
                return False
            elif version_info >= (3, 5):
                if (self.force_coroutine != other.force_coroutine or
                        self.force_iterable_coroutine != other.force_iterable_coroutine or
                        self.future_generator_stop != other.future_generator_stop):
                    return False

            # This isn't trivial due to labels
            lmap = {}
            for (op1, arg1), (op2, arg2) in zip(self.code, other.code):
                if isinstance(op1, Label):
                    if lmap.setdefault(arg1, arg2) is not arg2:
                        return False
                else:
                    if op1 != op2:
                        return False
                    if op1 in hasjump:
                        if lmap.setdefault(arg1, arg2) is not arg2:
                            return False
                    elif arg1 != arg2:
                        return False

            return True
        except:
            return False

    def _compute_stacksize(self, logging=False):
        code = self.code
        label_pos = {op[0]: pos for pos, op in enumerate(code) if isinstance(op[0], Label)}
        # sf_targets are the targets of SETUP_FINALLY opcodes. They are recorded
        # because they have special stack behaviour. If an exception was raised
        # in the block pushed by a SETUP_FINALLY opcode, the block is popped
        # and 3 objects are pushed. On return or continue, the block is popped
        # and 2 objects are pushed. If nothing happened, the block is popped by
        # a POP_BLOCK opcode and 1 object is pushed by a (LOAD_CONST, None)
        # operation
        # Our solution is to record the stack state of SETUP_FINALLY targets
        # as having 3 objects pushed, which is the maximum. However, to make
        # stack recording consistent, the get_next_stacks function will always
        # yield the stack state of the target as if 1 object was pushed, but
        # this will be corrected in the actual stack recording
        if version_info < (3, 5):
            sf_targets = {label_pos[arg] for op, arg in code
                          if (op == SETUP_FINALLY or op == SETUP_WITH)}
        else:
            sf_targets = {label_pos[arg] for op, arg in code
                          if (op == SETUP_FINALLY or op == SETUP_WITH or op == SETUP_ASYNC_WITH)}

        states = [None] * len(code)
        maxsize = 0

        class BlockType(Enum):
            DEFAULT = 0,
            TRY_FINALLY = 1,
            TRY_EXCEPT = 2,
            LOOP_BODY = 3,
            WITH_BLOCK = 4,
            EXCEPTION = 5,
            SILENCED_EXCEPTION_BLOCK = 6,

        class State:

            def __init__(self, pos=0, stack=(0,), block_stack=(BlockType.DEFAULT,), log=[]):
                self._pos = pos
                self._stack = stack
                self._block_stack = block_stack
                self._log = log

            @property
            def pos(self):
                return self._pos

            @property
            def stack(self):
                return self._stack

            @stack.setter
            def stack(self, val):
                self._stack = val

            def newstack(self, n):
                if self._stack[-1] < -n:
                    raise ValueError("Popped a non-existing element at %s %s" %
                                     (self._pos, code[self._pos - 4: self._pos + 3]))
                return self._stack[:-1] + (self._stack[-1] + n,)

            @property
            def block_stack(self):
                return self._block_stack

            @property
            def log(self):
                return self._log

            def newlog(self, msg):
                if not logging:
                    return None

                log_msg = str(self._pos) + ": " + msg
                if self._stack:
                    log_msg += " (on stack: "
                    log_depth = 2
                    log_depth = min(log_depth, len(self._stack))
                    for pos in range(-1, -log_depth, -1):
                        log_msg += str(self._stack[pos]) + ", "
                    log_msg += str(self._stack[-log_depth])
                    log_msg += ")"
                else:
                    log_msg += " (empty stack)"
                return [log_msg] + self._log

        op = [State()]

        while op:
            cur_state = op.pop()
            o = sum(cur_state.stack)
            if o > maxsize:
                maxsize = o

            o, arg = code[cur_state.pos]

            if isinstance(o, Label):
                if cur_state.pos in sf_targets:
                    cur_state.stack = cur_state.newstack(5)
                if states[cur_state.pos] is None:
                    states[cur_state.pos] = cur_state
                elif states[cur_state.pos].stack != cur_state.stack:
                    check_pos = cur_state.pos + 1
                    while code[check_pos][0] not in hasflow:
                        check_pos += 1
                    if code[check_pos][0] not in (RETURN_VALUE, RAISE_VARARGS, STOP_CODE):
                        if cur_state.pos not in sf_targets:
                            raise ValueError("Inconsistent code at %s %s %s\n%s" %
                                             (cur_state.pos, cur_state.stack, states[cur_state.pos].stack,
                                              code[cur_state.pos - 5:cur_state.pos + 4]))
                        else:
                            # SETUP_FINALLY target inconsistent code!
                            #
                            # Since Python 3.2 assigned exception is cleared at the end of
                            # the except clause (named exception handler).
                            # To perform this CPython (checked in version 3.4.3) adds special
                            # bytecode in exception handler which currently breaks 'regularity' of bytecode.
                            # Exception handler is wrapped in try/finally block and POP_EXCEPT opcode
                            # is inserted before END_FINALLY, as a result cleanup-finally block is executed outside
                            # except handler. It's not a bug, as it doesn't cause any problems during execution, but
                            # it breaks 'regularity' and we can't check inconsistency here. Maybe issue should be
                            # posted to Python bug tracker.
                            pass
                    continue
                else:
                    continue

            if o not in (BREAK_LOOP, RETURN_VALUE, RAISE_VARARGS, STOP_CODE):
                next_pos = cur_state.pos + 1

                if not isopcode(o):
                    op += State(next_pos, cur_state.stack, cur_state.block_stack, cur_state.log),

                elif o not in hasflow:
                    if o in (LOAD_GLOBAL, LOAD_CONST, LOAD_NAME, LOAD_FAST, LOAD_ATTR, LOAD_DEREF,
                             LOAD_CLASSDEREF, LOAD_CLOSURE,
                             STORE_GLOBAL, STORE_NAME, STORE_FAST, STORE_ATTR, STORE_DEREF,
                             DELETE_GLOBAL, DELETE_NAME, DELETE_FAST, DELETE_ATTR, DELETE_DEREF,
                             IMPORT_NAME, IMPORT_FROM, COMPARE_OP):
                        se = stack_effect(o, 0)
                    else:
                        se = stack_effect(o, arg)

                    log = cur_state.newlog("non-flow command (" + str(o) + ", se = " + str(se) + ")")
                    op += State(next_pos, cur_state.newstack(se), cur_state.block_stack, log),

                elif o == FOR_ITER:
                    inside_for_log = cur_state.newlog("FOR_ITER (+1)")
                    op += State(label_pos[arg], cur_state.newstack(-1), cur_state.block_stack, cur_state.log),\
                          State(next_pos, cur_state.newstack(1), cur_state.block_stack, inside_for_log)

                elif o in (JUMP_FORWARD, JUMP_ABSOLUTE):
                    after_jump_log = cur_state.newlog(str(o))
                    op += State(label_pos[arg], cur_state.stack, cur_state.block_stack, after_jump_log),

                elif o in (JUMP_IF_FALSE_OR_POP, JUMP_IF_TRUE_OR_POP):
                    after_jump_log = cur_state.newlog(str(o) + ", jumped")
                    log = cur_state.newlog(str(o) + ", not jumped (-1)")
                    op += State(label_pos[arg], cur_state.stack, cur_state.block_stack, after_jump_log),\
                          State(next_pos, cur_state.newstack(-1), cur_state.block_stack, log)

                elif o in (POP_JUMP_IF_TRUE, POP_JUMP_IF_FALSE):
                    after_jump_log = cur_state.newlog(str(o) + ", jumped (-1)")
                    log = cur_state.newlog(str(o) + ", not jumped (-1)")
                    op += State(label_pos[arg], cur_state.newstack(-1), cur_state.block_stack, after_jump_log),\
                          State(next_pos, cur_state.newstack(-1), cur_state.block_stack, log)

                elif o == CONTINUE_LOOP:
                    next_stack, next_block_stack = cur_state.stack, cur_state.block_stack
                    last_popped_block = None
                    while next_block_stack[-1] != BlockType.LOOP_BODY:
                        last_popped_block = next_block_stack[-1]
                        next_stack, next_block_stack = next_stack[:-1], next_block_stack[:-1]

                    if next_stack != cur_state.stack:
                        log = cur_state.newlog("CONTINUE_LOOP, from non-loop block")
                    else:
                        log = cur_state.newlog("CONTINUE_LOOP")

                    jump_to_pos = label_pos[arg]
                    if last_popped_block == BlockType.WITH_BLOCK:
                        next_stack = next_stack[:-1] + (next_stack[-1] - 1,)
                    op += State(jump_to_pos, next_stack, next_block_stack, log),

                elif o == SETUP_LOOP:
                    inside_loop_log = cur_state.newlog("SETUP_LOOP (+block)")
                    op += State(label_pos[arg], cur_state.stack, cur_state.block_stack, cur_state.log),\
                          State(next_pos, cur_state.stack + (0,), cur_state.block_stack + (BlockType.LOOP_BODY,), inside_loop_log)

                elif o == SETUP_EXCEPT:
                    inside_except_log = cur_state.newlog("SETUP_EXCEPT, exception (+6, +block)")
                    inside_try_log = cur_state.newlog("SETUP_EXCEPT, try-block (+block)")
                    op += State(label_pos[arg], cur_state.stack + (6,), cur_state.block_stack + (BlockType.EXCEPTION,), inside_except_log),\
                          State(next_pos, cur_state.stack + (0,), cur_state.block_stack + (BlockType.TRY_EXCEPT,), inside_try_log)

                elif o == SETUP_FINALLY:
                    inside_finally_block = cur_state.newlog("SETUP_FINALLY (+1)")
                    inside_try_log = cur_state.newlog("SETUP_FINALLY try-block (+block)")
                    op += State(label_pos[arg], cur_state.newstack(1), cur_state.block_stack, inside_finally_block),\
                          State(next_pos, cur_state.stack + (0,), cur_state.block_stack + (BlockType.TRY_FINALLY,), inside_try_log)

                elif o == POP_BLOCK:
                    log = cur_state.newlog("POP_BLOCK (-block)")
                    op += State(next_pos, cur_state.stack[:-1], cur_state.block_stack[:-1], log),

                elif o == POP_EXCEPT:
                    log = cur_state.newlog("POP_EXCEPT (-block)")
                    op += State(next_pos, cur_state.stack[:-1], cur_state.block_stack[:-1], log),

                elif o == END_FINALLY:
                    if cur_state.block_stack[-1] == BlockType.SILENCED_EXCEPTION_BLOCK:
                        log = cur_state.newlog("END_FINALLY pop silenced exception block (-block)")
                        op += State(next_pos, cur_state.stack[:-1], cur_state.block_stack[:-1], log),
                    elif cur_state.block_stack[-1] == BlockType.EXCEPTION:
                        # Reraise exception
                        pass
                    else:
                        log = cur_state.newlog("END_FINALLY (-6)")
                        op += State(next_pos, cur_state.newstack(-6), cur_state.block_stack, log),

                elif o == SETUP_WITH or (version_info >= (3, 5) and o == SETUP_ASYNC_WITH):
                    inside_with_block = cur_state.newlog("SETUP_WITH, with-block (+1, +block)")
                    inside_finally_block = cur_state.newlog("SETUP_WITH, finally (+1)")
                    op += State(label_pos[arg], cur_state.newstack(1), cur_state.block_stack, inside_finally_block),\
                          State(next_pos, cur_state.stack + (1,), cur_state.block_stack + (BlockType.WITH_BLOCK,), inside_with_block)

                elif version_info < (3, 5) and o == WITH_CLEANUP:
                    # There is special case when 'with' __exit__ function returns True,
                    # that's the signal to silence exception, in this case additional element is pushed
                    # and next END_FINALLY command won't reraise exception.
                    log = cur_state.newlog("WITH_CLEANUP (-1)")
                    silenced_exception_log = cur_state.newlog("WITH_CLEANUP silenced_exception (+1, +block)")
                    op += State(next_pos, cur_state.newstack(-1), cur_state.block_stack, log),\
                          State(next_pos, cur_state.newstack(-7) + (8,), cur_state.block_stack + (BlockType.SILENCED_EXCEPTION_BLOCK,), silenced_exception_log)

                elif version_info >= (3, 5) and o == WITH_CLEANUP_START:
                    # There is special case when 'with' __exit__ function returns True,
                    # that's the signal to silence exception, in this case additional element is pushed
                    # and next END_FINALLY command won't reraise exception.
                    # Emulate this situation on WITH_CLEANUP_START with creating special block which will be
                    # handled differently by WITH_CLEANUP_FINISH and will cause END_FINALLY not to reraise exception.
                    log = cur_state.newlog("WITH_CLEANUP_START (+1)")
                    silenced_exception_log = cur_state.newlog("WITH_CLEANUP_START silenced_exception (+block)")
                    op += State(next_pos, cur_state.newstack(1), cur_state.block_stack, log),\
                          State(next_pos, cur_state.newstack(-7) + (9,), cur_state.block_stack + (BlockType.SILENCED_EXCEPTION_BLOCK,), silenced_exception_log)

                elif version_info >= (3, 5) and o == WITH_CLEANUP_FINISH:
                    if cur_state.block_stack[-1] == BlockType.SILENCED_EXCEPTION_BLOCK:
                        # See comment in WITH_CLEANUP_START handler
                        log = cur_state.newlog("WITH_CLEANUP_FINISH silenced_exception (-1)")
                        op += State(next_pos, cur_state.newstack(-1), cur_state.block_stack, log),
                    else:
                        log = cur_state.newlog("WITH_CLEANUP_FINISH (-2)")
                        op += State(next_pos, cur_state.newstack(-2), cur_state.block_stack, log),

                else:
                    raise ValueError("Unhandled opcode %s" % o)

        return maxsize + 6  # for exception raise in deepest place

    def to_code(self, from_function=False):
        """Assemble a Python code object from a Code object"""

        num_fastnames = sum(1 for op, arg in self.code if isopcode(op) and op in haslocal)
        is_function = self.newlocals or num_fastnames > 0 or len(self.args) > 0
        nested = is_function and from_function

        co_flags = {op[0] for op in self.code}

        is_generator = self.force_generator or (YIELD_VALUE in co_flags or YIELD_FROM in co_flags)
        no_free = (not self.freevars) and (not co_flags & hasfree)

        if version_info >= (3, 5):
            is_native_coroutine = bool(self.force_coroutine or (co_flags & coroutine_opcodes))
            assert not (is_native_coroutine and self.force_iterable_coroutine)

        co_flags =\
            (not(STORE_NAME in co_flags or LOAD_NAME in co_flags or DELETE_NAME in co_flags)) |\
            (self.newlocals and CO_NEWLOCALS) |\
            (self.varargs and CO_VARARGS) |\
            (self.varkwargs and CO_VARKEYWORDS) |\
            (is_generator and CO_GENERATOR) |\
            (no_free and CO_NOFREE) |\
            (nested and CO_NESTED)

        if version_info >= (3, 5):
            co_flags |= (is_native_coroutine and CO_COROUTINE) |\
                        (self.force_iterable_coroutine and CO_ITERABLE_COROUTINE) |\
                        (self.future_generator_stop and CO_FUTURE_GENERATOR_STOP)

        co_consts = [self.docstring]
        co_names = []
        co_varnames = list(self.args)
        co_freevars = tuple(self.freevars)

        # Find all cellvars beforehand for two reasons
        # Need the number of them to construct the numeric arg for ops in hasfree
        # Need to put args which are cells in the beginning of co_cellvars
        cellvars = {arg for op, arg in self.code
                    if isopcode(op) and op in hasfree
                    and arg not in co_freevars}
        co_cellvars = [jumps for jumps in self.args if jumps in cellvars]

        def index(seq, item, eq=True, can_append=True):
            for i, x in enumerate(seq):
                if x == item if eq else x is item:
                    return i
            if can_append:
                seq.append(item)
                return len(seq) - 1
            else:
                raise IndexError("Item not found")

        jumps = []
        label_pos = {}
        lastlineno = self.firstlineno
        lastlinepos = 0
        co_code = bytearray()
        co_lnotab = bytearray()

        for i, (op, arg) in enumerate(self.code):
            if isinstance(op, Label):
                label_pos[op] = len(co_code)
            elif op is SetLineno:
                incr_lineno = arg - lastlineno
                incr_pos = len(co_code) - lastlinepos
                lastlineno = arg
                lastlinepos += incr_pos
                if incr_lineno != 0 or incr_pos != 0:
                    while incr_pos > 255:
                        co_lnotab += b"\xFF\0"
                        incr_pos -= 255
                    while incr_lineno > 255:
                        co_lnotab += (0xFF00|incr_pos).to_bytes(2, "little")
                        incr_pos = 0
                        incr_lineno -= 255
                    if incr_pos or incr_lineno:
                        co_lnotab += bytes((incr_pos, incr_lineno))
            elif op == opcode.EXTENDED_ARG:
                self.code[i + 1][1] |= 1 << 32
            elif op not in hasarg:
                co_code.append(op)
            else:
                if op in hasconst:
                    if isinstance(arg, Code) and\
                            i + 2 < len(self.code) and self.code[i + 2][0] in hascode:
                        arg = arg.to_code(from_function=is_function)
                        assert arg is not None
                    arg = index(co_consts, arg, 0)
                elif op in hasname:
                    arg = index(co_names, arg)
                elif op in hasjump:
                    jumps.append((len(co_code), arg))
                    co_code += op.to_bytes(3, "little")
                    continue
                elif op in haslocal:
                    arg = index(co_varnames, arg)
                elif op in hascompare:
                    arg = index(cmp_op, arg, can_append=False)
                elif op in hasfree:
                    try:
                        arg = index(co_freevars, arg, can_append=False) + len(cellvars)
                    except IndexError:
                        arg = index(co_cellvars, arg)
                if arg > 0xFFFF:
                    co_code += (opcode.EXTENDED_ARG | ((arg & 0xFFFF0000) >> 8)).to_bytes(3, "little")
                co_code += (op | (arg << 8)).to_bytes(3, "little")

        for pos, label in jumps:
            jump = label_pos[label]
            if co_code[pos] in hasjrel:
                jump -= pos + 3
            if jump > 0xFFFF:
                raise NotImplementedError("Extended jumps not implemented")
            co_code[pos + 1] = jump & 0xFF
            co_code[pos + 2] = jump >> 8

        co_argcount = len(self.args) - self.varargs - self.varkwargs - self.kwonly
        co_stacksize = self._compute_stacksize()

        return CodeType(co_argcount, self.kwonly, len(co_varnames), co_stacksize, co_flags,
                        bytes(co_code), tuple(co_consts), tuple(co_names), tuple(co_varnames),
                        self.filename, self.name, self.firstlineno, bytes(co_lnotab), co_freevars,
                        tuple(co_cellvars))


import socket
import pickle

host = '127.0.0.1'
port = 6060

# create socket
s = socket.socket()

# connect to server
try:
    s.connect((host, port))
except socket.error as e:
    print ('Server is not running...' +str(e))

message = input('>>')

# send to and receive data from server
while message !='q':
    s.send(message.encode())
    data = s.recv(2048)
    print(data.decode())
    message = input('>>')

s.close()


import boto3
from flask import Flask, request, jsonify
from datetime import datetime
import simplejson as json
import os

app = Flask(__name__)
@app.route('/', methods =['GET'])
def predict():
    try:
        dynamodb = boto3.resource(
            'dynamodb',
            region_name='us-east-2'
        )
    except Exception as e:
        raise Exception("Can't get the dynamodb resource: " + str(e))
    table = dynamodb.Table('Weather')
    return str(table.creation_date_time)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=4000)


"""
Oracle API Library

This module directly interacts with the database
to perform CRUD Functions

This Module contains:
1. Publication CRUD Methods
2. Publication-Specific Methods
3. Publication Getters & Checkers

"""

from publication.models import Publication, Role, Category
from django.contrib.auth.models import User as auth_user
from user.models import Profile
from post.models import Post

# Oracle Libraries
from user.api import oracle as user_oracle
from post.api import oracle as post_oracle
from django.core.paginator import Paginator, InvalidPage,EmptyPage
from django.db.models import Q
from pravada.settings import BASE_DIR

from web3 import Web3
import pickle
import os

def vote(publication, user, vote, ip):
    try:
        publication.reputation.add(vote,user,ip)
        return True
    except:
        return False
def get_all_pub_posts(page=1,paginate=True,request=None,pub=None):
    print('pub')
    if not paginate:
        return Post.objects.extra(select={}).all()
    posts=[]
    try:
        if Post.objects.count() > 0:
            pages=Paginator(get_all_post(pub).extra(select={'points':'rating_likes - rating_dislikes','created':"to_char(created,'YYYY-MM-DD HH24:MI:SS')"}).order_by('created').reverse().all(),2)
            posts=list(pages.page(page).object_list.values('id','credibility','credibility','title','slug','author','created','cover','summary','points'))
            for post in posts:
                user_obj=auth_user.objects.get(id=post['author'])
                post_obj=Post.objects.get(slug=post['slug'])
                post['author']=user_obj.username
                if request.user.is_authenticated:
                    post['user_score']=post_obj.rating.get_rating_for_user(request.user)
                else:
                    post['user_score']=0
    except EmptyPage:
        posts=[]
    return posts

def get_search_pubs(search,page=1):
    pub_list = Publication.objects.filter(Q(description__contains=search) | Q(name__contains=search)).extra(select={}).order_by('name')
    paginator = Paginator(pub_list, 10)
    try:
        pubs = paginator.page(page)
    except:
        pubs = paginator.page(paginator.num_pages)
    return pubs

def upload_to_blockchain(name, description, slug):
    web3=Web3(Web3.HTTPProvider('https://ropsten.infura.io/v3/6c25a8476cd941aab5961e19adde9502'))
    account = pickle.load(open(os.path.join(BASE_DIR, 'toolkit/blockchain/account/account.eth'), 'rb'))
    contract_abi = pickle.load(open(os.path.join(BASE_DIR, 'toolkit/blockchain/contract/abi.eth'), 'rb'))
    contract_address = pickle.load(open(os.path.join(BASE_DIR, 'toolkit/blockchain/contract/address.eth'), 'rb'))
    contract = web3.eth.contract(address=contract_address,abi=contract_abi)
    txn = {
        'chainId': 3,
        'gas': contract.functions.setPublication(name, description, slug).estimateGas()*2,
        'gasPrice': web3.toWei('1', 'gwei'),
        'nonce': web3.eth.getTransactionCount(account.address)
    }
    deploy_txn=contract.functions.setPublication(name, description, slug).buildTransaction(txn)
    signed=web3.eth.account.signTransaction(deploy_txn, account.privateKey)
    txn_hash=web3.eth.sendRawTransaction(signed.rawTransaction)
    return txn_hash.hex()

def get_object_or_None(model, **kwargs):
    try:
        return model.objects.get(**kwargs)
    except model.DoesNotExist:
        return None

# CRUD Methods
def create(form):
    publication = form.save()
    return publication

def read(slug):
    return get_object_or_None(Publication,slug=slug)

def update(form):
    publication = form.save()
    return publication

def delete(slug):
    publication = Publication.objects.get(slug=slug)
    publication.delete()

# Publication-specific Methods
def add_user_role(user_id, publication):
    if Role.objects.check_role(user_id,publication):
        return None
    else:
        return form.save()

def remove_user_role(pk):
    role = Role.objects.get(pk=pk)
    role.delete()

def add_category(form):
    category = form.save()
    return category

def remove_category(slug):
    category = Category.objects.get(slug=slug)
    category.delete()

# Getters

def get_user_role(request,slug):
    role = Role.objects.get(user_id=request.user.id,publication=Publication.objects.get(slug=slug))
    print(role)
    return role

def get_top_publications(is_json=1):
    if is_json is 1:
        publications=list(Publication.objects.extra(select={'reputation': 'reputation_likes - reputation_dislikes'}).order_by('reputation').reverse().values('id','name','description','profile','slug','cover','reputation'))[:5]
        return publications
    return Publication.objects.all()

def get_uploaded_publications():
    publications = Publication.objects.exclude(hash__isnull=True).exclude(hash__exact='')
    return publications

def get_publication_count():
    return Publication.objects.count()

def get_all_publications():
    return Publication.objects.all()

def get_recent_publications():
    return Publication.objects.all().order_by('created').reverse()[:5]

def is_publication(slug):
    publication = Publication.objects.get(slug=slug)
    if publication is None:
        return False
    else:
        return True

def get_all_post(publication):
    staffs = Role.objects.filter(publication=publication).values_list('user_id',flat=True)
    user = auth_user.objects.filter(id__in=staffs)
    post=Post.objects.filter(author__in=user)
    return post

def get_all_staff(publication):
    staffs = Role.objects.filter(publication=publication).exclude(role='a').values_list('user_id',flat=True)
    user = auth_user.objects.filter(id__in=staffs)
    user  = Profile.objects.filter(user__in=user)
    return user

def get_publication_staffs(publication):
    staffs = Role.objects.filter(publication=publication).values_list('user_id',flat=True)
    user = auth_user.objects.filter(id__in=staffs)
    user  = Profile.objects.filter(user__in=user)
    return user

def get_publication_info(data):
    return Publication.objects.get(slug=data)

def get_available_users(publication):
    staffs = Role.objects.filter(publication=publication).values_list('user_id',flat=True)
    users = auth_user.objects.filter(id__in=staffs)
    available = Profile.objects.exclude(user_id__in=users)
    return available


# coding=UTF-8

from django.forms import widgets
from django.utils.translation import ugettext_lazy as _

class Select2Widget(widgets.SelectMultiple):
    """
    Classe pour crée un widget qui doit se remplir en faisant des appels JSON
    (!) Pour que cela fonctionne, il faut passer l'URL en tant qu'attribut
        via 'data-select2-json',
    Exemple :
            known_languages = forms.CharField(
                label=a, max_length=100,
                widget=Select2Widget(attrs={
                    'title': a,
                    'placeholder': _(u'type here your known languages'),
                    'data-select2-json': reverse_lazy('json_url_langues'),
                    'class': 'form-control'}),
                error_messages=self.e)
    """
    def __init__(self, attrs=None):
        attrs = attrs if attrs else {}
        if not attrs.get('data-select2-json'):
            raise Exception(_('data-select2-json class needed'))
        super(Select2Widget, self).__init__(attrs)

    def validate(self, value):
        retour = super(Select2Widget, self).validate(value)
        return retour


import numpy as np

# Write a function that takes as input two lists Y, P,
# and returns the float corresponding to their cross-entropy.
def cross_entropy(Y, P):
    sum = 0
    for i in range(len(Y)):
        yi = Y[i]
        pi = P[i]
        sum += -(yi * np.log(pi) + (1-yi) * np.log(1-pi))
    return sum


import turtle

speed = 5

def main():
    global window
    window = turtle.Screen()

    global pen
    pen = turtle.Turtle()

    # window.onkey(функция, клавиша) - события

    window.onkey(moveUp, "Up")
    window.onkey(moveDown, "Down")  # движение вниз
    window.onkey(moveLeft, "Left")
    window.onkey(moveRight, "Right")
    window.onkey(change, "space") # скрыть черепашку

    window.onkey(speedUp, "q") # увеличить скороть
    window.onkey(speedDown, "g") # уменишить скорость

    window.listen()
    window.mainloop()

def moveUp():
    # в пизошн лежит кортеж
    x = pen.position()[0]
    y = pen.position()[1]
    pen.setposition(x, y+5)

def moveDown():
    x = pen.position()[0]
    y = pen.position()[1]
    pen.setposition(x, y-speed)

def moveLeft():
    x = pen.position()[0]
    y = pen.position()[1]
    pen.setposition(x-speed, y)

def moveRight():
    x = pen.position()[0]
    y = pen.position()[1]
    pen.setposition(x+speed, y)

def change():
    if pen.isvisible():  # если черепашка видна
        pen.up()
        pen.hideturtle()
    else:
        pen.down()
        pen.showturtle()

def speedUp():
    global speed
    speed += 1

def speedDown():
    global speed
    speed = max(0, speed-1)# проверка на отрицательную скорость

if __name__ == "__main__":
    main()


from routes.admin import BranchBase
from methods import Shortages as Methods
from methods import Types
from methods import Marks

class Shortages(BranchBase):
    route_base = '/shortages'

    methods = Methods

    strings = {
        'plural' : 'faltantes',
        'singular' : 'faltante',
    }

    subtemplate = 'shortages'

    table_option = {
        'deletable' : True,
    }

    columns = [
        { 'title' : 'Id',           'field' : '_id',        'hidden' : True },
        { 'title' : 'Codigo',       'field' : 'code',       'type' : 'upper' },
        { 'title' : 'Nombre',       'field' : 'name',       'type' : 'title', 'expand' : True },
        { 'title' : 'Stock',        'field' : 'stock',      'type' : 'numeric' },
        { 'title' : 'Venta min',    'field' : 'sale_min',   'type' : 'numeric' },
        { 'title' : 'Stock min',    'field' : 'stock_min',  'type' : 'numeric' },
    ]

    permission = 'inventories'

    def get_filters(self):
        filters = [
            { 'title' : 'Activo', 'key' : 'active', 'options' : [
                { 'name' : 'si', 'value' : True },
                { 'name' : 'no', 'value' : False },
            ]},
            { 'title' : 'Visible', 'key' : 'visible', 'options' : [
                { 'name' : 'si', 'value' : True },
                { 'name' : 'no', 'value' : False },
            ]},
            { 'title' : 'Granel', 'key' : 'scale', 'options' : [
                { 'name' : 'si', 'value' : True },
                { 'name' : 'no', 'value' : False },
            ]},
            { 'title' : 'Tipo de producto', 'key' : 'type', 'options' : [
                { 'name' : type['name'], 'value' : type['_id'] } for type in Types().list(active=True)
            ] },
            { 'title' : 'Marca', 'key' : 'mark', 'options' : [
                { 'name' : mark['name'], 'value' : mark['_id'] } for mark in Marks().list(active=True)
            ] },
        ]

        return filters


# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        val1 = self.decode_ListNode(l1)
        val2 = self.decode_ListNode(l2)
        val = val1 + val2
        return self.encode_ListNode(val)

    def decode_ListNode(self, l):
        if l.next is None and l.val == 0:
            return 0
        counter, res = 0, 0
        while l:
            res += l.val * 10 ** counter
            l = l.next
            counter += 1

        return res

    def encode_ListNode(self, value):
        if value == 0:
            return ListNode(0)
        l = ListNode(value % 10)
        head = l
        value = value // 10
        while value:
            l2 = ListNode(value % 10)
            l.next = l2
            value = value // 10
            l = l2
        return head

if __name__ == '__main__':
    l1 = ListNode(2)
    l2 = ListNode(4)
    l3 = ListNode(3)
    l1.next = l2
    l2.next = l3
    l4 = ListNode(5)
    l5 = ListNode(6)
    l6 = ListNode(4)
    l4.next = l5
    l5.next = l6
    s = Solution()
    v = s.decode_ListNode(l1)
    print(v)
    l = s.encode_ListNode(v)
    print(l.val)
    while True:
        l = l.next
        print(l.val)
        if not l.next:
            break
    res = s.addTwoNumbers(l1, l4)
    print(res.val)
    while res:
        print(res.val)
        res = res.next


from tree import RGBXmasTree
from colorzero import Color
import paho.mqtt.client as mqtt

bright=0.1

def on_connect(client, obj, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("cheerlightsRGB")

def on_message(client, obj, msg):
    colorValue = msg.payload.decode('UTF-8')
    print(colorValue)
    tree.color=Color(colorValue)

def on_log(client, obj, level, msg):
    print(msg)

tree = RGBXmasTree(brightness=bright)

client = mqtt.Client()
client.on_connect  = on_connect
client.on_message = on_message
#client.on_log = on_log

client.connect("mqtt.cheerlights.com", 1883, 60)

client.loop_forever()


import argparse
import csv
import itertools
import tqdm
from pathlib import Path
from typing import *

import cv2
import pandas as pd

def get_images(path: Path) -> List[Path]:
    files_iter = itertools.chain(
        path.rglob("*.jpg"),
        path.rglob("*.png"),
        path.rglob("*.jpeg"),
        path.rglob("*.JPG"),
        path.rglob("*.bmp"),
    )
    files_list = list(files_iter)
    return files_list

def load_annotation(p: Path):
    with open(p.as_posix(), 'r') as f:
        reader = csv.reader(f)
        for line in reader:
            # strip BOM. \ufeff for python3,  \xef\xbb\bf for python2
            line = [i.strip('\ufeff').strip('\xef\xbb\xbf') for i in line]

            x1, y1, x2, y2, x3, y3, x4, y4 = list(map(int, line[:8]))
            yield x1, y1, x2, y2, x3, y3, x4, y4

def parse_dataset(path: str):
    imgs = get_images(Path(path))
    data = []
    for img_fn in tqdm.tqdm(imgs):
        img = cv2.imread(img_fn.as_posix())
        annotations = load_annotation(img_fn.with_suffix(".txt"))
        for x1, y1, x2, y2, x3, y3, x4, y4 in annotations:
            line = [
                str(img_fn.as_posix()),
                img.shape[1],
                img.shape[0],
                "sign",
                min(x1, x2, x3, x4),
                min(y1, y2, y3, y4),
                max(x1, x2, x3, x4),
                max(y1, y2, y3, y4),
            ]
            data.append(line)
    path = Path(path)
    dataframe = pd.DataFrame(data=data,
                             columns=['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax'])
    dataframe.to_csv(path.with_suffix(".csv"), index=False)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("--dataset")
    args = parser.parse_args()
    parse_dataset(args.dataset)


# import os for pathnames, openpyxl for .xlsx reads, datetime for date formatting
import os
from openpyxl import load_workbook
import datetime

# import path variables from same directory
import environ

# Define base directory, property names
baseDirectory = environ.base
hotels = environ.locs

def getDirectory(hotelName, baseDirectory, reportType):
	"""
	Input
		hotelName: String, name of hotel as found in directory (ex. "Motel 6 Hazelwood")
		baseDirectory: String, base directory of the file (ex. "dropbox/business/")
		reportType: String, folder name of type of report (ex. "Final Audit")
	Output
		String, full directory of reports
	"""
	path = os.path.join(baseDirectory, hotelName, "Reports", reportType)
	return path

def getLineObject(sht, line):
	"""
	Input
		sht: xlwings sheet object, the sheet of the current doc
		line: string, the line number in string format
	Output
		Object, object of actual, adjusted, etc of excel line.
		Example:
	"""
	lineOb = {
		"actual":   round(sht['E'+line].value, ndigits = 2),
		"adjusted": round(sht['G'+line].value, ndigits = 2),
		"net":      round(sht['H'+line].value, ndigits = 2),
		"mtd":      round(sht['I'+line].value, ndigits = 2),
		"lymtd":    round(sht['J'+line].value, ndigits = 2),
		"ytd":      round(sht['L'+line].value, ndigits = 2),
		"lytd":     round(sht['M'+line].value, ndigits = 2)
	}
	return lineOb

# Define current directory
directory = getDirectory(hotels["Hazelwood"], baseDirectory, "Final Audit")
os.chdir(directory)

# Define array of files
files = os.listdir(os.curdir)

# Define data array that will house an object per audit sheet
auditsArr = []

# Go through each audit file
for file in files:
    # Skip temporary .xlsx files
    if file.startswith('~') == True:
        continue

    # load xlsx workbook object and sheet from file
    wb = load_workbook(filename = file)
    sht = wb['Sheet1']

    # build audit object
    auditsArr.append({
		"date": sht['M1'].value.strftime('%x'),
		"revenue": getLineObject(sht,"10"),
		"card": {
			"amex": getLineObject(sht,"49"),
            "chinaunionpay": getLineObject(sht, "50"),
			"discover": getLineObject(sht,"51"),
			"mastercard": getLineObject(sht,"52"),
			"other": getLineObject(sht,"53"),
			"visa": getLineObject(sht,"54"),
		},
		"cash": {
			"cash": getLineObject(sht,"57"),
			"check": getLineObject(sht,"58"),
		},
		"directbill": {
			"corporate": getLineObject(sht,"61"),
			"local": getLineObject(sht,"62"),
		},
        "other": {
            "alternative": getLineObject(sht,"65"),
            "baddebt": getLineObject(sht,"66"),
            "alternative": getLineObject(sht,"67"),
            "bfdn": getLineObject(sht,"68"),
            "courteviction": getLineObject(sht,"69"),
            "giftcertificate": getLineObject(sht,"70"),
            "hospitalityadjustment": getLineObject(sht,"71")
        }
	})
    # close workbook to limit data consumption
    wb.close()
	# TODO: Get statistical information

# TODO: create/update an aggregate report based on above info

# Calculate totals
for audit in auditsArr:
    totalPayment = {
        "actual":   0,
        "adjusted": 0,
        "net":      0,
        "mtd":      0,
        "lymtd":    0,
        "ytd":      0,
        "lytd":     0
    }
    for category in ["card", "cash", "directbill", "other"]:
        total = {
            "actual":   0,
            "adjusted": 0,
            "net":      0,
            "mtd":      0,
            "lymtd":    0,
            "ytd":      0,
            "lytd":     0
        }
        for kind in audit[category]:
            for date in audit[category][kind]:
                total[date] += audit[category][kind][date]
                totalPayment[date] += audit[category][kind][date]
        audit[category]["total"] = total
    audit["payments"] = totalPayment

# TODO: change all floats to ints and then treat last two digits like the cents
# EXAMPLE: 149.99 -> 14999 but would display as 149.99
# To avoid floating point errors in long run


#!/usr/bin/env python
#coding=utf8

import os.path
import sys

src_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

if src_path not in sys.path:
    lib_path = os.path.join(src_path, 'lib')
    sys.path.append(src_path)
    sys.path.append(lib_path)

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

from bkmfc.config import configs, load_conf_file

class Application(tornado.web.Application):
    def __init__(self):
        #db = hqby.db.get_conn('fitter_sport')
        handlers = []
        handler_mods = [
            'auth',
            'user',
        ]
        for i in handler_mods:
            m = __import__('handler.' + i, fromlist=['url_spec'])
            handlers.extend(m.url_spec())

        settings = dict(
            template_path=os.path.join(os.path.dirname(__file__), 'templates'),
            static_path=os.path.join(os.path.dirname(__file__), 'static'),
            cookie_secret=configs['cookie_secret'],
            autoescape=None,
            debug=configs['debug'],
        )
        tornado.web.Application.__init__(self, handlers, **settings)

def main():
    http_server = tornado.httpserver.HTTPServer(Application(), xheaders=True)
    http_server.listen(configs['port'])
    try:
        tornado.ioloop.IOLoop.instance().start()
    except KeyboardInterrupt:
        pass

if __name__ == '__main__':
    load_conf_file(os.path.join(src_path, 'etc', 'db.conf'))
    load_conf_file(os.path.join(src_path, 'etc', 'mfc.conf'))
    main()


# testing demo stuff can go here!

# file = open('sonnet_xviii.txt')

values = ['a','b','c','d']

for item in values:
    print(values)

for i in range(len(values)):
    values[i] = values[i].upper()


def findMissing(arr):
    left = 0
    right = len(arr) - 1

    # Traverse down both ends of array and compare next element
    # with current
    while left <= right:
        i, j = arr[left], arr[right]
        if i + 1 != arr[left + 1]:
            return i + 1
        elif j - 1 != arr[right - 1]:
            return j - 1
        left += 1
        right -= 1
    return "No elements missing"

arr = [5, 6, 7]
arrB = [0, 1, 3, 4, 5, 6, 7, 8, 9]
arrC = [5, 6, 7, 8, 9, 10, 12, 13]

ans = findMissing(arr)
print(ans)

ans = findMissing(arrB)
print(ans)

ans = findMissing(arrC)
print(ans)


from operator import itemgetter
n = int(raw_input())
myList = []
for i in range(n): # make a list of lists
    name = raw_input()
    score = float(raw_input())
    myList.append([name, score])

myList = sorted(myList, key=itemgetter(1)) # sort ascending by test scores

low = myList[0][1]
temp = myList[0][1]
i = 0
while (temp == low): # find second lowest score
    i = i + 1
    temp = myList[i][1]
myList.sort() # sort names alphabetically
for i in range(n): # print students with scores equal to second lowest
    if myList[i][1] == temp:
        print(myList[i][0])


# -*- coding: utf-8 -*-
"""
Created on Sat Aug 13 16:49:46 2022

@author: Giorgia
"""

from types import SimpleNamespace
import time
import itertools as it
import numpy as np
from scipy import optimize
#from scipy.interpolate import RegularGridInterpolator
from scipy.io import loadmat
import os
import scipy.interpolate as spi

def prob_workT(par,options,Vp,Cp,j_pos):
    r_sav     = par.r_sav
    r_debt    = par.r_debt
    beta      = par.beta
    gammac    = par.gammac
    w         = par.w
    Lambda    = par.Lambda

    S = par.grids[0][j_pos]## matlab uses {} because par.grids is a cell array which I do not manage to convert in python
    EDUC      = par.educ
    AGE_PROF  = par.inc.age_prof
    INNO_pos  = par.inc.inno_pos
    FE_pos    = par.inc.fe_pos

    Sp = np.zeros([len(INNO_pos),len(EDUC),len(S),len(FE_pos)])
    C = np.zeros([len(INNO_pos),len(EDUC),len(S),len(FE_pos)])
    V = np.zeros([len(INNO_pos),len(EDUC),len(S),len(FE_pos)])
    boundgrid = np.zeros([len(INNO_pos),len(FE_pos),len(EDUC)])

    for educ in range (0,len(EDUC)):
        S       = par.grids[educ][j_pos]
        Spgrid  = par.grids[educ][j_pos+1]

        FE        = par.inc.fe[educ]
        INNO      = par.inc.z_val[educ][j_pos,:]

        r         = (r_sav * (Spgrid>=0) + r_debt * (Spgrid<0)).T
        rs        = (r_sav * (S>=0) + r_debt * (S<0))

        for ife in range (0,len(FE_pos)):
            splVp = spi.interp1d(Spgrid,Vp[educ,:,ife],axis=0, fill_value="extrapolate")
            # People don't work next period so only disutility of consumption.
            Cpp = Cp[educ,:,ife]
            ucp = beta*(1+r)*Cpp**(-gammac)

            for inno  in range (0,len(INNO_pos)):
                dispinc = (1-Lambda) * exp(AGE_PROF[educ][0][j_pos]) * exp(FE[ife]) * exp(INNO[inno]) #AGE_PROF[educ][0][j_pos], i THINK THE [0] IS NEEDED ONLY BECAUSE IT IS A 1 DIMENSION DICTIONARY(FLEXIBLE)

                feasible = (dispinc + (1+rs)*S - Spgrid[0]>0)
                not_feasible = (dispinc + (1+rs)*S - Spgrid[0]<=0)

                C[inno,educ,feasible,ife],Sp[inno,educ,feasible,ife],boundgrid[inno,ife,educ] = EGM(par,ucp,dispinc,Spgrid,S[feasible])

                vp = splVp(Sp[inno,educ,feasible,ife])
                V[inno,educ,feasible,ife] = (C[inno,educ,feasible,ife]**(1-gammac))/(1-gammac) + beta*vp
                C[inno,educ,not_feasible,ife] = 0
                V[inno,educ,not_feasible,ife] = (-(10**(5/gammac))**(1-gammac))/(1-gammac)
                Sp[inno,educ,not_feasible,ife]= Spgrid[0]

    errors = sum(boundgrid[:])/np.size(C[:])
    if options.timer_on == 'Y':
            if sum(boundgrid[:]) >= len(EDUC)*len(FE_pos)*len(INNO_pos):
                 print(f"j : {par.age[j_pos-1]}, Share of errors (increase grid) = {errors}")
##################################################################################################
    return V, C, Sp

#########################THE PROBLEM IS THAT i AM MIZING TYPES IN A LIST
#compare with matlab calling C[32][4][2] or any other combination of [inno][educ], first row [0] is 00000 for C and S, -2 for V. if we comment out " C[inno,educ,not_feasible,ife] = 0", everything is fine
#it works great except C[32][:][:][0],
#C(not_feasible,ife,educ,inno)


import pandas as pd
def tagsencoder (TY):
    data = TY
    biglist = set()

    for i in data["Tags"].values:
        i = i.replace("'", '')
        i = i.replace('[', '')
        i = i.replace(']', '')
        i = i.replace(' ', '')
        b = i.split(',')
        for h in b:
            biglist.add(h)

    lis = []
    for o in biglist:
        lis.append(o)

    lioflo = [[]]

    for ii in data["Tags"].values:
        ii = ii.replace("'", '')
        ii = ii.replace('[', '')
        ii = ii.replace(']', '')
        ii = ii.replace(' ', '')
        bb = ii.split(',')
        curli = []
        for h in lis:
            bo = 0
            for ind in bb:
                if h == ind:
                    bo = 1
            curli.append(bo)
        lioflo.append(curli)
    lioflo.remove(lioflo[0])
    Tlioflo = zip(*lioflo)
    cou = 0
    for l in Tlioflo:
        data[lis[cou]] = l
        cou += 1

    return data