# -*- coding: utf-8 -*-
"""Django page CMS unit test suite module."""
from basic_cms.models import Page, Content
from basic_cms.placeholders import PlaceholderNode, get_filename
from basic_cms.tests.testcase import TestCase, MockRequest
from basic_cms import urlconf_registry as reg
from basic_cms.http import get_language_from_request
from basic_cms.http import get_request_mock, remove_slug
from basic_cms.utils import export_po_files, import_po_files, now_utc
from basic_cms.views import details
from basic_cms.templatetags.pages_tags import get_page_from_string_or_id

import django
from django.utils import unittest
from django.http import Http404
from django.contrib.auth.models import User
from django.conf import settings
from django.core.urlresolvers import reverse
from django.template import Template, RequestContext, Context, TemplateSyntaxError
try:
    from django.template.loader import get_template_from_string
except ImportError:
    def get_template_from_string(template_code):
        from django.template import engines
        template = engines['django'].from_string(template_code)
        return template
from taggit.models import Tag

import datetime

class UnitTestCase(TestCase):
    """Django page CMS unit test suite class."""

    def test_date_ordering(self):
        """Test page date ordering feature."""
        self.set_setting("PAGE_USE_SITE_ID", False)
        author = User.objects.all()[0]
        yesterday = now_utc() - datetime.timedelta(days=1)
        now = now_utc()
        p1 = Page(author=author, status=Page.PUBLISHED, publication_date=now)
        p1.save()
        p2 = Page(
            author=author,
            publication_date=now,
            status=Page.PUBLISHED
        )
        p2.save()
        p3 = Page(
            author=author,
            publication_date=yesterday,
            status=Page.PUBLISHED
        )
        p3.save()

        p2.move_to(p1, position='first-child')
        p3.move_to(p1, position='first-child')

        p1 = Page.objects.get(pk=p1.id)
        p2 = Page.objects.get(pk=p2.id)
        p3 = Page.objects.get(pk=p3.id)
        self.assertEqual(
            [p.id for p in p1.get_children_for_frontend()],
            [p3.id, p2.id]
        )

        self.assertEqual(
            [p.id for p in p1.get_date_ordered_children_for_frontend()],
            [p2.id, p3.id]
        )

    def test_widgets_registry(self):
        """Test the widget registry module."""
        from basic_cms import widgets_registry as wreg
        for widget in wreg.registry:
            w = widget()
            w.render('name', 'value')

        try:
            wreg.register_widget(wreg.registry[0])
            raise AssertionError("Error not raised properly.")
        except wreg.WidgetAlreadyRegistered:
            pass

        try:
            wreg.get_widget('wrong')
            raise AssertionError("Error not raised properly.")
        except wreg.WidgetNotFound:
            pass

    def test_page_caculated_status(self):
        """Test calculated status property."""
        self.set_setting("PAGE_SHOW_START_DATE", True)
        yesterday = now_utc() - datetime.timedelta(days=1)
        tomorrow = now_utc() + datetime.timedelta(days=1)

        page = self.new_page()
        self.assertEqual(page.calculated_status, Page.PUBLISHED)
        page.publication_date = tomorrow
        self.assertEqual(page.calculated_status, Page.DRAFT)
        page.publication_date = yesterday
        self.assertEqual(page.calculated_status, Page.PUBLISHED)
        self.set_setting("PAGE_SHOW_END_DATE", True)
        page.publication_end_date = yesterday
        self.assertEqual(page.calculated_status, Page.EXPIRED)

    def test_placeholder_inherit_content(self):
        """Test placeholder content inheritance between pages."""
        self.set_setting("PAGE_USE_SITE_ID", False)
        p1 = self.new_page(content={'inher': 'parent-content'})
        p2 = self.new_page()
        template = django.template.loader.get_template('pages/tests/test7.html')
        context = Context({'current_page': p2, 'lang': 'en-us'})
        self.assertEqual(template.render(context), '')

        p2.move_to(p1, position='first-child')
        self.assertEqual(template.render(context), 'parent-content')

    def test_get_page_template_tag(self):
        """Test get_page template tag."""
        context = Context({})
        pl1 = """{% load pages_tags %}{% get_page "get-page-slug" as toto %}{{ toto }}"""
        template = get_template_from_string(pl1)
        self.assertEqual(template.render(context), u'None')
        self.new_page({'slug': 'get-page-slug'})
        self.assertEqual(template.render(context), u'get-page-slug')

    def test_placeholder_all_syntaxes(self):
        """Test placeholder syntaxes."""
        page = self.new_page()
        context = Context({'current_page': page, 'lang': 'en-us'})

        pl1 = """{% load pages_tags %}{% placeholder title as hello %}"""
        template = get_template_from_string(pl1)
        self.assertEqual(template.render(context), '')

        pl1 = """{% load pages_tags %}{% placeholder title as hello %}{{ hello }}"""
        template = get_template_from_string(pl1)
        self.assertEqual(template.render(context), page.title())

        # to be sure to raise an errors in parse template content
        setattr(settings, "DEBUG", True)

        page = self.new_page({'wrong': '{% wrong %}'})
        context = Context({'current_page': page, 'lang': 'en-us'})

        pl2 = """{% load pages_tags %}{% placeholder wrong parsed %}"""
        template = get_template_from_string(pl2)
        from basic_cms.placeholders import PLACEHOLDER_ERROR
        error = PLACEHOLDER_ERROR % {
            'name': 'wrong',
            'error': "Invalid block tag: 'wrong'",
        }
        self.assertEqual(template.render(context), error)

        # generate errors
        pl3 = """{% load pages_tags %}{% placeholder %}"""
        try:
            template = get_template_from_string(pl3)
        except TemplateSyntaxError:
            pass

        pl4 = """{% load pages_tags %}{% placeholder wrong wrong %}"""
        try:
            template = get_template_from_string(pl4)
        except TemplateSyntaxError:
            pass

        pl5 = """{% load pages_tags %}{% placeholder wrong as %}"""
        try:
            template = get_template_from_string(pl5)
        except TemplateSyntaxError:
            pass

    def test_parsed_template(self):
        """Test the parsed template syntax."""
        setattr(settings, "DEBUG", True)
        page = self.new_page({'title': '{{ "hello"|capfirst }}'})
        page.save()
        context = Context({'current_page': page, 'lang': 'en-us'})
        pl_parsed = """{% load pages_tags %}{% placeholder title parsed %}"""
        template = get_template_from_string(pl_parsed)
        self.assertEqual(template.render(context), 'Hello')
        setattr(settings, "DEBUG", False)
        page = self.new_page({'title': '{{ "hello"|wrong_filter }}'})
        context = Context({'current_page': page, 'lang': 'en-us'})
        self.assertEqual(template.render(context), u'')

    def test_video(self):
        """Test video placeholder."""
        page = self.new_page(content={
            'title': 'video-page',
            'video': 'http://www.youtube.com/watch?v=oHg5SJYRHA0\\\\'
        })
        context = Context({'current_page': page, 'lang': 'en-us'})
        pl1 = """{% load pages_tags %}{% videoplaceholder video %}"""
        template = get_template_from_string(pl1)
        self.assertNotEqual(template.render(context), '')
        self.assertTrue(len(template.render(context)) > 10)

    def test_placeholder_untranslated_content(self):
        """Test placeholder untranslated content."""
        self.set_setting("PAGE_USE_SITE_ID", False)
        page = self.new_page(content={})
        placeholder = PlaceholderNode('untrans', page='p', untranslated=True)
        placeholder.save(page, 'fr-ch', 'test-content', True)
        placeholder.save(page, 'en-us', 'test-content', True)
        self.assertEqual(len(Content.objects.all()), 1)
        self.assertEqual(Content.objects.all()[0].language, 'en-us')

        placeholder = PlaceholderNode('untrans', page='p', untranslated=False)
        placeholder.save(page, 'fr-ch', 'test-content', True)
        self.assertEqual(len(Content.objects.all()), 2)

        # test the syntax
        page = self.new_page()
        template = django.template.loader.get_template(
                'pages/tests/untranslated.html')
        context = Context({'current_page': page, 'lang': 'en-us'})
        self.assertEqual(template.render(context), '')

    def test_urlconf_registry(self):
        """Test urlconf_registry basic functions."""
        reg.register_urlconf('Documents', 'example.documents.urls',
            label='Display documents')

        reg.get_urlconf('Documents')
        try:
            reg.register_urlconf('Documents', 'example.documents.urls',
            label='Display documents')
        except reg.UrlconfAlreadyRegistered:
            pass
        reg.registry = []
        try:
            reg.get_urlconf('Documents')
        except reg.UrlconfNotFound:
            pass

        reg.register_urlconf('Documents', 'example.documents.urls',
            label='Display documents')

        self.assertEqual(reg.get_choices(),
            [('', 'No delegation'), ('Documents', 'Display documents')])

    def test_permissions(self):
        pass

    def test_managers(self):
        # TODO: this test seems dependant from other tests
        self.set_setting("PAGE_USE_SITE_ID", False)
        Page.objects.populate_pages(child=2, depth=2)
        for p in Page.objects.all():
            p.invalidate()
        self.assertEqual(Page.objects.count(), 3)
        self.assertEqual(Page.objects.published().count(), 3)
        self.assertEqual(Page.objects.drafts().count(), 0)
        self.assertEqual(Page.objects.expired().count(), 0)

    def test_get_content_tag(self):
        """
        Test the {% get_content %} template tag
        """
        page_data = {'title': 'test', 'slug': 'test'}
        page = self.new_page(page_data)

        context = RequestContext(MockRequest, {'page': page})
        template = Template('{% load pages_tags %}'
                            '{% get_content page "title" "en-us" as content %}'
                            '{{ content }}')
        self.assertEqual(template.render(context), page_data['title'])
        template = Template('{% load pages_tags %}'
                            '{% get_content page "title" as content %}'
                            '{{ content }}')
        self.assertEqual(template.render(context), page_data['title'])

    def test_get_content_tag_bug(self):
        """
        Make sure that {% get_content %} use the "lang" context variable if
        no language string is provided.
        """
        page_data = {'title': 'test', 'slug': 'english'}
        page = self.new_page(page_data)
        Content(page=page, language='fr-ch', type='title', body='french').save()
        Content(page=page, language='fr-ch', type='slug', body='french').save()
        self.assertEqual(page.slug(language='fr-ch'), 'french')
        self.assertEqual(page.slug(language='en-us'), 'english')

        # default
        context = RequestContext(MockRequest, {'page': page})
        template = Template('{% load pages_tags %}'
                            '{% get_content page "slug" as content %}'
                            '{{ content }}')
        self.assertEqual(template.render(context), 'english')

        # french specified
        context = RequestContext(MockRequest, {'page': page, 'lang': 'fr'})
        template = Template('{% load pages_tags %}'
                            '{% get_content page "slug" as content %}'
                            '{{ content }}')
        self.assertEqual(template.render(context), 'french')

        # english specified
        context = RequestContext(MockRequest, {'page': page, 'lang': 'en-us'})
        template = Template('{% load pages_tags %}'
                            '{% get_content page "slug" as content %}'
                            '{{ content }}')
        self.assertEqual(template.render(context), 'english')

    def test_show_content_tag(self):
        """
        Test the {% show_content %} template tag.
        """
        page_data = {'title': 'test', 'slug': 'test'}
        page = self.new_page(page_data)
        # cleanup the cache from previous tests
        page.invalidate()

        context = RequestContext(MockRequest, {'page': page, 'lang': 'en-us',
            'path': '/page-1/'})
        template = Template('{% load pages_tags %}'
                            '{% show_content page "title" "en-us" %}')
        self.assertEqual(template.render(context), page_data['title'])
        template = Template('{% load pages_tags %}'
                            '{% show_content page "title" %}')
        self.assertEqual(template.render(context), page_data['title'])

    def test_pages_siblings_menu_tag(self):
        """
        Test the {% pages_siblings_menu %} template tag.
        """
        page_data = {'title': 'test', 'slug': 'test'}
        page = self.new_page(page_data)
        # cleanup the cache from previous tests
        page.invalidate()

        context = RequestContext(MockRequest, {'page': page, 'lang': 'en-us',
            'path': '/page-1/'})
        template = Template('{% load pages_tags %}'
                            '{% pages_siblings_menu page %}')
        template.render(context)

    def test_show_absolute_url_with_language(self):
        """
        Test a {% show_absolute_url %} template tag  bug.
        """
        page_data = {'title': 'english', 'slug': 'english'}
        page = self.new_page(page_data)
        Content(page=page, language='fr-ch', type='title', body='french').save()
        Content(page=page, language='fr-ch', type='slug', body='french').save()

        self.assertEqual(page.get_url_path(language='fr-ch'),
            self.get_page_url(u'french'))
        self.assertEqual(page.get_url_path(language='en-us'),
            self.get_page_url(u'english'))

        context = RequestContext(MockRequest, {'page': page})
        template = Template('{% load pages_tags %}'
                            '{% show_absolute_url page "en-us" %}')
        self.assertEqual(template.render(context),
            self.get_page_url(u'english'))
        template = Template('{% load pages_tags %}'
                            '{% show_absolute_url page "fr-ch" %}')
        self.assertEqual(template.render(context),
            self.get_page_url('french'))

    def test_get_page_ids_by_slug(self):
        """
        Test that get_page_ids_by_slug work as intented.
        """
        page_data = {'title': 'test1', 'slug': 'test1'}
        page1 = self.new_page(page_data)

        self.assertEqual(
            Content.objects.get_page_ids_by_slug('test1'),
            [page1.id]
        )

        page_data = {'title': 'test1', 'slug': 'test1'}
        page2 = self.new_page(page_data)

        self.assertEqual(
            Content.objects.get_page_ids_by_slug('test1'),
            [page1.id, page2.id]
        )

        Content(page=page1, language='en-us', type='slug', body='test2').save()

        self.assertEqual(
            Content.objects.get_page_ids_by_slug('test1'),
            [page1.id, page2.id]
        )

        Content(page=page1, language='en-us', type='slug', body='test1').save()

        self.assertEqual(
            Content.objects.get_page_ids_by_slug('test1'),
            [page1.id, page2.id]
        )

    def test_get_language_from_request(self):
        """
        Test that get_language_from_request return the default language even if a
        unaccepted language is used.
        """
        class Req():
            LANGUAGE_CODE = 'en-us'
            GET = {}
        request = Req()
        self.assertEqual(
            get_language_from_request(request), 'en-us')

        request.LANGUAGE_CODE = 'dont'
        self.assertEqual(
            get_language_from_request(request), 'en-us')

        request.LANGUAGE_CODE = 'fr-ch'
        self.assertEqual(
            get_language_from_request(request), 'fr-ch')

    def test_default_view_with_language_prefix(self):
        """
        Test that everything is working with the language prefix option
        activated.
        """
        self.set_setting("PAGE_USE_LANGUAGE_PREFIX", True)

        req = get_request_mock()
        self.assertRaises(Http404, details, req, '/pages/')

        page1 = self.new_page(content={'slug': 'page1'})
        page2 = self.new_page(content={'slug': 'page2'})

        self.assertEqual(page1.get_url_path(),
            reverse('pages-details-by-path', args=[],
            kwargs={'lang': 'en-us', 'path': 'page1'})
        )

        self.assertEqual(details(req, page1.get_url_path(),
            only_context=True)['current_page'],
            page1)

        self.assertEqual(details(req, path=page2.get_complete_slug(),
            only_context=True)['current_page'], page2)

        self.assertEqual(details(req, page2.get_url_path(),
            only_context=True)['current_page'],
            page2)

        self.set_setting("PAGE_USE_LANGUAGE_PREFIX", False)

        self.assertEqual(details(req, page2.get_url_path(),
            only_context=True)['current_page'],
            page2)

    def test_root_page_hidden_slug(self):
        """
        Check that the root works properly in every case.
        """
        page1 = self.new_page(content={'slug': 'page1'})

        self.set_setting("PAGE_USE_LANGUAGE_PREFIX", False)
        self.set_setting("PAGE_HIDE_ROOT_SLUG", True)
        self.assertEqual(page1.is_first_root(), True)
        self.assertEqual(page1.get_url_path(),
            reverse('pages-details-by-path', args=[], kwargs={'path': ''})
        )

        self.set_setting("PAGE_USE_LANGUAGE_PREFIX", True)
        self.assertEqual(page1.get_url_path(),
            reverse('pages-details-by-path', args=[],
            kwargs={'lang': 'en-us', 'path': ''})
        )

        self.set_setting("PAGE_HIDE_ROOT_SLUG", False)
        page1.invalidate()
        self.assertEqual(page1.get_url_path(),
            reverse('pages-details-by-path', args=[],
            kwargs={'lang': 'en-us', 'path': 'page1'})
        )

        self.set_setting("PAGE_USE_LANGUAGE_PREFIX", False)
        self.assertEqual(page1.get_url_path(),
            reverse('pages-details-by-path', args=[],
            kwargs={'path': 'page1'})
        )

    def test_revision_depth(self):
        """
        Check that PAGE_CONTENT_REVISION_DEPTH works.
        """
        page1 = self.new_page(content={'slug': 'page1'})
        self.set_setting("PAGE_CONTENT_REVISION_DEPTH", 3)
        Content.objects.create_content_if_changed(page1, 'en-us', 'rev-test', 'rev1')
        Content.objects.create_content_if_changed(page1, 'en-us', 'rev-test', 'rev2')
        Content.objects.create_content_if_changed(page1, 'en-us', 'rev-test', 'rev3')
        Content.objects.create_content_if_changed(page1, 'en-us', 'rev-test', 'rev4')
        self.assertEqual(Content.objects.filter(type='rev-test').count(), 3)
        self.assertEqual(
            Content.objects.filter(type='rev-test').latest('creation_date').body,
            'rev4')

    def test_content_dict(self):
        """
        Check that content_dict method works.
        """
        page1 = self.new_page(content={'slug': 'page1'})
        page1.save()
        c = Content.objects.create_content_if_changed(page1, 'en-us', 'body', 'test')
        self.assertEqual(
            page1.content_by_language(language='en-us'),
            [c]
        )

    def test_strict_urls(self):
        """
        Check that the strict handling of URLs work as
        intended.
        """
        page1 = self.new_page(content={'slug': 'page1'})
        page2 = self.new_page(content={'slug': 'page2'})
        page1.save()
        page2.save()
        page2.parent = page1
        page2.save()

        page1 = Page.objects.get(id=page1.id)
        self.assertTrue(page1.get_children(), [page2])

        self.assertEqual(
            Page.objects.from_path('wrong/path/page2', 'en-us'),
            page2
        )

        self.set_setting("PAGE_USE_STRICT_URL", True)

        self.assertEqual(
            Page.objects.from_path('wrong/path/page2', 'en-us'),
            None
        )

        self.assertEqual(
            Page.objects.from_path('page1/page2', 'en-us'),
            page2
        )

    def test_remove_slug(self):
        """Test the remove slug function."""
        self.assertEqual(remove_slug('hello/world/toto'), 'hello/world')
        self.assertEqual(remove_slug('hello/world'), 'hello')
        self.assertEqual(remove_slug('/hello/world/'), 'hello')
        self.assertEqual(remove_slug('hello'), None)

    def test_path_too_long(self):
        """Test that the CMS try to resolve the whole page path to find
        a suitable sub path with delegation."""
        page1 = self.new_page(content={'slug': 'page1'})
        page2 = self.new_page(content={'slug': 'page2'})
        from basic_cms import urlconf_registry as reg
        reg.register_urlconf('test', 'basic_cms.testproj.documents.urls',
            label='test')
        page2.delegate_to = 'test'
        page1.delegate_to = 'test'
        page1.save()
        page2.save()
        page2.parent = page1
        page2.save()

        from basic_cms.testproj.documents.models import Document
        doc = Document(title='doc title 1', text='text', page=page1)
        doc.save()

        req = get_request_mock()
        self.set_setting("PAGE_HIDE_ROOT_SLUG", False)
        page1.invalidate()
        page2.invalidate()

        def _get_context_page(path):
            return details(req, path, 'en-us')
        self.assertEqual(_get_context_page('/').status_code, 200)
        self.assertEqual(_get_context_page('/page1/').status_code, 200)
        self.assertEqual(_get_context_page('/page1/').status_code, 200)
        self.assertEqual(_get_context_page('/page1/page2').status_code, 301)
        self.assertEqual(_get_context_page('/page1/page2/').status_code, 301)
        self.assertEqual(_get_context_page('/page1/page2/doc-%d' % doc.id
            ).status_code, 301)
        self.assertRaises(Http404, _get_context_page,
            '/page1/page-wrong/doc-%d' % doc.id)

        reg.registry = []

    def test_po_file_imoprt_export(self):
        """Test the po files export and import."""
        try:
            import polib
        except ImportError:
            return unittest.skip("Polib is not installed")

        page1 = self.new_page(content={'slug': 'page1', 'title': 'english title'})
        page1.save()
        #Content(page=page1, language='en-us', type='title', body='toto').save()
        Content(page=page1, language='fr-ch', type='title', body='french title').save()
        page1.invalidate()

        import StringIO
        stdout = StringIO.StringIO()

        # TODO: might be nice to use a temp dir for this test
        export_po_files(path='potests', stdout=stdout)
        self.assertTrue("Export language fr-ch" in stdout.getvalue())

        f = open("potests/fr-ch.po", "r+")
        old = f.read().replace('french title', 'translated')
        f.seek(0)
        f.write(old)
        f.close()

        stdout = StringIO.StringIO()
        import_po_files(path='potests', stdout=stdout)

        self.assertTrue("Update language fr-ch" in stdout.getvalue())
        self.assertTrue(("Update page %d" % page1.id) in stdout.getvalue())
        self.assertTrue(page1.title(language='fr-ch'), 'translated')

    def test_page_methods(self):
        """Test that some methods run properly."""
        page1 = self.new_page(content={'slug': 'page1', 'title': 'hello'})
        page2 = self.new_page(content={'slug': 'page2'})
        page1.save()
        page2.save()
        page2.parent = page1
        page2.save()
        self.assertEqual(
            page1.expose_content(),
            u"hello"
        )
        self.assertEqual(
            page2.slug_with_level(),
            u"   page2"
        )
        p = Page(author=page1.author)
        self.assertEqual(str(p), u"Page without id")
        p.save()
        self.assertEqual(str(p), u"Page %d" % p.id)

    def test_context_processor(self):
        """Test that the page's context processor is properly activated."""
        from basic_cms.views import details
        req = get_request_mock()
        page1 = self.new_page(content={'slug': 'page1', 'title': 'hello'})
        page1.save()
        self.set_setting("PAGES_MEDIA_URL", "test_request_context")
        self.assertContains(details(req, path='/'), "test_request_context")

    def test_get_page_from_id_context_variable(self):
        """Test get_page_from_string_or_id with an id context variable."""
        page = self.new_page({'slug': 'test'})
        self.assertEqual(get_page_from_string_or_id(str(page.id)), page)

        content = Content(page=page, language='en-us', type='test_id',
            body=page.id)
        content.save()
        context = Context({'current_page': page})
        context = RequestContext(MockRequest, context)
        template = Template('{% load pages_tags %}'
                            '{% placeholder test_id as str %}'
                            '{% get_page str as p %}'
                            '{{ p.slug }}')
        self.assertEqual(template.render(context), 'test')

    def test_get_page_from_slug_context_variable(self):
        """Test get_page_from_string_or_id with an slug context variable."""
        page = self.new_page({'slug': 'test'})

        context = Context({'current_page': page})
        context = RequestContext(MockRequest, context)
        template = Template('{% load pages_tags %}'
                            '{% placeholder slug as str %}'
                            '{% get_page str as p %}'
                            '{{ p.slug }}')
        self.assertEqual(template.render(context), 'test')

        template = Template('{% load pages_tags %}'
                            '{% get_page "test" as p %}'
                            '{{ p.slug }}')
        self.assertEqual(template.render(context), 'test')

    def test_get_page_template_tag_with_page_arg_as_id(self):
        """Test get_page template tag with page argument given as a page id"""
        context = Context({})
        pl1 = """{% load pages_tags %}{% get_page 1 as toto %}{{ toto }}"""
        template = get_template_from_string(pl1)
        self.new_page({'id': 1, 'slug': 'get-page-slug'})
        self.assertEqual(template.render(context), u'get-page-slug')

    def test_get_page_template_tag_with_variable_containing_page_id(self):
        """Test get_page template tag with page argument given as a page id"""
        context = Context({})
        pl1 = ('{% load pages_tags %}{% placeholder somepage as page_id %}'
            '{% get_page page_id as toto %}{{ toto }}')
        template = get_template_from_string(pl1)
        page = self.new_page({'id': 1, 'slug': 'get-page-slug',
            'somepage': '1'})
        context = Context({'current_page': page})
        self.assertEqual(template.render(context), u'get-page-slug')

    def test_get_page_template_tag_with_variable_containing_page_slug(self):
        """Test get_page template tag with page argument given as a page id"""
        context = Context({})
        pl1 = ('{% load pages_tags %}{% placeholder somepage as slug %}'
            '{% get_page slug as toto %}{{ toto }}')
        template = get_template_from_string(pl1)
        page = self.new_page({'slug': 'get-page-slug', 'somepage':
            'get-page-slug'})
        context = Context({'current_page': page})
        self.assertEqual(template.render(context), u'get-page-slug')

    def test_get_pages_with_tag(self):
        """Test get_page template tag with page argument given as a page id"""
        page = self.new_page({'slug': 'footer-page', 'somepage': 'get-footer-slug'})
        tag = Tag.objects.create(name="footer")
        page.tags.add(tag)
        context = Context({})
        pl1 = ('{% load pages_tags %}{% get_pages_with_tag "footer" as pages %}{% for page in pages %}{{ page.slug }}{% endfor %}')
        template = get_template_from_string(pl1)
        self.assertEqual(template.render(context), u'footer-page')

    def test_variable_disapear_in_block(self):
        """Try to test the disapearance of a context variable in a block."""
        tpl = ("{% load pages_tags %}"
          "{% placeholder slug as test_value untranslated %}"
          "{% block someblock %}"
          "{% get_page test_value as toto %}"
          "{{ toto.slug }}"
          "{% endblock %}")

        template = get_template_from_string(tpl)
        page = self.new_page({'slug': 'get-page-slug'})
        context = Context({'current_page': page})
        self.assertEqual(template.render(context), u'get-page-slug')

    def test_get_filename(self):
        placeholder = PlaceholderNode("placeholdername")
        page = self.new_page({'slug': 'page1'})
        data = "myfile.pdf"
        self.assertTrue(data in get_filename(page, placeholder, data))
        self.assertTrue("page_%d" % page.id in get_filename(page, placeholder, data))
        self.assertTrue(placeholder.name in get_filename(page, placeholder, data))


# Import required modules
import re
import os
import sys
import random

# Global parameters
variableStack = [{}] # Variable name -> VariableType
memory = {} # Address -> Value
jumper = {} # Label name -> Line Point
returnStack = [] # Store return opinter
register = [] # Register is a stack, store variable or temporary address
linePointer = 0 # The line executer currently running on

# Address Generator
def addressGenerator() -> str:
    return hex(random.randint(0, 4294967295))

# String spliter
def stringSpliter(string: str, pattern: str = ' ', limit: int = 0, ignore: list = []) -> list:
    r"""
    Split the string with pattern.

    Parameters
    ---
    string : str
        Input string.

    pattern: str
        Char or string to split a string.
        For exmaple, pattern=' ' means, using space to split a string.

    ignore: list
        The char or string in ignore list will be ignore if this char or string is not in a string (starts with '"' and ends with '"').

    Returns
    ---
    list
        Splited string list.
    """
    assert pattern not in ignore # Pattern and ignore cannot be the same string.

    result, temp, inString = [], "", False

    for i in string:
        if i == '"': inString = not inString

        if i in ignore and not inString: continue
        elif i == pattern and not inString:
            if temp != "": result.append(temp)
            temp = ""
            limit -= 1
            if limit == 0: break
        else: temp += i

    if temp != "": result.append(temp)

    return result

def typeOf(string: str) -> str:
    r"""
        Return the type of input string.=
        (1) integer
        (2) float
        (3) string
        (4) bool
        (5) parameter
        (6) systme code (System code starts with '!')
    """

    if str(string).count('"') == 2 and str(string)[0] == '"' and str(string)[-1] == '"':
        return "string"
    elif string in ["true", "false", "null"]:
        return "bool"

    try:
        if str(int(string)) == str(string):
            int(string)
            return "integer"
    except: pass

    try:
        assert "." in str(string)
        float(string)
        return "float"
    except: pass

    return "parameter"

def autoConvert(string: str):
    typeOfString = typeOf(string)

    if typeOfString == "string": return str(string[1:-1])
    elif typeOfString == "integer": return int(string)
    elif typeOfString == "float": return float(string)
    elif typeOfString == "bool":
        if string == "true": return True
        elif string == "false": return False
        else: return None
    else: return string

# Variable type
class VariableType:
    def __init__(self, type: str, address: str, shape: str = []) -> None:
        self.type = type
        self.shape = shape
        self.address = address

def main(file: str) -> None:
    global linePointer
    inSkipArea = 0

    lines = file.split('\n')

    # Pre-processing
    # Remove comments and empty lines.
    for i, line in enumerate(lines):
        inString, temp = False, ""
        for j in line:
            if j == '"': inString = not inString
            if j == ';' and not inString:
                lines[i] = temp
                break
            else: temp += j

    # lines = [x for x in lines if x != '']

    # First Pass
    # To locate labels and functions.
    for i, line in enumerate(lines):
        if line.startswith(':'): # Function
            jumper[line[1:].split()[0]] = i
        elif line.startswith('LABEL'): # Label
            jumper[line[6:]] = i

    # Second Pass
    while linePointer < len(lines):
        line = lines[linePointer]

        # Check if in skip area (function area).
        if line == "SSKP": inSkipArea += 1
        elif line == "ESKP": inSkipArea -= 1

        if inSkipArea > 0:
            linePointer += 1
            continue

        elif re.match(r"LDA .*", line):
            line = line[3:].strip()
            if typeOf(line) != "parameter": register.append(line)
            else: register.append(memory[variableStack[-1][line].address])

        elif re.match(r"LDAA .*", line):
            line = line[4:].strip().split()
            variableName = line.pop(0)

            for i, position in enumerate(line):
                if position == "_": line[i] = int(register.pop())
                else: line[i] = int(line[i])
            line = line[::-1]

            position = sum([x * y for x, y in zip(line[:-1], variableStack[-1][variableName].shape)]) + line[-1]

            register.append(memory[variableStack[-1][variableName].address][position])

        elif re.match(r"STA .*", line):
            variableName = line[3:].strip()
            memory[variableStack[-1][variableName].address] = register.pop()

        elif re.match(r"STAA .*", line):
            line = line[4:].strip().split()
            variableName = line.pop(0)

            for i, position in enumerate(line):
                if position == "_": line[i] = int(register.pop())
                else: line[i] = int(line[i])
            line = line[::-1]

            position = sum([x * y for x, y in zip(line[:-1], variableStack[-1][variableName].shape)]) + line[-1]

            memory[variableStack[-1][variableName].address][position] = register.pop()

        elif re.match(r"((INT )|(FLOAT )|(STR )|(BOOL )).*", line):
            address = addressGenerator()
            variableType, variableName, value = stringSpliter(line)

            if value == "_": value = register.pop()

            memory[address] = value
            variableStack[-1][variableName] = VariableType(variableType, address)

        elif re.match(r"((INTA )|(FLOATA )|(STRA )|(BOOLA )).*", line):
            address = addressGenerator()
            line = stringSpliter(line)
            variableType, variableName = line[0], line[1]
            line = line[2:]

            temp = []
            for i in line: temp.append(int(register.pop()) if i == "_" else int(i))

            length = 1
            for i in temp: length *= i

            initial = []
            if variableType == "INTA": initial = [0] * length
            elif variableType == "FLOATA": initial = [0.0] * length
            elif variableType == "STRA": initial = [""] * length
            elif variableType == "BOOLA": initial = ["false"] * length

            memory[address] = initial
            variableStack[-1][variableName] = VariableType(variableType, address, shape=temp)

        elif re.match(r"ADD .*", line):
            a, b = register.pop(), register.pop()
            ta, tb = typeOf(a), typeOf(b)
            if ta == "string" or tb == "string": temp = str(autoConvert(b)) + str(autoConvert(a))
            else: temp = autoConvert(b) + autoConvert(a)
            register.append(temp)

        elif re.match(r"SUB .*", line):
            a, b = register.pop(), register.pop()
            temp = autoConvert(b) - autoConvert(a)
            register.append(temp)

        elif re.match(r"MUL .*", line):
            a, b = register.pop(), register.pop()
            temp = autoConvert(b) * autoConvert(a)
            register.append(temp)

        elif re.match(r"DIV .*", line):
            a, b = register.pop(), register.pop()
            temp = autoConvert(b) / autoConvert(a)
            register.append(temp)

        elif re.match(r"EXP .*", line):
            a, b = register.pop(), register.pop()
            temp = autoConvert(b) ** autoConvert(a)
            register.append(temp)

        elif re.match(r"REM .*", line):
            a, b = register.pop(), register.pop()
            temp = autoConvert(b) % autoConvert(a)
            register.append(temp)

        elif re.match(r"EQL .*", line):
            a, b = register.pop(), register.pop()
            temp = bool(autoConvert(b) == autoConvert(a))
            register.append("true" if temp else "false")

        elif re.match(r"NEQ .*", line):
            a, b = register.pop(), register.pop()
            temp = bool(autoConvert(b) != autoConvert(a))
            register.append("true" if temp else "false")

        elif re.match(r"GRT .*", line):
            a, b = register.pop(), register.pop()
            temp = bool(autoConvert(b) > autoConvert(a))
            register.append("true" if temp else "false")

        elif re.match(r"LST .*", line):
            a, b = register.pop(), register.pop()
            temp = bool(autoConvert(b) < autoConvert(a))
            register.append("true" if temp else "false")

        elif re.match(r"GTE .*", line):
            a, b = register.pop(), register.pop()
            temp = bool(autoConvert(b) >= autoConvert(a))
            register.append("true" if temp else "false")

        elif re.match(r"LTE .*", line):
            a, b = register.pop(), register.pop()
            temp = bool(autoConvert(b) <= autoConvert(a))
            register.append("true" if temp else "false")

        elif re.match(r"BSL .*", line):
            a, b = register.pop(), register.pop()
            temp = autoConvert(b) >> autoConvert(a)
            register.append(temp)

        elif re.match(r"BSR .*", line):
            a, b = register.pop(), register.pop()
            temp = autoConvert(b) << autoConvert(a)
            register.append(temp)

        elif re.match(r"BAD .*", line):
            a, b = register.pop(), register.pop()
            temp = autoConvert(b) & autoConvert(a)
            register.append(temp)

        elif re.match(r"BXR .*", line):
            a, b = register.pop(), register.pop()
            temp = autoConvert(b) ^ autoConvert(a)
            register.append(temp)

        elif re.match(r"BOR .*", line):
            a, b = register.pop(), register.pop()
            temp = autoConvert(b) | autoConvert(a)
            register.append(temp)

        elif re.match(r"LAD .*", line):
            a, b = register.pop(), register.pop()
            temp = bool(autoConvert(b) and autoConvert(a))
            register.append("true" if temp else "false")

        elif re.match(r"LOR .*", line):
            a, b = register.pop(), register.pop()
            temp = bool(autoConvert(b) or autoConvert(a))
            register.append("true" if temp else "false")

        elif re.match(r"LNT .*", line):
            a = register.pop()
            temp = not bool(autoConvert(a))
            register.append("true" if temp else "false")

        elif re.match(r"MSG .*", line):
            line = line[3:].split()

            for i in line:
                if i == "_": print(register.pop())
                else: print(i)

        elif re.match(r"JMP ", line):
            condition, jumpToLabel = line[3:].split()

            if condition == "_": condition = register.pop()
            if autoConvert(condition):
                linePointer = int(jumper[jumpToLabel])
                continue

        elif re.match(r"CALL", line):
            line = line[4:].strip()

            returnStack.append(linePointer + 1)
            linePointer = int(jumper[line])
            continue

        elif re.match(r":", line):
            variableStack.append({})

        elif re.match(r"RET", line):
            variableStack.pop()
            linePointer = int(returnStack.pop())
            continue

        linePointer += 1

# Error handler
def error(code: int, message: str) -> None:
    r"""
        Error Codes:
            0: "Input Error",
            1: "Undefined",
            2: "Syntax Error",
            3: "Type Error",
            4: "Value Error",
            5: "Defined"
    """
    global linePointer

    codes = {
        0: "Input Error",
        1: "Undefined",
        2: "Syntax Error",
        3: "Type Error",
        4: "Value Error",
        5: "Defined"
    }

    print(f'Traceback:\
          \n  File {file}, line {linePointer}\
          \n    {""}\
          \n      ^^^\
          \n{codes[code]}: {message}'
    )
    exit()

if __name__ == "__main__":
    # If there is no input assembly file, throw error.
    if len(sys.argv) < 2: error(0, "Input file has not been specified.")

    filename = sys.argv[1]
    if not os.path.isfile(filename): error(0, f"Input file {filename} not exists.")

    file = open(filename, "r").read()
    main(file)


from fireml.processing.dataset.realtime.constants import DiscretizationMethods
from typing import Any, Dict, cast
from fireml.processing.dataset.realtime.util import (
    create_evt_to_lf_arr,
    timedelta64_to_uint,
)
import numpy as np
from fireml.processing.dataset.realtime.settings import (
    DEFAULT_CELL_SIZE,
    DEFAULT_LAND_COVER_CELL_SIZE,
    DEFAULT_METEOROLOGY_CELL_SIZE,
    DEFAULT_SHOULD_FILTER_BY_DETECTIONS,
    DEFAULT_SHOULD_FILTER_BY_LAND_COVER,
    DEFAULT_WINDOW_SIZE,
    PreprocessDataConfig,
    SetupData,
)

def setup(
    config: PreprocessDataConfig,
    points: np.ndarray,
    detections_search_table: np.ndarray,
    evt_metadata,
) -> SetupData:
    created_config: Dict[str, Any] = {
        k: timedelta64_to_uint(config["fire_detections"][k])
        for k in [
            "detection_window_lower",
            "detection_window_upper",
            "forecast_window_lower",
            "forecast_window_upper",
        ]
    }

    created_config["use_land_cover"] = config["land_cover"]["use_land_cover"]
    created_config["use_meteorology"] = config["meteorology"]["use_meteorology"]

    created_config["lags"] = timedelta64_to_uint(
        np.array(config["fire_detections"]["lags"])
    )
    created_config["aggregate_lags"] = timedelta64_to_uint(
        np.array(config["fire_detections"]["aggregate_lags"])
    )

    created_config["meteorology_lags"] = timedelta64_to_uint(
        np.array(config["meteorology"]["lags"])
    )

    created_config["forecast_offsets"] = timedelta64_to_uint(
        np.array(config["fire_detections"]["forecast_offsets"])
    )

    created_config["cell_size"] = DEFAULT_CELL_SIZE
    created_config["land_cover_cell_size"] = DEFAULT_LAND_COVER_CELL_SIZE
    created_config["meteorology_cell_size"] = DEFAULT_METEOROLOGY_CELL_SIZE
    created_config["window_size"] = DEFAULT_WINDOW_SIZE
    created_config["discretization_method"] = DiscretizationMethods.EXACT.value

    created_config["width"] = int(
        created_config["window_size"] // created_config["cell_size"]
    )

    created_config["land_cover_width"] = int(
        created_config["window_size"] // created_config["land_cover_cell_size"]
    )

    created_config["meteorology_width"] = int(
        created_config["window_size"] // created_config["meteorology_cell_size"]
    )

    num_layers = (
        1
        + len(created_config["lags"])
        + (len(created_config["aggregate_lags"]) // 2)
        + len(created_config["forecast_offsets"])
    )

    created_config["num_detection_layers"] = num_layers

    evt_to_class, num_classes = (
        create_evt_to_lf_arr(evt_metadata)
        if config["land_cover"]["use_land_cover"]
        else np.empty((1))
    )

    created_config["num_one_hot_classes"] = num_classes

    created_config["num_land_cover_layers"] = (
        len(config["land_cover"]["land_cover_layers"])
        + created_config["num_one_hot_classes"]
        - 1
    )

    # created_config["should_convert_evt_classes"] = True
    created_config["should_convert_evt_classes"] = False

    created_config["num_meteorology_layers"] = len(
        config["meteorology"]["meteorology_layers"]
    ) * len(config["meteorology"]["lags"])

    points_time = cast(np.ndarray, points[:, 0].astype("uint64"))
    points_xy = np.ascontiguousarray(points[:, 1:])

    detections_search_table_times = cast(
        np.ndarray,
        detections_search_table[:, 0].astype("datetime64[ns]").astype("uint64"),
    )
    detections_search_table_xys = np.ascontiguousarray(detections_search_table[:, 1:])

    # Filtering
    created_config["should_filter_by_detections"] = DEFAULT_SHOULD_FILTER_BY_DETECTIONS
    created_config["should_filter_by_land_cover"] = DEFAULT_SHOULD_FILTER_BY_LAND_COVER
    created_config["minimum_detections"] = 5
    created_config["minimum_land_cover_detections"] = 3
    created_config["minimum_land_cover_detections_percentage"] = 0.0
    created_config["maximum_lags_detections"] = 2
    created_config["maximum_lags_land_cover"] = 2

    return {
        "config": created_config,
        "points_time": points_time,
        "points_xy": points_xy,
        "detections_search_table_times": detections_search_table_times,
        "detections_search_table_xys": detections_search_table_xys,
        "evt_to_class": evt_to_class,
    }


import unittest
from model_builder import *
import link_lexemes
import operator

class FullLinkSetExtractionTest(unittest.TestCase):
    INPUT_FILE = 'tests/input.txt'
    ANSWER_FILE = 'tests/fls_extraction_answer.txt'
    def setUp(self):
        raw_text = ' '.join([line.strip() for line in open(FullLinkSetExtractionTest.INPUT_FILE)])
        self.sentences = stop(tokenize_sentences(raw_text))
        self.answer = [(line.strip().split()[0], int(line.strip().split()[1])) \
            for line in open(FullLinkSetExtractionTest.ANSWER_FILE)]

    def test_extraction(self):
        self.assertEqual(link_lexemes.extract_full_link_set(self.sentences, True), self.answer)

class ExistenceAreasCalculationTest(unittest.TestCase):
    INPUT_FILE = 'tests/input.txt'
    ANSWER_FILE = 'tests/existence_areas_calc_answer.txt'

    def get_existence_areas(self, in_indexed_text, in_lexemes):
        areas_dict = calculate_existence_areas(in_indexed_text, in_lexemes)
        result = [value for (key, value) in sorted(areas_dict.iteritems(), key = operator.itemgetter(0))]
        return result

    def setUp(self):
        raw_text = ' '.join([line.strip() for line in open(ExistenceAreasCalculationTest.INPUT_FILE)])
        self.sentences = stop(tokenize_sentences(raw_text))
        self.answer = [[int(index) for index in line.strip().split()[1:]] \
            for line in open(ExistenceAreasCalculationTest.ANSWER_FILE)]

    def test_extraction(self):
        fls = make_lexemes_dict(link_lexemes.extract_full_link_set(self.sentences))
        indexed_text = build_text_index(self.sentences, fls)
        self.assertEqual(self.get_existence_areas(indexed_text, fls), self.answer)

class ConstantPhraseTest(unittest.TestCase):
    INPUT_FILE = 'tests/input.txt'

    def setUp(self):
        raw_text = ' '.join([line.strip() for line in open(ExistenceAreasCalculationTest.INPUT_FILE)])
        self.sentences = stop(tokenize_sentences(raw_text))
        self.fls = make_lexemes_dict(link_lexemes.extract_full_link_set(self.sentences))
        self.indexed_text = build_text_index(self.sentences, self.fls)
        existence_areas = calculate_existence_areas(self.indexed_text, self.fls)
        self.const_phrases = extract_constant_phrases(existence_areas)

    def test_extraction(self):
        answer = [[int(index) for index in line.strip().split()] \
            for line in open('tests/const_phrase_answer.txt')]
        self.assertEqual(self.const_phrases, answer)

    def test_merge(self):
        answer = [[int(index) for index in line.strip().split()] \
            for line in open('tests/const_phrase_merge_answer.txt')]
        (lexemes_merged, text_merged) = \
            merge_constant_phrases(self.fls, self.indexed_text, self.const_phrases)
        self.assertEqual([words for (id, words) in sorted(text_merged.iteritems())], answer)

class AssociativePowerTest(unittest.TestCase):
    INPUT_FILE = 'tests/input.txt'

    def setUp(self):
        raw_text = ' '.join([line.strip() for line in open(ExistenceAreasCalculationTest.INPUT_FILE)])
        self.sentences = stop(tokenize_sentences(raw_text))
        self.fls = make_lexemes_dict(link_lexemes.extract_full_link_set(self.sentences))
        self.indexed_text = build_text_index(self.sentences, self.fls)
        self.lexeme_powers = {id: lexeme_associative_power(id, self.indexed_text) \
            for id in self.fls}

    def test_lexeme_powers(self):
        answer = [int(line.strip()) for line in open('tests/associative_power_answer.txt')]
        self.assertEqual(answer, self.lexeme_powers.values())

    def test_dominant_lexemes(self):
        self.assertEqual(extract_dominants(self.indexed_text, self.fls), self.fls.keys())

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


# has_name = True
has_name = False

name = 'Max' if has_name else 'no name'
print(name)

# is_one = True
is_one = False
number = 1 if is_one else 2
print(number)

# is_russian = True
is_russian = False
print('Привет мир' if is_russian else 'Hello world')

string = 'helloooooo'

# 1) lower/upper by if ilse
if_else_result = []

for i in range(len(string)):
    if i % 2 == 0:
        letter = string[i].upper()
        if_else_result.append(letter)
    else:
        letter = string[i].lower()
        if_else_result.append(letter)

result_string = ''.join(if_else_result)
print('1)', result_string)

# 2) lower/upper by ternar operator
ternar_result = []

for i in range(len(string)):
    letter = string[i]
    letter = letter.upper() if i % 2 == 0 else letter.lower()
    ternar_result.append(letter)

result_string = ''.join(ternar_result)
print('2)', result_string)

#


'''
Description

2017_03_25.  THis class was extracted from the
pgguiutilities.py module, so that it is easier
to debug.
'''
from future import standard_library
standard_library.install_aliases()
from builtins import range
__filename__ = "pgkeycategoricalvalueframe.py"
__date__ = "20170325"
__author__ = "Ted Cosart<ted.cosart@umontana.edu>"

from tkinter import *
from tkinter.ttk import *
import agestrucne.createtooltip as ctt
import sys

from agestrucne.pgkeycontrolframe import PGKeyControlFrame
from agestrucne.pgguiutilities import FredLundhsAutoScrollbar
from agestrucne.pgguiutilities import PGGUIInfoMessage
from agestrucne.pgguiutilities import PGGUIYesNoMessage
from agestrucne.pgguiutilities import PGGUIErrorMessage

'''
2017_04_18.  To consolidate some of the objects and functions
common to the key-value-frame classes, we add a second parent class.
'''
class KeyCategoricalValueFrame( PGKeyControlFrame ):

	'''
	Description

	Revised KeyValueFrame
	substituting a Radiobutton widget
	for the entry box used in KeyValFrame

	'''

	def __init__( self, s_name,
			lq_modes,
			i_default_mode_number,
			o_value_type=None,
			o_master=None,
			s_associated_attribute=None,
			o_associated_attribute_object=None,
			def_on_button_change=None,
			i_labelwidth=15,
			b_is_enabled=True,
			s_label_justify='right',
			s_buttons_justify='right',
			s_label_name=None,
			b_buttons_in_a_row=False,
			b_force_disable=False,
			s_tooltip = "" ):

		"""
		Param lq_modes, list of sequences, each a pair
		    giving the mode label text, and its associated value
			assigned when it is the selected radio button
		Param i_default_mode_number gives the ith (one-indexed)
			item in modes, that is to be the active button,
			and that gives the default value
		Param o_value_type gives the python type for the values
			given in lq_modes value items.  Currently implemented
			for bool, int, float, and string.
		Param o_master is the parent Tkinter object.
				Param s_associated_attribute is the name of
			attribute instance that can be accessed
			using "getattr", and that will be
			updated when the value is updated.
		Param o_associated_attribute_object is the object whose attribute
			is to be unpdated when the value is updated.  If
			s_associated_attribute is not None, and this parameter
			is None, the attribute is presumed to be
			owned by the o_master object.
		Param def_on_button_change, if not None, execute the def
			after updating both the value and the attribute (if any).
			This def is to have no passed params.
		Param i_labelwidth gives the width the the Label widget.
		Param s_label_justify gives Label widget "justify" value.
		Param s_buttons_justify gives Radiobutten Widget text "justify" value.
				currently not implemented (ttk radio button widgets are not
				settable for justify and foreground, without using a syle map).
		Param s_label_name, if not None, replaces s_name as the text for the label.
		Param b_buttons_in_a_row, if False (default) all buttons are in a single column, if True,
				then all buttons side by side in a single row
		Param b_force_disable, if True, will override the b_is_enabled value and disable all entry
			  boxes
		"""

		PGKeyControlFrame.__init__( self, o_master, name=s_name.lower() )

		self.__master=o_master
		self.__value=None
		self.__default_mode_number=i_default_mode_number
		self.__modes=lq_modes
		self.__name=s_name
		self.__lablewidth=i_labelwidth
		self.__labeljustify=s_label_justify
		self.__buttons_justify=s_buttons_justify
		self.__isenabled=b_is_enabled
		self.__associated_attribute=s_associated_attribute
		self.__associated_attribute_object=o_associated_attribute_object
		self.__def_on_button_change=def_on_button_change
		self.__put_buttons_in_row=b_buttons_in_a_row
		self.__current_button_value=self.__init_current_button_val( o_value_type )
		self.__label_name=self.__name if s_label_name is None else s_label_name
		self.__force_disable=b_force_disable
		self.__tooltip=self.__label_name if s_tooltip == "" else s_tooltip
		self.__subframe=None

		#To maintain a reference to the Radiobutton objects,
		#this will be appended-to as they are created:
		self.__radio_buttons=[]
		self.__setup()
	#end init

	def __init_current_button_val( self, o_value_type ):

		o_var=None

		if o_value_type==bool:
			o_var=BooleanVar()
		elif o_value_type==int:
			o_var=IntVar()
		elif o_value_type==float:
			o_var=DoubleVar()
		elif o_value_type==StringVar:
			o_var=StringVar()
		else:
			s_msg="in KeyCategoryValFrame object instance, " \
					+ "value type, " + str( o_value_type ) \
					+ " has no associated Tkinter variable type"
			raise Exception( s_msg )
		#end if bool ... else int ... etc

		return o_var

	#end __init_current_button_val

	def __reset_value( self ):

		try:

			self.__value= self.__current_button_value.get()

		except ValueError as ve:

			s_msg= "KeyCategoryValFrame instance, trying to update values: " \
				+ "current entry value is \"" + o_entryval.get() \
				+ "\" original value type is: " + o_type.__name__ + "\n"
			sys.stderr.write( s_msg + "\n" )
			raise ( ve )
		#end try...except

	#end __reset_value

	def __setup( self ):
		self.__setup_subwidgets()
		self.__subframe.bind( '<Configure>', self.__on_configure_subframe )
		return
	#end __setup

	def __on_configure_subframe( self, event ):
		#we need the scroll region and the canvas dims to
		#always match the subframe dims.
		q_size=( self.__subframe.winfo_reqwidth(), self.__subframe.winfo_reqheight() )
		self.__canvas.config( scrollregion="0 0 %s %s" % q_size )
		self.__canvas.config( width=q_size[ 0 ] )
		self.__canvas.config( height=q_size[ 1 ] )
		return
	#end __configure_subframe

	def __setup_subwidgets( self ):

		o_horiz_scroll=FredLundhsAutoScrollbar( self, orient=HORIZONTAL )
		self.__canvas=Canvas( self, xscrollcommand=o_horiz_scroll.set )
		self.__subframe=Frame( self.__canvas )

		self.__setup_label()
		self.__setup_buttons()

		self.__subframe_id=self.__canvas.create_window(0,0, anchor=NW, window=self.__subframe )
		o_horiz_scroll.config( command=self.__canvas.xview )

		self.__canvas.grid( row=0, column=0, sticky=( N,W,E,S ) )
		o_horiz_scroll.grid( row=1, column=0, sticky=(W,E) )

		self.grid_rowconfigure( 0, weight=1 )
		self.grid_columnconfigure( 0, weight=1 )

		self.__canvas.grid_rowconfigure( 0, weight=1 )
		self.__canvas.grid_columnconfigure( 0, weight=1 )

	#end __setup_subwidgets

	def __setup_label( self ):
		o_label=Label( self.__subframe, text=self.__label_name, justify=self.__labeljustify )
		o_label.config( width=self.__lablewidth )
		o_label.grid( row=0, column=0 )
		self.label=o_label

		'''
		2018_10_23
		Adding the tooltip text to the label.  Formerly
		it was only applied to the control.
		'''
		s_tooltip=ctt.insertNewlines( self.__tooltip )
		o_tooltip=ctt.CreateToolTip( o_label,  s_tooltip )

	#end __setup_label

	def __setup_buttons( self ):

		self.__make_radio_buttons()

		return

	#end __setup_entries

	def __make_radio_buttons( self ):

		i_rowcount=0

		s_state="enabled"
		if self.__isenabled==False or self.__force_disable==True:
			s_state="disabled"
		#end if enabled else not

		for idx in range( len( self.__modes ) ):

			#modes is a list of sequences, pairs
			#giving ( buttontext, buttonvalue):
			s_text, v_value=self.__modes[ idx ]

			i_rowcount+=1

			self.__current_button_value.set( v_value )

			o_radio_button=Radiobutton( self.__subframe,
										text=s_text,
										variable=self.__current_button_value,
										value=v_value,
										command=self.__on_button_change,
										state=s_state )

			self.__tooltip=ctt.insertNewlines( self.__tooltip )
			o_tooltip=ctt.CreateToolTip( o_radio_button,  self.__tooltip )

			i_row_val=i_rowcount
			i_column_val=0

			#if user wants buttons in a row
			#invert the default row,col vals:
			if self.__put_buttons_in_row == True:
				i_row_val=0
				i_column_val=i_rowcount
			#end if we want buttons in single row

			o_radio_button.grid( row = i_row_val, column = i_column_val, sticky=(NW) )

			if idx == self.__default_mode_number - 1:
				o_defaul_button=o_radio_button
			#end if this is the default button

			self.__radio_buttons.append( o_radio_button )

		#end for each index

		self.__current_button_value.set( o_defaul_button.cget( "value" ) )

		return
	#end __make_value_row

	def __on_button_change( self, event=None ):

		if self.__isenabled == False or self.__force_disable == True:
			return
		else:
			self.__reset_value()
		#end

		#we also re-assign the parent attribute (if the caller gave us a ref to it)
		#from which our key-value was derived
		if self.__associated_attribute is not None:

			#default object whose attribute is to be
			#updated is the master to this keyvalframe object
			if self.__associated_attribute_object is None:
				setattr( self.__master, self.__associated_attribute, self.__value )
			else:
				setattr( self.__associated_attribute_object, self.__associated_attribute, self.__value )
			#eend if attribute object is None, then use master, else use object
		#end if caller passed a def

		#if there is a command associated with a button change, execute:
		if self.__def_on_button_change is not None:
			self.__def_on_button_change()
		#end if change command

		return
	#end __on_button_change

	def setStateControls( self, s_state ):
		'''
		Set the state of all this objects
		radio buttons.
		'''
		for o_radio_button in self.__radio_buttons:
			o_radio_button.configure( state=s_state )
		#end for each entry box

		return
	#end disableControls

	def getControlStates( self ):
		ls_states=[]
		for o_radio_button in self.__radio_buttons:
			s_state=o_radio_button.cget( "state" )
			ls_states.append( s_state )
		#end for each entry box

		return ls_states
	#end

	@property
	def is_enabled( self ):
		return self.__isenabled
	#end property is_enabled

	@property
	def force_disable( self ):
		return self.__force_disable
	#end property force_disable

	@property
	def val( self ):
		return self.__value
	#end getter

	@val.deleter
	def val( self ):
		del self.__value
		return
	#end deleter
#end class KeyCategoricalValueFrame

if __name__ == "__main__":
	pass
#end if main


#!/urs/bin/env python
# -*- conding: utf-8 -*-
# @Author : Senci
# @Time   : 2020/3/6 14:45
# @File   : house-data.py

import requests
from bs4 import BeautifulSoup
import re

import pandas as pd
import random
import time

proxies={}
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
    'cookie': 'global_cookie=ndhzo4i3v9myct7aqau6zp6si10k0ncoeps; __utmz=147393320.1568695301.1.1.utmcsr=shbbs.fang.com|utmccn=(referral)|utmcmd=referral|utmcct=/esf~-1/538150834_538150842.htm; __utma=147393320.1476417876.1568695301.1568695301.1568771948.2; __utmc=147393320; Captcha=434D58793841766F7637624862786B682B684D4B454431767946477634343578436B6978474361474C45335739576D5139355553557463676C6150554F45377962612B456F624974536F383D; newhouse_user_guid=35B671E8-BF35-888C-AC78-ED09FB6489C8; newhouse_chat_guid=3262F18D-7EFB-AE4D-CC6E-D47888369019; g_sourcepage=esf_xq%5Elb_pc; __utmt_t0=1; __utmt_t1=1; __utmt_t2=1; unique_cookie=U_7eu0ocfmua6k7nyn858kd6mb727k0omb896*20; __utmb=147393320.60.10.1568771948'
}
url_souce = 'https://sz.esf.fang.com'

def get_true_url(old_url):
    '''获得正确的url'''
    # print(old_url)
    r = requests.get(url=old_url, headers=headers)
    if r'<title>跳转...</title>' in r.text:
        soup = BeautifulSoup(r.text, 'lxml')
        new_url = soup.find(name='a', attrs={'class': 'btn-redir'}).attrs['href']
        return new_url
    return old_url

def get_num():
    '''获取总页数'''

    true_url = r"https://sz.esf.fang.com/housing/85__1_0_0_0_1_0_0_0/"
    true_url = get_true_url(true_url)
    r = requests.get(url=true_url, headers=headers)
    soup = BeautifulSoup(r.text, 'lxml')
    a = soup.find('div', class_='fanye gray6').find('span',class_='txt').get_text()
    pag_num=int(re.findall(r"\d+",a)[0])
    print('===========================共{}页数==========================='.format(pag_num))
    return pag_num

def getUrls(page_num):
    '''当前页中小区的url'''
    urls = []
    p = page_num
    url_list=[]
    print('获取当前页中小区的URL中....')
    for i in range(1, p):
        url = 'https://sz.esf.fang.com/housing/85__1_0_0_0_'+str(i)+'_0_0_0/'
        #url = r"https://sz.esf.fang.com/housing/85__0_0_0_0_1_0_0_0/"https://antongdasha.fang.com/
        #print(url)
        reg_url = []
        true_url = get_true_url(url)
        try:
            r = requests.get(url=true_url, headers=headers)
        except:
            time.sleep(3)
            r = requests.get(url=true_url, headers=headers)
        soup = BeautifulSoup(r.text, 'lxml')
        for i in range(1, 20):
            if i < 10:
                i = "0" + str(i)
            reg_url.append('https:'+soup.find('div', id='houselist_B09_' + str(i)).find('a')[
                'href'])
            #print(reg_url)
        url_list.append(reg_url)
        #print(url_list)

    return url_list

def get_map_info(old_url):
    '''地图地理位置获取'''
    print('地图地理位置获取中....\n')
    #old_url = "https://sz.esf.fang.com/newsecond/map/NewHouse/NewProjMap.aspx?newcode=2810022810"
    true_url = get_true_url(old_url)
    r = requests.get(url=true_url, headers=headers)
    time.sleep(2)
    r.encoding = 'gb2312'
    soup = BeautifulSoup(r.text, 'lxml')
    a = soup.select('head script')[-2].text.strip()
    #print(a)
    x = re.findall(r'px:"(.*?)",',a)[0]
    y = re.findall(r'py:"(.*?)",',a)[0]
    map_info = [x,y]
    #print(map_info)
    return map_info

def get_house_deep_url(old_url):
    '''获得小区的详请URL'''
    # old_url ='https://doushihuayuan.fang.com/'
    true_url = get_true_url(old_url)
    r = requests.get(url=true_url, headers=headers,proxies=proxies)
    r.encoding = 'gb2312'
    soup = BeautifulSoup(r.text, 'lxml')
    deep_url = 'https:' + soup.find('li',id='kesfxqxq_A01_03_01').a['href']
    #print(deep_url)
    #print(type(deep_url))
    return deep_url

def get_house_info(old_url):
    '''获得小区的详细信息'''
    House_list = []
    House_dict = {'url':'空',
                   '小区名称': '空',
                   '别名':'空',
                   '本月均价':'空',
                   '小区地址':'空',
                   '行政区': '空',
                   '片区': '空',
                   '邮编': '空',
                   '产权描述': '空',
                   '物业类别': '空',
                   '建筑年代': '空',
                   '开发商': '空',
                   '建筑类型': '空',
                   '建筑面积': '空',
                   '占地面积': '空',
                   '房屋总数': '空',
                   '楼栋总数': '空',
                   '绿化率': '空',
                   '容积率': '空',
                   '物业费': '空',
                   '停车位': '空',
                   '交通状况': '空',
                   '周边信息': '空',
                   '地理位置': '空',
                   '更新时间': '空'
}
    deep_url = get_house_deep_url(old_url)
    true_url = get_true_url(deep_url)
    r = requests.get(url=true_url, headers=headers,proxies=proxies)
    time.sleep(3)
    r.encoding = 'gb2312'
    soup = BeautifulSoup(r.text, 'lxml')
    name = soup.find('div', class_='ceninfo_sq').find('a', class_="tt").get_text()

    print(name)
    print(true_url)
    print('获得小区的详细信息中....')
    try:
        other_name= soup.find('div', class_='ceninfo_sq').find('span', class_="bm_title").get_text().split("别名：")[-1]
    except:
        other_name = '无别名'
    Average_price_info = soup.find('div', class_="box detaiLtop mt20 clearfix").find_all('span')
    Average_price_current_month = Average_price_info[0].get_text()
    Average_price_last_month = Average_price_info[1].get_text()
    Average_price_last_year = Average_price_info[-1].get_text()
    House_info = soup.find('div', class_='inforwrap clearfix').find_all('dd')
    Supporting_facilities = soup.find_all('dl', class_='clearfix mr30')[-1]
    Traffic_info = soup.find_all('dl', class_='floatl mr30')[0]
    Address_info = soup.select('body > div.wrap > div.con.clearfix > div.con_left > div:nth-child(6) > div.detailMapwrap > dt > iframe')
    #print(Address_info)
    # print(type(Address_info[0]))
    #print(true_url)
    # print(add_re)
    info = soup.find_all('dl', class_='floatl mr30')[-1]
    House_dict['url'] = true_url
    House_dict['小区名称'] = name
    House_dict['别名'] = other_name
    House_dict['本月均价'] = Average_price_current_month
    House_list.append(true_url)
    House_list.append(name)
    House_list.append(other_name)
    House_list.append(Average_price_current_month)
    try:
        add_re = 'https:' + re.findall(r'src="(.*?)"',str(Address_info))[-1]
    except:
        Address_info = soup.select('body > div.wrap > div.con.clearfix > div.con_left > div:nth-child(5) > div.detailMapwrap > dt > iframe')
        add_re = 'https:' + re.findall(r'src="(.*?)"', str(Address_info))[-1]
    #print(add_re)
    map_info = get_map_info(add_re)
    House_dict['地理位置'] = map_info
    # print(name)
    # print(other_name)
    # print(Average_price_current_month)
    # print(Average_price_last_month)
    # print(Average_price_last_year)
    # print(Traffic_info)
    # print(info)

    for item in House_info:
        #print(item)
        #print(item.find('strong').get_text())
        if item.find('strong').get_text() == '小区地址：':
            address = item.get('title')
            House_dict['小区地址']=address
            House_list.append(address)
            #print(address)
        elif item.find('strong').get_text() == '所属区域：':
            area1 = item.get_text().replace('所属区域：','')
            area1_1 = area1.split(' ')[0]
            area1_2 = area1.split(' ')[-1]
            House_dict['行政区'] = area1_1
            House_dict['片区'] = area1_2
            House_list.append(area1_1)
            House_list.append(area1_2)
            #print(area1.split(' ')[0])
            #print(area1.split(' ')[-1])
        elif item.find('strong').get_text() == '邮    编：':
            area2 = item.get_text().replace('邮    编：','')
            House_dict['邮编'] = area2
            House_list.append(area2)
            #print(area2)
        #########
        elif item.find('strong').get_text() == '产权描述：':
            area3 = item.get_text().replace('产权描述：','')
            House_dict['产权描述'] = area3
            House_list.append(area3)
            #print(area3)
            #print(House_dict['产权描述'])
        #########
        elif item.find('strong').get_text() == '物业类别：':
            area4 = item.get_text().replace('物业类别：','')
            House_dict['物业类别'] = area4
            House_list.append(area4)
            #print(area4)
        elif item.find('strong').get_text() == '建筑年代：':
            area5 = item.get_text().replace('建筑年代：', '')
            House_dict['建筑年代'] = area5
            House_list.append(area5)
            #print(area5)
        elif item.find('strong').get_text() == '开 发 商：':
            area6 = item.get_text().replace('开 发 商：','')
            House_dict['开发商'] = area6
            House_list.append(area6)
            #print(area6)
        elif item.find('strong').get_text() == '建筑类型：':
            area7 = item.get_text().replace('建筑类型：','')
            House_dict['建筑类型'] = area7
            House_list.append(area7)
            #print(area7)

        elif item.find('strong').get_text() == '建筑面积：':
            area8 = item.get_text().replace('建筑面积：','')
            House_dict['建筑面积'] = area8
            House_list.append(area8)
            #print(area9)
        elif item.find('strong').get_text() == '占地面积：':
            area9 = item.get_text().replace('占地面积：','')
            House_dict['占地面积'] = area9
            House_list.append(area9)
            #print(area10)
        elif item.find('strong').get_text() == '房屋总数：':
            area10 = item.get_text().replace('房屋总数：','')
            House_dict['房屋总数'] = area10
            House_list.append(area10)
            #print(area11)
        elif item.find('strong').get_text() == '楼栋总数：':
            area11 = item.get_text().replace('楼栋总数：','')
            House_dict['楼栋总数'] = area11
            House_list.append(area11)
            #print(area12)
        elif item.find('strong').get_text() == '绿 化 率：':
            area12 = item.get_text().replace('绿 化 率：','')
            House_dict['绿化率'] = area12
            House_list.append(area12)
            #print(area13)
        elif item.find('strong').get_text() == '容 积 率：':
            area13 = item.get_text().replace('容 积 率：','')
            House_dict['容积率'] = area13
            House_list.append(area13)
            #print(area14)
        elif item.find('strong').get_text() == '物 业 费：':
            area14 = item.get_text().replace('物 业 费：','')
            House_dict['物业费'] = area14
            House_list.append(area14)
            #print(area15)
    for item in Traffic_info:
        try:
            if '本段合作编辑者' not in item.get_text():
                Traffic = item.get_text()
                House_dict['交通状况'] = Traffic
                #print(House_dict['交通状况'])
                House_list.append(Traffic)
                #print(Traffic)
        except AttributeError as AE:
            pass
    info_list = []
    for item in info:
        try:
            if '本段合作编辑者' not in item.get_text():
                other_info = item.get_text()
                info_list.append(other_info)
                # print("-----")
                #info_list.append(other_info)
        except AttributeError as AE:
            pass
    info_str = '|'.join(info_list)
    House_dict['周边信息'] = info_str
    House_list.append(info_list)
    for item in Supporting_facilities:
        try:
            if item.find('strong').get_text() == '停 车 位：':
                part1 = item.get_text().replace('停 车 位：', '')
                House_dict['停车位'] = part1
                House_list.append(part1)

        except AttributeError as AE:
            pass

    House_list.append(None)
    #时间
    Now_time = time.strftime('%Y-%m-%d %H:%M',time.localtime(time.time()))
    House_dict['更新时间'] = Now_time
    House_list.append(Now_time)

    #print(House_dict)
    return House_dict

def get_ip():
    '''获取ip'''
    r = ['192.168.100.198:8888','Error004','Error888']
    return random.choice(r)

def dic2pd(House_All_list):
    '''数据转换为pandas'''
    print('数据转换为pandas中....')
    House_All_DF = pd.DataFrame(House_All_list)
    print(House_All_DF)

    return House_All_DF

# def list2pd(House_All_list):
#
#     columns_list = ['url','小区名称','别名','本月均价',
#                    '小区地址','行政区','片区','邮编','产权描述','物业类别',
#                    '建筑年代','开发商','建筑类型','建筑面积','占地面积','房屋总数',
#                    '楼栋总数','绿化率','容积率','物业费','停车位','交通状况','周边信息','地理位置','更新时间']
#     House_DF = pd.DataFrame(House_All_list,columns=columns_list)
#     print(House_DF.head())
#     return House_DF

def pd2csv(House_DF,file_name):
    '''存储csv文件'''
    print('存储csv文件中....')
    #file_name = 'test1.csv'
    file_name = file_name+'.csv'
    try:
        House_DF.to_csv(file_name,encoding="utf_8_sig")
    except UnicodeEncodeError:
        print("编码错误, 该数据无法写到文件中, 直接忽略该数据")

def run_log(start_time,end_time,ip_num,house_cout):
    '''日志生成'''
    print('日志生成中....')
    with open('run_log.txt', 'a', encoding='utf-8') as file:
        file.write(start_time+'\t'+end_time+'\t'+ip_num+'\t'+house_cout)
        file.write('\n')

def ip_proxy():
    '''检查代理ip是否正常'''
    print('检查代理ip是否正常中....')
    ip_num = 0
    ip = get_ip()
    Error004_status=False
    proxies_inter={}
    while 'Error' in ip:
        if 'Error004' in ip:
            print("Error004 异常,结束程序....")
            ip_num += 1
            Error004_status = True
            #print(ip_num)
            break
        else:
            print('进入十秒等待....')
            time.sleep(10)
            ip = get_ip()
            ip_num += 1
            continue
    else:
        ip_num += 1
        proxy_ip=('http://' + ip)
        proxies_inter = {'http': proxy_ip}

    #print(proxies_inter)
    #print(ip_num)
    return (proxies_inter,ip_num,Error004_status)

def main():
    '''入口函数'''

    file_name = input("请输入文件名：")
    ip_num = 0
    house_cout = 1
    start_time = time.strftime('%Y-%m-%d %H:%M',time.localtime(time.time()))
    House_All_list = []
    ##########################################
    # proxies,ip_num,Error004_status= ip_proxy()
    # if Error004_status == True:
    #     print("关闭程序，日志提前结束")
    #     end_time = time.strftime('%Y-%m-%d %H:%M', time.localtime(time.time()))
    #     print(house_cout)
    #     print(start_time)
    #     print(end_time)
    #     run_log(start_time, end_time, str(ip_num), str(house_cout))
    #     exit()
    ##########################################
    pag_num = get_num()
    reg_urls_list = getUrls(pag_num)
    for i,each in enumerate(reg_urls_list):
        print('===========================当前页数：%d===========================\n'%(i+1))
        for url in each:
            House_All = get_house_info(url)
            House_All_list.append(House_All)
            house_cout +=1
    House_DF = dic2pd(House_All_list)
    pd2csv(House_DF,file_name)
    end_time = time.strftime('%Y-%m-%d %H:%M',time.localtime(time.time()))
    run_log(start_time,end_time,str(ip_num),str(house_cout))
    print('===========================完成爬取===========================')

if __name__ == '__main__':
    main()
    #get_house_info()
    #get_house_deep_url()


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

import torch
from torch import nn
from torch.autograd import Variable
from sklearn import preprocessing

from rnn_prepare import set_data_9, set_data_10

class RNN(nn.Module):
    def __init__(self):
        super(RNN, self).__init__()

        self.rnn = nn.RNN(
            input_size=INPUT_SIZE,
            hidden_size=32,     # rnn hidden unit
            num_layers=6,       # number of rnn layer
            batch_first=True,   # input & output will has batch size as 1s dimension. e.g. (batch, time_step, input_size)
        )
        self.out = nn.Linear(32, 1)

    def forward(self, x, h_state):
        # x (batch, time_step, input_size)
        # h_state (n_layers, batch, hidden_size)
        # r_out (batch, time_step, hidden_size)
        r_out, h_state = self.rnn(x, h_state)

        outs = []    # save all predictions
        for time_step in range(r_out.size(1)):    # calculate output for each time step
            outs.append(self.out(r_out[:, time_step, :]))
        return torch.stack(outs, dim=1), h_state

def read_data(f):
    data = pd.read_csv(f)
    data['date'] = range(len(data))
    data.columns = ['count', 'date']
    # data = data.set_index('date')
    # data.index = pd.to_datetime(data.index)
    ts = data['count']
    # draw_ts(ts)  # 绘图
    return ts

if __name__ == '__main__':
    torch.manual_seed(1)    # reproducible

    # Hyper Parameters
    TIME_STEP = 10      # rnn time step
    INPUT_SIZE = 1      # rnn input size
    LR = 0.01           # learning rate
    length = 0          # 绘图用长度

    # show data
    file_9 = './data/data_after_kalman/sample9/bicycle/bicycle01.txt'
    file_10 = './data/data_after_kalman/sample10/bicycle/bicycle01.txt'
    # 用9轴数据预测10轴数据
    freq, waves, test_size = set_data_10(file_9, file_10)
    filename_9 = './data/cycle_9.txt'
    filename_10 = './data/cycle_10.txt'
    ts_9 = read_data(filename_9).values # 读取数据
    ts_10 = read_data(filename_10).values

    # 标准化
    ts_9 = preprocessing.scale(ts_9) * 10
    ts_10 = preprocessing.scale(ts_10) * 10

    # 绘图
    # plt.subplot(211)
    # plt.plot(ts_9)
    # plt.subplot(212)
    # plt.plot(ts_10)

    rnn = RNN().double()
    print(rnn)

    optimizer = torch.optim.Adam(rnn.parameters(), lr=LR)   # optimize all cnn parameters
    loss_func = nn.MSELoss()

    h_state = None      # for initial hidden state

    plt.figure(1, figsize=(12, 5))
    plt.ion()           # continuously plot

    for step in range(len(waves)):
        start, end = waves[step][0], waves[step][2]   # time range
        # use sin predicts cos
        # x_np = ts_9[start:end]    # float32 for converting torch FloatTensor
        x_np = ts_10[start:end]
        y_np = ts_10[start:end]

        x = Variable(torch.from_numpy(x_np[np.newaxis, :, np.newaxis]))    # shape (batch, time_step, input_size)
        y = Variable(torch.from_numpy(y_np[np.newaxis, :, np.newaxis]))

        prediction, h_state = rnn(x, h_state)   # rnn output
        # !! next step is important !!
        h_state = Variable(h_state.data)        # repack the hidden state, break the connection from last iteration

        loss = loss_func(prediction, y)         # cross entropy loss
        optimizer.zero_grad()                   # clear gradients for this training step
        loss.backward()                         # backpropagation, compute gradients
        optimizer.step()                        # apply gradients

        # plotting
        plt.plot(range(length, length + len(y_np.flatten())), y_np.flatten(), 'r-')
        plt.plot(range(length, length + len(y_np.flatten())), prediction.data.numpy().flatten(), 'b-')
        plt.draw()
        plt.pause(0.05)

        length = length + len(y_np.flatten())


#!/usr/bin/python3
# Write a Python script that takes in a URL, sends a request to the URL and displays the body of the response.
import requests
import sys

# Check if a URL argument is provided
if len(sys.argv) != 2:
    print("Usage: python script.py <URL>")
    sys.exit(1)

url = sys.argv[1]

try:
    response = requests.get(url)

    # Check the HTTP status code
    if response.status_code >= 400:
        print(f"Error code: {response.status_code}")
    else:
        # Display the body of the response
        print("Response body:")
        print(response.text)

except requests.exceptions.RequestException as e:
    print("Error:", e)


def find_anagrams(s, p):

    result = []

    cnts = [0] * 26
    for c in p:
        cnts[ord(c) - ord('a')] += 1

    left, right = 0, 0
    while right < len(s):
        cnts[ord(s[right]) - ord('a')] -= 1
        while left <= right and cnts[ord(s[right]) - ord('a')] < 0:
            cnts[ord(s[left]) - ord('a')] += 1
            left += 1
        if right - left + 1 == len(p):
            result.append(left)
        right += 1

    return result

print(find_anagrams("cbaebabacd", "abc"))


#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Auther : Jianghao
# Date : 2017/11/18

# l=['alex_SB','wupeiqi_SB','yuanhao_SB','egon']
# # res=filter(lambda x:x.endswith('SB'),l)      #匿名函数是判断是否以xxx结尾，
# # # 得到bool值--是就True不是Flase，filter就是利用这个bool值--filter会依次迭代l进行匿名函数运算，结果是True就被过滤出来了
# # print(res)
# # print(list(res))
# aaa = int(123)
# cc = str(aaa)
# print(cc,id(cc))
# print(cc,id(cc))

ss=1
def s1():
    print(ss)

s1()

for p in range(5):
    print(p)


import os
import collections
import logging

import yaml
import torch
import joblib
import numpy as np

from mathtools import utils, torchutils, metrics
from kinemparse import assembly as lib_assembly
import make_data

logger = logging.getLogger(__name__)

class DummyClassifier(torch.nn.Module):
    def __init__(self, input_dim, out_set_size, binary_multiclass=False):
        super().__init__()

        self.input_dim = input_dim
        self.out_set_size = out_set_size

        logger.info(
            f'Initialized dummy classifier. '
            f'Input dim: {self.input_dim}, Output dim: {self.out_set_size}'
        )

    def forward(self, input_seq):
        return input_seq.transpose(1, 2)

    def predict(self, outputs):
        __, preds = torch.max(outputs, -1)
        return preds

def adjacencies(assembly, link_names, lower_tri_only=False):
    name_to_index = {name: i for i, name in enumerate(link_names)}
    num_links = len(link_names)
    adjacencies = torch.zeros(num_links, num_links, dtype=torch.bool)
    for joint in assembly.joints.values():
        parent_index = name_to_index[joint.parent_name]
        child_index = name_to_index[joint.child_name]
        adjacencies[parent_index, child_index] = True
        adjacencies[child_index, parent_index] = True

    if lower_tri_only:
        rows, cols = np.tril_indices(adjacencies.shape[1], k=-1)
        adjacencies = adjacencies[rows, cols]

    return adjacencies

class AssemblyClassifier(torch.nn.Module):
    def __init__(
            self, assemblies, link_names,
            scale=1, alpha=1, update_params=False, eq_classes=None):
        super().__init__()

        self.assembly_vocab = assemblies
        self.link_vocab = link_names
        self.eq_classes = torch.tensor(eq_classes, dtype=torch.float)

        self._scale = torch.nn.Parameter(
            torch.tensor(scale, dtype=torch.float),
            requires_grad=update_params
        )
        self._alpha = torch.nn.Parameter(
            torch.tensor(alpha, dtype=torch.float),
            requires_grad=update_params
        )

        self._part_pair_names = make_data.makePairs(link_names, lower_tri_only=True)
        self._pair_is_possible = make_data.possibleConnections(self._part_pair_names)

    def forward(self, input_seq):
        output_seq = tuple(self._score_assembly(input_seq, a) for a in self.assembly_vocab)
        output_seq = torch.stack(output_seq, axis=-1)

        if self.eq_classes is not None:
            output_seq = output_seq @ self.eq_classes

        return output_seq

    def _score_assembly(self, input_seq, assembly):
        """
        Parameters
        ----------
        input_seq : torch.Tensor, shape (batch_size, num_edges, num_samples, num_features)
        assembly : assembly.Assembly

        Returns
        -------
        scores : torch.Tensor, shape (batch_size, num_samples)
        """
        input_seq = input_seq.sum(axis=-1)
        edge_is_observed = ~torch.isnan(input_seq)
        input_seq[~edge_is_observed] = 0

        edge_is_present = adjacencies(assembly, self.link_vocab, lower_tri_only=True)
        edge_is_present = edge_is_present[self._pair_is_possible]

        if not edge_is_present.any():
            shape = (input_seq.shape[0], input_seq.shape[-1])
            edge_scores = torch.zeros(shape, dtype=torch.float)
        else:
            edge_features = input_seq[:, edge_is_present, :]
            edge_scores = torch.sum(
                -edge_features * edge_is_observed[:, edge_is_present, :],
                axis=1
            )

        if not (~edge_is_present).any():
            shape = (input_seq.shape[0], input_seq.shape[-1])
            no_edge_scores = torch.zeros(shape, dtype=torch.float)
        else:
            no_edge_features = input_seq[:, ~edge_is_present, :]
            no_edge_scores = torch.sum(
                torch.ones_like(no_edge_features) * edge_is_observed[:, ~edge_is_present, :],
                axis=1
            )

        scores = self._scale * edge_scores + self._alpha * no_edge_scores
        return scores

    def predict(self, outputs):
        __, preds = torch.max(outputs, -1)
        return preds

def makeEqClasses(assembly_vocab, part_symmetries):
    def renameLink(assembly, old_name, new_name):
        link_dict = {}
        for link in assembly.links.values():
            new_link = lib_assembly.Link(
                link.name.replace(old_name, new_name),
                pose=link.pose
            )
            if new_link.name in link_dict:
                if link_dict[new_link.name] != new_link:
                    raise AssertionError()
                continue
            else:
                link_dict[new_link.name] = new_link
        new_links = list(link_dict.values())

        new_joints = [
            lib_assembly.Joint(
                joint.name.replace(old_name, new_name),
                joint.joint_type,
                joint.parent_name.replace(old_name, new_name),
                joint.child_name.replace(old_name, new_name),
                transform=joint._transform
            )
            for joint in assembly.joints.values()
        ]

        new_assembly = lib_assembly.Assembly(links=new_links, joints=new_joints)
        return new_assembly

    eq_class_vocab = []
    assembly_eq_classes = []
    for vocab_index, assembly in enumerate(assembly_vocab):
        for new_name, old_names in part_symmetries.items():
            for old_name in old_names:
                assembly = renameLink(assembly, old_name, new_name)
        eq_class_index = utils.getIndex(assembly, eq_class_vocab)
        assembly_eq_classes.append(eq_class_index)

    assembly_eq_classes = np.array(assembly_eq_classes)

    eq_classes = np.zeros((len(assembly_vocab), len(eq_class_vocab)), dtype=float)
    for vocab_index, eq_class_index in enumerate(assembly_eq_classes):
        eq_classes[vocab_index, eq_class_index] = 1
    eq_classes /= eq_classes.sum(axis=0)

    # import pdb; pdb.set_trace()

    return eq_classes, assembly_eq_classes, eq_class_vocab

def main(
        out_dir=None, data_dir=None, model_name=None, part_symmetries=None,
        gpu_dev_id=None, batch_size=None, learning_rate=None,
        model_params={}, cv_params={}, train_params={}, viz_params={},
        plot_predictions=None, results_file=None, sweep_param_name=None):

    if part_symmetries is None:
        part_symmetries = {
            'beam_side': (
                'backbeam_hole_1', 'backbeam_hole_2',
                'frontbeam_hole_1', 'frontbeam_hole_2'
            ),
            'beam_top': ('backbeam_hole_3', 'frontbeam_hole_3'),
            'backrest': ('backrest_hole_1', 'backrest_hole_2')
        }

    data_dir = os.path.expanduser(data_dir)
    out_dir = os.path.expanduser(out_dir)
    if not os.path.exists(out_dir):
        os.makedirs(out_dir)

    logger = utils.setupRootLogger(filename=os.path.join(out_dir, 'log.txt'))

    if results_file is None:
        results_file = os.path.join(out_dir, 'results.csv')
    else:
        results_file = os.path.expanduser(results_file)

    fig_dir = os.path.join(out_dir, 'figures')
    if not os.path.exists(fig_dir):
        os.makedirs(fig_dir)

    out_data_dir = os.path.join(out_dir, 'data')
    if not os.path.exists(out_data_dir):
        os.makedirs(out_data_dir)

    def saveVariable(var, var_name):
        joblib.dump(var, os.path.join(out_data_dir, f'{var_name}.pkl'))

    def loadAll(seq_ids, var_name, data_dir):
        def loadOne(seq_id):
            fn = os.path.join(data_dir, f'trial={seq_id}_{var_name}')
            return joblib.load(fn)
        return tuple(map(loadOne, seq_ids))

    # Load vocab
    with open(os.path.join(data_dir, "part-vocab.yaml"), 'rt') as f:
        link_vocab = yaml.safe_load(f)
    assembly_vocab = joblib.load(os.path.join(data_dir, 'assembly-vocab.pkl'))

    # Load data
    trial_ids = utils.getUniqueIds(data_dir, prefix='trial=')
    feature_seqs = loadAll(trial_ids, 'feature-seq.pkl', data_dir)
    label_seqs = loadAll(trial_ids, 'label-seq.pkl', data_dir)

    if part_symmetries:
        # Construct equivalence classes from vocab
        eq_classes, assembly_eq_classes, eq_class_vocab = makeEqClasses(
            assembly_vocab, part_symmetries
        )
        lib_assembly.writeAssemblies(
            os.path.join(fig_dir, 'eq-class-vocab.txt'),
            eq_class_vocab
        )
        label_seqs = tuple(assembly_eq_classes[label_seq] for label_seq in label_seqs)
        saveVariable(eq_class_vocab, 'assembly-vocab')
    else:
        eq_classes = None

    def impute_nan(input_seq):
        input_is_nan = np.isnan(input_seq)
        logger.info(f"{input_is_nan.sum()} NaN elements")
        input_seq[input_is_nan] = 0  # np.nanmean(input_seq)
        return input_seq

    # feature_seqs = tuple(map(impute_nan, feature_seqs))

    for trial_id, label_seq, feat_seq in zip(trial_ids, label_seqs, feature_seqs):
        saveVariable(feat_seq, f"trial={trial_id}_feature-seq")
        saveVariable(label_seq, f"trial={trial_id}_label-seq")

    device = torchutils.selectDevice(gpu_dev_id)

    # Define cross-validation folds
    dataset_size = len(trial_ids)
    cv_folds = utils.makeDataSplits(dataset_size, **cv_params)

    def getSplit(split_idxs):
        split_data = tuple(
            tuple(s[i] for i in split_idxs)
            for s in (feature_seqs, label_seqs, trial_ids)
        )
        return split_data

    for cv_index, cv_splits in enumerate(cv_folds):
        train_data, val_data, test_data = tuple(map(getSplit, cv_splits))

        train_feats, train_labels, train_ids = train_data
        train_set = torchutils.SequenceDataset(
            train_feats, train_labels,
            device=device, labels_dtype=torch.long, seq_ids=train_ids,
            transpose_data=True
        )
        train_loader = torch.utils.data.DataLoader(
            train_set, batch_size=batch_size, shuffle=True
        )

        test_feats, test_labels, test_ids = test_data
        test_set = torchutils.SequenceDataset(
            test_feats, test_labels,
            device=device, labels_dtype=torch.long, seq_ids=test_ids,
            transpose_data=True
        )
        test_loader = torch.utils.data.DataLoader(
            test_set, batch_size=batch_size, shuffle=False
        )

        val_feats, val_labels, val_ids = val_data
        val_set = torchutils.SequenceDataset(
            val_feats, val_labels,
            device=device, labels_dtype=torch.long, seq_ids=val_ids,
            transpose_data=True
        )
        val_loader = torch.utils.data.DataLoader(val_set, batch_size=batch_size, shuffle=True)

        logger.info(
            f'CV fold {cv_index + 1} / {len(cv_folds)}: {len(trial_ids)} total '
            f'({len(train_ids)} train, {len(val_ids)} val, {len(test_ids)} test)'
        )

        input_dim = train_set.num_obsv_dims
        output_dim = train_set.num_label_types
        if model_name == 'linear':
            model = torchutils.LinearClassifier(
                input_dim, output_dim, **model_params
            ).to(device=device)
        elif model_name == 'dummy':
            model = DummyClassifier(input_dim, output_dim, **model_params)
        elif model_name == 'AssemblyClassifier':
            model = AssemblyClassifier(
                assembly_vocab, link_vocab, eq_classes=eq_classes,
                **model_params
            )
        else:
            raise AssertionError()

        criterion = torch.nn.CrossEntropyLoss()
        if model_name != 'dummy':
            train_epoch_log = collections.defaultdict(list)
            val_epoch_log = collections.defaultdict(list)
            metric_dict = {
                'Avg Loss': metrics.AverageLoss(),
                'Accuracy': metrics.Accuracy(),
                'Precision': metrics.Precision(),
                'Recall': metrics.Recall(),
                'F1': metrics.Fmeasure()
            }

            optimizer_ft = torch.optim.Adam(
                model.parameters(), lr=learning_rate,
                betas=(0.9, 0.999), eps=1e-08,
                weight_decay=0, amsgrad=False
            )
            lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer_ft, step_size=1, gamma=1.00)

            model, last_model_wts = torchutils.trainModel(
                model, criterion, optimizer_ft, lr_scheduler,
                train_loader, val_loader,
                device=device,
                metrics=metric_dict,
                train_epoch_log=train_epoch_log,
                val_epoch_log=val_epoch_log,
                **train_params
            )

        logger.info(f'scale={float(model._scale)}')
        logger.info(f'alpha={float(model._alpha)}')

        # Test model
        metric_dict = {
            'Avg Loss': metrics.AverageLoss(),
            'Accuracy': metrics.Accuracy(),
            'Precision': metrics.Precision(),
            'Recall': metrics.Recall(),
            'F1': metrics.Fmeasure()
        }
        test_io_history = torchutils.predictSamples(
            model.to(device=device), test_loader,
            criterion=criterion, device=device,
            metrics=metric_dict, data_labeled=True, update_model=False,
            seq_as_batch=train_params['seq_as_batch'],
            return_io_history=True
        )

        metric_str = '  '.join(str(m) for m in metric_dict.values())
        logger.info('[TST]  ' + metric_str)

        d = {k: v.value for k, v in metric_dict.items()}
        utils.writeResults(results_file, d, sweep_param_name, model_params)

        if plot_predictions:
            io_fig_dir = os.path.join(fig_dir, 'model-io')
            if not os.path.exists(io_fig_dir):
                os.makedirs(io_fig_dir)

            label_names = ('gt', 'pred')
            preds, scores, inputs, gt_labels, ids = zip(*test_io_history)
            for batch in test_io_history:
                batch = tuple(
                    x.cpu().numpy() if isinstance(x, torch.Tensor) else x
                    for x in batch
                )
                for preds, _, inputs, gt_labels, seq_id in zip(*batch):
                    fn = os.path.join(io_fig_dir, f"trial={seq_id}_model-io.png")
                    utils.plot_array(
                        inputs.sum(axis=-1), (gt_labels, preds), label_names,
                        fn=fn, **viz_params
                    )

        def saveTrialData(pred_seq, score_seq, feat_seq, label_seq, trial_id):
            saveVariable(pred_seq, f'trial={trial_id}_pred-label-seq')
            saveVariable(score_seq, f'trial={trial_id}_score-seq')
            saveVariable(label_seq, f'trial={trial_id}_true-label-seq')
        for batch in test_io_history:
            batch = tuple(
                x.cpu().numpy() if isinstance(x, torch.Tensor) else x
                for x in batch
            )
            for io in zip(*batch):
                saveTrialData(*io)

        saveVariable(train_ids, f'cvfold={cv_index}_train-ids')
        saveVariable(test_ids, f'cvfold={cv_index}_test-ids')
        saveVariable(val_ids, f'cvfold={cv_index}_val-ids')
        saveVariable(train_epoch_log, f'cvfold={cv_index}_{model_name}-train-epoch-log')
        saveVariable(val_epoch_log, f'cvfold={cv_index}_{model_name}-val-epoch-log')
        saveVariable(metric_dict, f'cvfold={cv_index}_{model_name}-metric-dict')
        saveVariable(model, f'cvfold={cv_index}_{model_name}-best')

        train_fig_dir = os.path.join(fig_dir, 'train-plots')
        if not os.path.exists(train_fig_dir):
            os.makedirs(train_fig_dir)

        if train_epoch_log:
            torchutils.plotEpochLog(
                train_epoch_log,
                subfig_size=(10, 2.5),
                title='Training performance',
                fn=os.path.join(train_fig_dir, f'cvfold={cv_index}_train-plot.png')
            )

        if val_epoch_log:
            torchutils.plotEpochLog(
                val_epoch_log,
                subfig_size=(10, 2.5),
                title='Heldout performance',
                fn=os.path.join(train_fig_dir, f'cvfold={cv_index}_val-plot.png')
            )

if __name__ == "__main__":
    # Parse command-line args and config file
    cl_args = utils.parse_args(main)
    config, config_fn = utils.parse_config(cl_args, script_name=__file__)

    # Create output directory, instantiate log file and write config options
    out_dir = os.path.expanduser(config['out_dir'])
    if not os.path.exists(out_dir):
        os.makedirs(out_dir)
    with open(os.path.join(out_dir, config_fn), 'w') as outfile:
        yaml.dump(config, outfile)
    utils.copyFile(__file__, out_dir)

    main(**config)