from zope.component import getUtility, getMultiAdapter

from plone.portlets.interfaces import IPortletType
from plone.portlets.interfaces import IPortletManager
from plone.portlets.interfaces import IPortletAssignment
from plone.portlets.interfaces import IPortletDataProvider
from plone.portlets.interfaces import IPortletRenderer

from plone.app.portlets.storage import PortletAssignmentMapping

from optilux.cinemacontent.portlets import promotions

from optilux.cinemacontent.tests.base import CinemaContentTestCase

class TestPortlet(CinemaContentTestCase):

    def afterSetUp(self):
        self.setRoles(('Manager',))

    def testPortletTypeRegistered(self):
        portlet = getUtility(IPortletType, name='optilux.Promotions')
        self.assertEquals(portlet.addview, 'optilux.Promotions')

    def testInterfaces(self):
        portlet = promotions.Assignment()
        self.failUnless(IPortletAssignment.providedBy(portlet))
        self.failUnless(IPortletDataProvider.providedBy(portlet.data))

    def testInvokeAddview(self):
        portlet = getUtility(IPortletType, name='optilux.Promotions')
        mapping = self.portal.restrictedTraverse('++contextportlets++plone.leftcolumn')
        for m in mapping.keys():
            del mapping[m]
        addview = mapping.restrictedTraverse('+/' + portlet.addview)

        addview.createAndAdd(data={})

        self.assertEquals(len(mapping), 1)
        self.failUnless(isinstance(mapping.values()[0], promotions.Assignment))

    def testInvokeEditView(self):
        mapping = PortletAssignmentMapping()
        request = self.folder.REQUEST

        mapping['foo'] = promotions.Assignment()
        editview = getMultiAdapter((mapping['foo'], request), name='edit')
        self.failUnless(isinstance(editview, promotions.EditForm))

    def testRenderer(self):
        context = self.folder
        request = self.folder.REQUEST
        view = self.folder.restrictedTraverse('@@plone')
        manager = getUtility(IPortletManager, name='plone.rightcolumn', context=self.portal)
        assignment = promotions.Assignment()

        renderer = getMultiAdapter((context, request, view, manager, assignment), IPortletRenderer)
        self.failUnless(isinstance(renderer, promotions.Renderer))

class TestRenderer(CinemaContentTestCase):

    def afterSetUp(self):
        self.setRoles(('Manager',))
        self.portal.invokeFactory('Cinema Folder', 'cf1')
        self.portal.invokeFactory('Cinema Folder', 'cf2')
        self.portal.cf1.invokeFactory('Promotion', 'p1')
        self.portal.cf1.invokeFactory('Promotion', 'p2')
        self.portal.cf1.invokeFactory('Promotion', 'p3')
        self.portal.cf1.invokeFactory('Promotion', 'p4')
        self.portal.cf1.invokeFactory('Promotion', 'p5')
        self.portal.cf2.invokeFactory('Promotion', 'p6')
        self.portal.cf2.invokeFactory('Promotion', 'p7')

    def renderer(self, context=None, request=None, view=None, manager=None, assignment=None):
        context = context or self.folder
        request = request or self.folder.REQUEST
        view = view or self.folder.restrictedTraverse('@@plone')
        manager = manager or getUtility(IPortletManager, name='plone.rightcolumn', context=self.portal)
        assignment = assignment or promotions.Assignment()

        return getMultiAdapter((context, request, view, manager, assignment), IPortletRenderer)

    def test_count(self):
        r = self.renderer(context=self.portal.cf1, assignment=promotions.Assignment(count=5))
        self.assertEquals(5, len([p for p in r.promotions()]))

    def test_randomize(self):
        r = self.renderer(context=self.portal.cf1, assignment=promotions.Assignment(count=5, randomize=True))
        self.assertEquals(5, len([p for p in r.promotions()]))
        # Mmmm, hard to test for random things :)

    def test_sitewide(self):
        r = self.renderer(context=self.portal.cf1, assignment=promotions.Assignment(count=10, sitewide=True))
        p6_url = self.portal.cf2.p6.absolute_url()
        self.failUnless(p6_url in [p['url'] for p in r.promotions()])

def test_suite():
    from unittest import TestSuite, makeSuite
    suite = TestSuite()
    suite.addTest(makeSuite(TestPortlet))
    suite.addTest(makeSuite(TestRenderer))
    return suite


from django.urls import path
from .views import (
    create_blog_view,
    detail_blog_view,
    edit_blog_view,
    delete_blog_view,
    delete_comment_view,
    post_list_view,
    up_vote_view,
)

app_name = 'forum'

urlpatterns = [
    path('', post_list_view, name="post_list"),
    path('create/', create_blog_view, name="create"),
    path('<id>/<title>/', detail_blog_view, name="detail"),
    path('<id>/<title>/edit/', edit_blog_view, name="edit"),
    path('<id>/<title>/delete/', delete_blog_view, name='delete'),

    # comments
    path('<id>/<title>/comment/<cid>/delete', delete_comment_view, name='comment_delete'),

    # vote
    path('up/<id>/<title>', up_vote_view, name='up_vote'),

]


class Solution(object):
    def longestCommonPrefix(self, strs):
        """
        :type strs: List[str]
        :rtype: str
        """
        ####First Try
        ###if not strs: return false
        ###pre = min(strs, key=len)

        ###for i in range(len(pre)):
        ###	for s in strs:
        ###		if s[i] != pre[i]:
        ###			return pre[:i]
        ###return pre

        ####Second Try
        ###if not strs: return ""
        ###d = []
        ###for s in strs:
        ###    d.append(len(s))
        ###d=sorted(d)
        ###base=strs[0][:d[0]]
        #
        ###for i in range(len(base)):
        ###    for j in range(len(strs)):
        ###        if base[i]!=strs[j][i]:
        ###            return base[:i]
        ###return base

        ###third try
        if not strs:
            return ""

        for i in range(len(strs[0])):
            for string in strs:
                if i >= len(string) or string[i] != strs[0][i]:
                    return strs[0][:i]

        return strs[0]

if __name__=="__main__":
    strs=["flower","flow","flight"]
    ###strs = ["aa","a"]
    ###strs = ["dog","racecar","car"]
    results = Solution().longestCommonPrefix(strs)
    print(results)


#!/usr/bin/env python
#-*- coding:utf-8 -*-
#author: Enoch time:2018/10/22 0031

import time
import re
import operator
from string import punctuation
import sys
from collections import Counter

def ProcessLine0(line,counts):

    line = re.sub('[^a-z]', '', line)
    for ch in line:
        counts[ch] = counts.get(ch, 0) + 1
    return counts

def CountLetter(path):
    file = open(path, 'r')
    wordsCount = 0
    alphabetCounts = {}
    for line in file:
        alphabetCounts = ProcessLine0(line.lower(), alphabetCounts)
    wordsCount = sum(alphabetCounts.values())
    alphabetCounts = sorted(alphabetCounts.items(), key=lambda k: k[0])
    alphabetCounts = sorted(alphabetCounts, key=lambda k: k[1], reverse=True)
    for letter, fre in alphabetCounts:
    	print("|\t{:15}|{:<11.2%}|".format(letter, fre / wordsCount))

    file.close()

def CountWords1(file_name,n,stopName,verbName):
    print("File name:" + sys.path[0] + "\\" + file_name)
    if (stopName != None):
        stopflag = True
    else:
        stopflag = False
    if(verbName != None):
        verbflag = True
    else:
        verbflag = False

    with open(file_name) as f:
        txt = f.read()
    txt = txt.lower()
    if(stopflag == True):
        with open(stopName) as f:
            stoplist = f.readlines()
    pattern = r"[a-z][a-z0-9]*"
    wordList = re.findall(pattern,txt)
    totalNum = len(wordList)
    tempc = Counter(wordList)
    if (stopflag == True):
        for word in stoplist:
            word = word.replace('\n','')
            del tempc[word]
    dicNum = dict(tempc.most_common(n))
    if (verbflag == True):
        totalNum = 0
        verbDic = {}
        verbDicNum = {}
        with open(verbName) as f:
            for line in f.readlines():
                key,value = line.split('')
                verbDic[key] = value.replace('\n','').split(',')
                verbDicNum[key] = tempc[key]
                for word in verbDic[key]:
                    verbDicNum[key] += tempc[word]
                totalNum += verbDicNum[key]
        verbDicNum = sorted(verbDicNum.items(), key=lambda k: k[0])
        verbDicNum = sorted(verbDicNum, key=lambda k: k[1], reverse=True)
    dicNum = sorted(dicNum.items(), key=lambda k:k[0])
    dicNum = sorted(dicNum, key=lambda k:k[1], reverse=True)

    if (verbflag == True):
        print(verbDicNum[:n])
    else:
        print(dicNum)

def CountPhrases(file_name,n,stopName,verbName,k):
    print("File name:" + sys.path[0] + "\\" + file_name)
    totalNum = 0
    if (stopName != None):
        stopflag = True
    else:
        stopflag = False
    if(verbName != None):
        verbflag = True
    else:
        verbflag = False

    with open(file_name) as f:
        txt = f.read()
    txt = txt.lower()
    txt = re.sub(r'[\s|\']+',' ',txt)
    pword = r'(([a-z]+ )+[a-z]+)'  # extract sentence
    pattern = re.compile(pword)
    sentence = pattern.findall(txt)
    txt = ','.join([sentence[m][0] for m in range(len(sentence))])
    if(stopflag == True):
        with open(stopName) as f:
            stoplist = f.readlines()
    pattern = "[a-z]+[0-9]*"
    for i in range(k-1):
        pattern += "[\s|,][a-z]+[0-9]*"
    wordList = []
    for i in range(k):
        if( i == 0 ):
            tempList = re.findall(pattern, txt)
        else:
            wordpattern = "[a-z]+[0-9]*"
            txt = re.sub(wordpattern, '', txt, 1).strip()
            tempList = re.findall(pattern, txt)
        wordList += tempList
    tempc = Counter(wordList)
    if (stopflag == True):
        for word in stoplist:
            word = word.replace('\n','')
            del tempc[word]
    dicNum = {}
    if (verbflag == True):
        verbDic = {}
        with open(verbName) as f:
            for line in f.readlines():
                key,value = line.split(' -> ')
                for tverb in value.replace('\n', '').split(','):
                    verbDic[tverb] = key
                verbDic[key] = key
        for phrase in tempc.keys():
            if (',' not in phrase):
                totalNum += 1
                verbList = phrase.split(' ')
                normPhrase = verbList[0]
                for verb in verbList[1:]:
                    if verb in verbDic.keys():
                        verb = verbDic[verb]
                    normPhrase += ' ' + verb
                if (normPhrase in dicNum.keys()):
                    dicNum[normPhrase] += tempc[phrase]
                else:
                    dicNum[normPhrase] = tempc[phrase]
    else:
        phrases = tempc.keys()
        for phrase in phrases:
            if (',' not in phrase):
                dicNum[phrase] = tempc[phrase]
                totalNum += tempc[phrase]
    dicNum = sorted(dicNum.items(), key=lambda k: k[0])
    dicNum = sorted(dicNum, key=lambda k: k[1], reverse=True)

    print(dicNum[:n])

软件工程/软件工程.py


import datetime
from typing import Any, Callable, Dict, Optional, Tuple, Union
from uuid import uuid4

from crontab import CronTab
from loguru import logger
from tortoise import timezone

from rearq.job import JobStatus
from rearq.server.models import Job, JobResult
from rearq.utils import ms_to_datetime, timestamp_ms_now, to_ms_timestamp

class Task:
    def __init__(
        self,
        bind: bool,
        function: Callable,
        queue: str,
        rearq,
        job_retry: int,
        job_retry_after: int,
        expire: Optional[Union[float, datetime.datetime]] = None,
    ):

        self.job_retry = job_retry
        self.job_retry_after = job_retry_after
        self.queue = queue
        self.rearq = rearq
        self.function = function
        self.bind = bind
        self.expire = expire

    async def delay(
        self,
        args: Optional[Tuple[Any, ...]] = None,
        kwargs: Optional[Dict[str, Any]] = None,
        job_id: str = None,
        countdown: Union[float, datetime.timedelta] = 0,
        eta: Optional[datetime.datetime] = None,
        expire: Optional[Union[float, datetime.datetime]] = None,
        job_retry: int = 0,
        job_retry_after: int = 60,
    ) -> Job:
        """
        Add job to queue.
        :param args: Job args.
        :param kwargs: Job kwargs.
        :param job_id: Custom job id.
        :param countdown: Delay seconds to execute.
        :param eta: Delay to datetime to execute.
        :param expire: Override default expire.
        :param job_retry: Override default job retry.
        :param job_retry_after: Override default job retry after.
        :return:
        """
        if not job_id:
            job_id = uuid4().hex
        if countdown:
            defer_ts = to_ms_timestamp(countdown)
        elif eta:
            defer_ts = to_ms_timestamp(eta)
        else:
            defer_ts = timestamp_ms_now()
        expire_time = None
        expires = expire or self.expire
        if expires:
            expire_time = ms_to_datetime(to_ms_timestamp(expires))

        job = await Job.get_or_none(job_id=job_id)
        if job:
            logger.warning(f"Job {job_id} exists")
            return job

        job = Job(
            task=self.function.__name__,
            args=args,
            kwargs=kwargs,
            job_retry=job_retry or self.job_retry,
            queue=self.queue,
            job_id=job_id,
            expire_time=expire_time,
            enqueue_time=timezone.now(),
            job_retry_after=job_retry_after,
        )

        if not eta and not countdown:
            job.status = JobStatus.queued
            await job.save()
            await self.rearq.redis.xadd(self.queue, {"job_id": job_id})
        else:
            job.status = JobStatus.deferred
            await job.save()
            await self.rearq.zadd(defer_ts, f"{self.queue}:{job_id}")

        return job

async def check_pending_msgs(self: Task, queue: str, group_name: str, timeout: int):
    """
    check pending messages
    :return:
    """
    redis = self.rearq.redis
    pending_msgs = await redis.xpending(self.queue, group_name, "-", "+", 10)
    p = redis.pipeline()
    execute = False
    for msg in pending_msgs:
        msg_id, _, idle_time, times = msg
        job_result = await JobResult.filter(msg_id=msg_id).only("job_id").first()
        if not job_result:
            continue
        if int(idle_time / 1000) > timeout * 2:
            execute = True
            p.xack(queue, group_name, msg_id)
            p.xadd(queue, {"job_id": job_result.job_id})
    if execute:
        return await p.execute()

class CronTask(Task):
    _cron_tasks: Dict[str, "CronTask"] = {}
    next_run: int

    def __init__(
        self,
        bind: bool,
        function: Callable,
        queue: str,
        rearq,
        job_retry: int,
        job_retry_after: int,
        cron: str,
        expire: Optional[Union[float, datetime.datetime]] = None,
        run_at_start: Optional[bool] = False,
    ):
        super().__init__(bind, function, queue, rearq, job_retry, job_retry_after, expire)
        self.crontab = CronTab(cron)
        self.cron = cron
        self.run_at_start = run_at_start
        self.set_next()

    def set_next(self):
        self.next_run = to_ms_timestamp(self.crontab.next(default_utc=False))

    @classmethod
    def add_cron_task(cls, function: str, cron_task: "CronTask"):
        cls._cron_tasks[function] = cron_task

    @classmethod
    def get_cron_tasks(cls):
        return cls._cron_tasks


import sys
import aubio
from aubio import source, pitch, midi2note, freq2note, note2freq
from os import path
import numpy as np
import pyaudio
import wave
import queue
from time import sleep
from math import log
from threading import Thread
import kivy
kivy.require('1.11.1')
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import StringProperty, NumericProperty, BooleanProperty
from kivy.clock import Clock
from playsound import playsound

# Manager for the screens
class WindowManager(ScreenManager):
	pass

# Wrapper for the screens so that they are all similar
class ScreenWrapper(Screen):
	pass

class Comparison(ScreenWrapper, Screen):

	compare_text = StringProperty()
	scale = StringProperty()
	scale_text = StringProperty()
	is_recording = BooleanProperty()
	is_sharp = BooleanProperty()

	def __init__(self, **kwargs):
		super(Comparison, self).__init__(**kwargs)
		self.compare_text = "Comparison"
		self.scale_text = "None"
		self.scale = ""
		self.is_recording = False
		self.is_sharp = True
		self.scale_dict = {
		"A Scale": ['A', 'B', 'C#', 'D', 'E', 'F#', 'G#', 'A', 'G#', 'F#', 'E', 'D', 'C#', 'B', 'A'],
		"A# Scale": ['A#', 'C', 'D', 'D#', 'F', 'G', 'A', 'A#', 'A' 'G', 'F', 'D#', 'D', 'C', 'A#'],
		"B Scale": ['B', 'C#', 'D#', 'E', 'F#', 'G#', 'A#', 'B', 'A#', 'G#', 'F#', 'E', 'D#', 'C#', 'B'],
		"C Scale": ['C', 'D', 'E', 'F', 'G', 'A', 'B', 'C', 'B', 'A', 'G', 'F', 'E', 'D', 'C'],
		"C# Scale": ['C#', 'D#', 'F', 'F#', 'G#', 'A#', 'C' 'C#', 'C', 'A#', 'G#', 'F#', 'F', 'D#', 'C#'],
		"D Scale": ['D', 'E', 'F#', 'G', 'A', 'B', 'C#', 'D', 'C#', 'B', 'A', 'G', 'F#', 'E', 'D'],
		"D# Scale": ['D#', 'F', 'G', 'G#', 'A#', 'C', 'D', 'D#', 'D', 'C', 'A#', 'G#', 'G', 'F', 'D#'],
		"E Scale": ['E', 'F#', 'G#', 'A', 'B', 'C#', 'D#', 'E', 'D#', 'C#', 'B', 'A', 'G#', 'F#', 'E'],
		"F Scale": ['F', 'G', 'A', 'A#', 'C', 'D', 'E', 'F', 'E', 'D', 'C', 'A#', 'A', 'G', 'F'],
		"F# Scale": ['F#', 'G#', 'A#', 'B', 'C#', 'D#', 'F', 'F#', 'F', 'D#', 'C#', 'B', 'A#', 'G#', 'F#'],
		"G Scale": ['G', 'A', 'B', 'C', 'D', 'E', 'F#', 'G', 'F#', 'E', 'D', 'C', 'B', 'A', 'G'],
		"G# Scale": ['G#', 'A#', 'C', 'C#', 'D#', 'F', 'G', 'G#', 'G', 'F', 'D#', 'C#',  'C', 'A#', 'G#'],
		"A Scale": ['A', 'B', 'C#', 'D', 'E', 'F#', 'G#', 'A', 'G#', 'F#', 'E', 'D', 'C#', 'B', 'A'],
		}

	# Compares pitches of 2 files using the get pitch method
	def compare_pitch(self, file1, file2):
		file1_pitch = self.a.get_pitch(file1)
		file2_pitch = self.a.get_pitch(file2)

		if file1_pitch == file2_pitch:
			self.compare_text = "You are correct"
			print("\nYou are correct.")
		else:
			self.compare_text = "You are incorrect"
			print("\nYou are incorrect.")

	def record_scale(self, state):
		if self.scale == "":
			self.scale_text = "Select a Scale"
		else:
			self.state = state
			if self.state == 'down':
				self.is_recording = True
				self.q = queue.Queue()
				self.t = Thread(target=Comparison.record_compare, args=(self,))
				self.t.daemon = True
				self.t.start()
			else:
				self.is_recording = False

	def record_compare(self):
		self.gate = True
		while self.state == 'down':
			if self.gate == True:
				Analysis.record_init(self, self.state)
				self.gate = False
		Analysis.get_pitch_init(self, 'output.wav')
		self.notes = self.q.get()

		if self.notes == self.scale_dict[self.scale]:
			playsound('music/victory.wav')
		else:
			print('FUCK NOOOOOOOOOOOO')

	def on_leave(self):
		self.is_recording = False

class Analysis(ScreenWrapper, Screen):

	pitch_text = StringProperty()
	is_recording = BooleanProperty()

	def __init__(self, **kwargs):
		super(Analysis, self).__init__(**kwargs)
		self.pitch_text	= "Analysis"
		self.is_recording = False

	def get_pitch_init(self, filename):
		self.filename = filename
		self.t = Thread(target=Analysis.get_pitch, args=(self,))
		self.t.daemon = True
		self.t.start()

	# Gets the musical notes from a file
	def get_pitch(self):
		if path.exists(self.filename) == False:
			raise Exception(f"File Path to {self.filename} does not exist")

		else:
			downsample = 1
			samplerate = 44100 // downsample
			if len( sys.argv ) > 2: samplerate = int(sys.argv[2])

			win_s = 4096 // downsample # fft size
			hop_s = 512  // downsample # hop size

			s = source(self.filename, samplerate, hop_s)
			samplerate = s.samplerate

			tolerance = 0.8

			pitch_o = pitch("yin", win_s, hop_s, samplerate)
			pitch_o.set_unit("midi")
			pitch_o.set_tolerance(tolerance)

			pitches = []
			confidences = []

			# Total number of frames read
			total_frames = 0
			while True:
			    samples, read = s()
			    pitch_midi = pitch_o(samples)[0]
			    pitch_midi = int(round(pitch_midi))
			    confidence = pitch_o.get_confidence()
			    if confidence < 0.9: pitch_midi = 0.
			    #print("%f %f %f" % (total_frames / float(samplerate), pitch, confidence))
			    if len(pitches) == 0 and pitch_midi != 0:
			    	pitches.append(pitch_midi)
			    elif len(pitches) > 0:
			    	if pitch_midi != pitches[-1] and pitch_midi != 0:
			    		pitches.append(pitch_midi)
			    else:
			    	pass

			    #print(pitches)
			    confidences += [confidence]
			    total_frames += read
			    if read < hop_s: break

			if 0: sys.exit(0)
			notes = []
			for midi in pitches:
				note = midi2note(midi)
				notes.append(note.strip("0123456789"))

			print(notes)
			self.pitch_text = str(notes)
			self.q.put(notes)
			raise Exception("Thread Terminated")

	# Starts the thread to record from mic
	def record_init(self, state):
		self.state = state
		if self.state == 'down': # Checks if the button is in a pressed state
			self.is_recording = True
			self.t = Thread(target=Analysis.record, args=(self, self.state))
			self.t.daemon = True
			self.t.start()
		else:
			self.is_recording = False

	# Records input from the default mic
	def record(self, state, chunk=1024, wavformat=pyaudio.paInt16, channels=1, rate=44100, wave_output_filename="output.wav"):
		self.state = state

		p = pyaudio.PyAudio()

		stream = p.open(format=wavformat,
						channels=channels,
						rate=rate,
						input=True,
						frames_per_buffer=chunk)

		print("Recording...")

		frames = []

		while self.state == 'down': # Reads data while button is pressed
				data = stream.read(chunk)
				frames.append(data)

		print("Done Recording")

		stream.close()
		p.terminate()

		wf = wave.open(wave_output_filename, 'wb')
		wf.setnchannels(channels)
		wf.setsampwidth(p.get_sample_size(wavformat))
		wf.setframerate(rate)
		wf.writeframes(b''.join(frames))
		wf.close()
		raise Exception("Thread Terminated")

	def on_leave(self):
		self.state = 'up'

class Tuner(ScreenWrapper, Screen):

	note_text = StringProperty()
	cent_text = StringProperty()
	posy = NumericProperty()
	color_red = NumericProperty()
	color_green = NumericProperty()
	color_blue = NumericProperty()

	def __init__(self, **kwargs):
		super(Tuner, self).__init__(**kwargs)
		self.note_text = " "
		self.cent_text = " "
		self.posy = .65
		self.color_red = 0
		self.color_green = 0
		self.color_blue = 0

	# Starts the thread to tune from the mic when the screen is entered
	def on_enter(self):
		print("Tuning..")
		self.t = Thread(target=Tuner.tune, args=(self,))
		self.is_running = True
		self.t.daemon = True
		self.t.start()

	# Closes thread on leave
	def on_leave(self):
		self.is_running = False
		print("Done Tuning")

	# Tunes from the mic
	def tune(self):
		pDetection = aubio.pitch("default", 2048, 1024, 44100)
		pDetection.set_unit('Hz')
		pDetection.set_silence(-40)

		p = pyaudio.PyAudio()

		stream = p.open(format=pyaudio.paFloat32,
    					channels=1,
    					rate=44100,
    					input=True,
    					frames_per_buffer=1024)

		while self.is_running == True:

			data = stream.read(1024)

			samples = np.frombuffer(data, dtype=aubio.float_type)
			pitch = pDetection(samples)[0]

			if pitch != 0:
				pitch_cent = round(1200 * log(pitch / note2freq(freq2note(pitch)), 2), 2)
				self.note_text = freq2note(pitch)
				self.cent_text = str(pitch_cent)
				if pitch_cent < 0:
					self.posy = .45
				else:
					self.posy = .65
				self.color_red = round((abs(pitch_cent) * .051), 3)
				self.color_green = round(((abs(pitch_cent) * -.051) + 2.55), 3)
				print(f"Green: {self.color_green} Red: {self.color_red}")
			#print(freq2note(pitch))

		raise Exception("Thread Terminated") # Terminates the thread

class Metronome(ScreenWrapper, Screen):

	met_text = StringProperty()
	format_text = StringProperty()
	met_format = NumericProperty()

	def __init__(self, **kwargs):
		super(Metronome, self).__init__(**kwargs)
		self.met_text = "Metronome OFF"
		self.format_text = 'None'
		self.met_format = 4
		self.clock = None

	# Schedules the met to be played
	def met(self, state, bpm):
		self.state = state
		self.bpm = bpm
		if self.state == 'down':
			if self.bpm.isdigit() == False :
				self.met_text = "Input was not a natural number"
			else:
				self.bpm = int(self.bpm)
				if self.bpm < 1:
					self.met_text = "Input was not a natural number"
				else:
					self.bpm = 60/self.bpm
					self.met_text = "Metronome ON"
					self.t = Thread(target=Metronome.playmet, args=(self, self.bpm))
					self.is_running = True
					self.t.daemon = True
					self.t.start()

		# Kills the thread running the Metronome
		else:
			self.met_text = "Metronome OFF"
			self.is_running = False

	# Plays the metronome sound
	def playmet(self, bpm):
		counter = 0
		while self.is_running == True:
			if self.format_text == '2/4':
				if counter == 0 or counter%2 == 0:
					playsound('music/highmet.wav')
				else:
					playsound('music/lowmet.wav')
				sleep(bpm)
			elif self.format_text == '3/4':
				if counter == 0 or counter%3 == 0:
					playsound('music/highmet.wav')
				else:
					playsound('music/lowmet.wav')
				sleep(bpm)
			elif self.format_text == '4/4':
				if counter == 0 or counter%4 == 0:
					playsound('music/highmet.wav')
				else:
					playsound('music/lowmet.wav')
				sleep(bpm)
			elif self.format_text == '6/8':
				if counter == 0 or counter%6 == 0:
					playsound('music/highmet.wav')
				elif counter%3 == 0:
					playsound('music/met.wav')
				else:
					playsound('music/lowmet.wav')
				sleep(bpm/3)
			else:
				pass

			counter += 1
		raise Exception("Thread Terminated")

class BandApp(App):

	def build(self):
		pass

if __name__ == '__main__':
	BandApp().run()


__author__ = ["jwely"]
__all__ = ["extract_TRMM_NetCDF"]

# dnppy imports
from dnppy import core

# arcpy imports
import arcpy
arcpy.env.overwriteOutput = True

def extract_TRMM_NetCDF(filelist, outdir):

    """
     Function converts NetCDFs to tiffs. Designed to work with TRMM data downloaded
     from GLOVIS

     inputs:
       filelist    list of '.nc' files to convert to tiffs.
       outdir      directory to which tif files should be saved

    returns an output filelist of local filepaths of extracted data.
    """

    # Set up initial parameters.
    arcpy.env.workspace = outdir
    filelist = core.enf_list(filelist)
    output_filelist = []

    # convert every file in the list "filelist"
    for infile in filelist:

        # use arcpy module to make raster layer from netcdf
        arcpy.MakeNetCDFRasterLayer_md(infile, "r", "longitude", "latitude", "r", "", "", "BY_VALUE")
        outname = core.create_outname(outdir, infile, "e", "tif")
        arcpy.CopyRaster_management("r", outname, "", "", "", "NONE", "NONE", "")
        output_filelist.append(outname)
        print('Converted netCDF file ' + outname + ' to Raster')

    return output_filelist

if __name__ == "__main__":
    afile = ""
    outdir = ""
    extract_TRMM_NetCDF(afile, outdir)


import sys

def is_unique(x, l):
    return l.count(x) == 1

def lowest_unique(l):
    m = 9
    mi = 0
    for i in range(len(l)):
        if is_unique(l[i], l) and l[i] < m:
            m = l[i]
            mi = i + 1

    return mi

if len(sys.argv) <= 1:
    exit(0)

test_cases = open(sys.argv[1], 'r')
l = []
for test in test_cases:
    test = test.strip("\n")
    test = test.strip(" ")
    if test == "":
        continue

    l.append(test)

test_cases.close()

for s in l:
    arg = []
    for i in s.split(" "):
        arg.append(int(i))
    print(lowest_unique(arg))


from setuptools import setup, find_packages
from os.path import join

version = '4.0.dev0'

tests_require=[
      'cssselect',
      'lxml',
      'mock',
      'plone.api >=1.8.5',
      'plone.app.robotframework',
      'plone.app.testing [robot]',
      'plone.browserlayer',
      'plone.cachepurging',
      'plone.testing',
      'robotsuite',
      'testfixtures',
      'transaction',
      'tzlocal',
]

setup(name='Products.Maps',
      version=version,
      description="A simple, easy to use Plone integration with Google Maps",
      long_description=open("README.rst").read() + '\n' +
                       open(join('docs','HISTORY.rst')).read(),
      classifiers=[
        "Framework :: Zope2",
        "Programming Language :: Python",
        "Programming Language :: Python :: 2.7",
        "Programming Language :: Python :: 3.7",
        "Topic :: Software Development :: Libraries :: Python Modules",
        "Framework :: Plone",
        "Framework :: Plone :: 5.0",
        "Framework :: Plone :: 5.1",
        "Framework :: Plone :: 5.2",
        "License :: OSI Approved :: GNU General Public License (GPL)",
      ],
      keywords='Google Maps Zope Plone',
      author='Florian Schulze',
      author_email='fschulze@jarn.com',
      maintainer='Luca Fabbri',
      maintainer_email='luca@keul.it',
      url='http://plone.org/products/maps',
      license='GPL',
      packages=find_packages(exclude=['ez_setup']),
      namespace_packages=['Products'],
      include_package_data=True,
      zip_safe=False,
      tests_require=tests_require,
      extras_require=dict(test=tests_require),
      install_requires=[
          'setuptools',
          'six',
          'plone.formwidget.geolocation',
      ],
)


#-*- coding: utf-8

from ihna.kozhukhov.core import ProcessedData
from MapTable import MapTable
from FilteredMapTable import FilteredMapTable
from Hist1DDataManager import Hist1DDataManager

import numpy as np
import matplotlib.pyplot as plt

class Hist1D(ProcessedData):
	'''
	prints a one-dimensional histogram
	'''

	def getName(self):
		'''
		Returns a histogram
		'''
		return "hist"

	def setSource(self, value):
		'''
		Sets a source
		'''
		if isinstance(value, MapTable):
			super(Hist1D, self).setSource(value)
		else:
			raise ValueError("{0} is not a valid source for the object".format(value.__class__.__name__))

	def __str__(self):
		S = super(Hist1D, self).__str__()+"\n"
		try:
			S += "Binning value: {0}\n".format(self.getBinningValue())
			S += "Binning edges: "
			for x in self.getBinEdges():
				S += "{0:.2f}\t".format(x)
		except AttributeError as err:
			S += "\033[31m{0}\033[0m".format(err)
		return S

	__binningValue = None

	def getBinningValue(self):
		'''
		Returns a histogram value
		'''
		if self.__binningValue is None:
			raise AttributeError("Please, specify a binning value by setBinningValue")
		return self.__binningValue

	def setBinningValue(self, value):
		'''
		Sets a binning value
		'''
		if not isinstance(self.getSource(), Hist1DDataManager) and not self.getSource() is None:
			idx = self.getSource().getColumns().index(value)
		self.__binningValue = value

	def isCircular(self):
		'''
		Returns True if the binning value is circular
		'''
		return self.getBinningValue().find("orientation")!=-1

	__binEdges = None

	def getBinEdges(self):
		'''
		Returns bin centers
		'''
		if self.__binEdges is None:
			raise AttributeError("Please, specify bin edges by setBinEdges or \
bin size by setBinRange or by setBinNumber")
		return self.__binEdges

	def setBinEdges(self, value):
		'''
		Sets bin centers
		'''
		if isinstance(value, np.ndarray):
			self.__binEdges = value
		else:
			raise ValueError("Please, specify bin edges")

	def setBinNumber(self, N):
		'''
		Sets bin number (for circular values only)
		'''
		if not self.isCircular():
			raise ValueError("The function is applicable for circular binning data only")
		binSize = np.pi/int(N)
		leftBorder = -np.pi/2-binSize/2
		rightBorder = np.pi/2+binSize/2
		edges = np.arange(leftBorder, rightBorder+1e-10, binSize)
		self.setBinEdges(edges)

	def setBinSize(self, left, size, right):
		'''
		Sets the bin size (for linear data only)

		left - left border of the data
		right - right border of the data
		size - the bin size
		'''
		if self.isCircular():
			raise ValueError("The function is applicable for linear data only")
		edges = np.arange(left, right+1e-10, size)
		self.setBinEdges(edges)

	def getBinCenters(self):
		'''
		Returns bin centers
		'''
		edges = self.getBinEdges()
		return 0.5*(edges[:-1]+edges[1:])

	__columns = None

	def getColumns(self):
		'''
		Returns a list of all columns
		'''
		if self.__columns is None:
			raise ValueError("The data was not processed")
		return self.__columns

	__counts = None

	def getCounts(self):
		'''
		Returns counts
		'''
		if not self.isDataProcessed():
			raise ValueError("The data was not processed")
		return self.__counts

	def getProportions(self):
		'''
		Returns proportions
		'''
		counts = self.getCounts()
		return counts/counts.sum()

	def getPercentages(self):
		'''
		Returns percentages
		'''
		return self.getProportions()*100

	__values = None
	__meanValues = None
	__stdValues = None
	__sterrValues = None

	def getValues(self, colname, centerIdx):
		'''
		get column values for a certain column name and a certain center index
		'''
		if not self.isDataProcessed():
			raise ValueError("Data was not processed")
		return self.__values[colname][centerIdx]

	def getMeanValues(self, colname=None):
		'''
		get mean values for the column
		'''
		if colname is None:
			return self.__meanValues
		if not self.isDataProcessed():
			raise ValueError("Data was not processed")
		col = self.getColumns().index(colname)
		return self.__meanValues[:,col]

	def getStdValues(self, colname=None):
		'''
		get mean values for the column
		'''
		if colname is None:
			return self.__stdValues
		if not self.isDataProcessed():
			raise ValueError("Data was not processed")
		col = self.getColumns().index(colname)
		return self.__stdValues[:,col]

	def getSterrValues(self, colname=None):
		'''
		get mean values for the column
		'''
		if colname is None:
			return self.__sterrValues
		if not self.isDataProcessed():
			raise ValueError("Data was not processed")
		col = self.getColumns().index(colname)
		return self.__sterrValues[:,col]

	def process(self):
		'''
		Processes the data
		'''
		centers = self.getBinCenters()
		self.__columns = self.getSource().getColumns()
		L = len(self.__columns)
		self.__counts = np.zeros(centers.size)
		self.__values = dict()
		self.__meanValues = np.zeros((centers.size, L))
		self.__stdValues = np.zeros((centers.size, L))
		self.__sterrValues = np.zeros((centers.size, L))
		for i in range(centers.size):
			leftBorder = self.getBinEdges()[i]
			rightBorder = self.getBinEdges()[i+1]
			hdata = FilteredMapTable.createFromData(self.getSource())
			hdata.setFiltrationValue(self.getBinningValue())
			hdata.setRange((leftBorder, rightBorder))
			hdata.process()
			self.__counts[i] = hdata.getRows()
			for col in self.__columns:
				iCol = self.__columns.index(col)
				if not self.__values.has_key(col):
					self.__values[col] = list()
				self.__values[col].append(hdata.getTable().copy()[:,iCol])
				self.__meanValues[i][iCol] = hdata.getAverage(col)
				self.__stdValues[i][iCol] = hdata.getStd(col)
				self.__sterrValues[i][iCol] = hdata.getStErr(col)
		self._setDataProcessed(True)

	def getMeanValuesTxt(self):
		'''
		Returns mean values as a text
		'''
		return self._getValuesTxt(self.__meanValues)

	def getStdValuesTxt(self):
		'''
		Returns standard deviations as a text
		'''
		return self._getValuesTxt(self.__stdValues)

	def getSterrValuesTxt(self):
		'''
		Return standard errors as a text
		'''
		return self._getValuesTxt(self.__sterrValues)

	def _getValuesTxt(self, matrix):
		S = "\t"
		for col in self.getColumns():
			S += "{0}\t".format(col)
		S += "\n\t"
		for col in self.getColumns():
			S += "=====\t"
		S += "\n"
		centers = self.getBinCenters()
		edges = self.getBinEdges()
		for i in range(centers.size):
			S += "{0}<=val<={1}\t".format(edges[i], edges[i+1])
			for j in range(len(self.getColumns())):
				S += "{0:.2f}\t".format(matrix[i,j])
			S += "\n"
		return S

	def getParameters(self):
		d = dict(value = self.getBinningValue())
		for i in range(self.getBinEdges().size):
			d["edge_{0}".format(i)] = str(self.getBinEdges()[i])
		return d

	def setParameters(self, d):
		self.setBinningValue(d['value'])
		edges = np.zeros(len(d)-1)
		for key, value in d.iteritems():
			if key.startswith("edge_"):
				idx = int(key[5:])
				edges[idx] = float(value)
		self.setBinEdges(edges)

	def getDataManagerClass(self):
		'''
		Returns a data manager class
		'''
		return Hist1DDataManager

	def write(self):
		self.getDataManager().write(self)

	def _readString(self, X):
		y =  X.tostring().replace('\x00', '')
		return y

	def read(self):
		d = self.getDataManager().read()
		self._setSpecimen(self._readString(d['cat']))
		self.getDataManager()._setSpecimen(self._readString(d['cat']))
		self._setExperiment(self._readString(d['experiment']))
		self.getDataManager()._setExperiment(self._readString(d['experiment']))
		self._setCondition(self._readString(d['condition']))
		self.getDataManager()._setCondition(self._readString(d['condition']))
		self.setBinEdges( d['bin_edges'][0] )
		self.setBinningValue( self._readString(d['binning_value']) )
		self.__columns = []
		self.__values = dict()
		for colname in d['columns'][0]:
			col = self._readString(colname)
			self.__columns.append(col)
			mcol = col.replace('-','_')
			cnt = d[mcol][0]
			self.__values[col] = list()
			for k in range(len(self.getBinCenters())):
				coldata = np.array(cnt[k][0])
				self.__values[col].append(coldata)
		self.__meanValues = d['mean_values']
		self.__stdValues = d['std_values']
		self.__sterrValues = d['sterr_values']
		self.__counts = d['counts']

	def plot(self, colname = None, ax = None):
		if ax is None:
			ax = plt.axes()
		centers = self.getBinCenters()
		bsize = self.getBinEdges()[1:] - self.getBinEdges()[:-1]
		if self.getBinningValue().find('orientation')!=-1:
			centers = centers*180/np.pi
			bsize = bsize*180/np.pi
		if colname is None:
			val = self.getPercentages()
			plt.ylabel('% of pixels')
		else:
			if colname.find('orientation')==-1 or colname=="orientation":
				val = self.getMeanValues(colname)
				if colname=="orientation":
					val = val*180/np.pi
			else:
				val = self.getStdValues(colname)*180/np.pi
			plt.ylabel(colname)
		h = ax.bar(centers, val, 0.9*bsize)
		plt.xlabel(self.getBinningValue())
		plt.title(self.getFullname())
		return h

	def plotGraph(self, colname, ax = None):
		if ax is None:
			ax = plt.axes()
		centers = self.getBinCenters()
		if self.getBinningValue().find('orientation')!=-1:
			centers = centers*180/np.pi
		if colname.find('orientation')==-1 or colname=="orientation":
			means = self.getMeanValues(colname)
			errors = self.getSterrValues(colname)
			h = ax.errorbar(centers, means, yerr=errors)
		else:
			std = self.getStdValues(colname)*180/np.pi
			h = ax.plot(centers, std)
		plt.xlabel(self.getBinningValue())
		plt.ylabel(colname)
		plt.title(self.getFullname())
		return h


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Wed Mar 13 00:08:25 2019

@author: etekken
"""

import os, h5py
from PyQt5 import QtCore, QtGui, QtWidgets
from postProcessWidget_ui import Ui_PostProcessWidget
from PlotTypeOneWidget import PlotTypeOneWidget
from PlotTypeTwoWidget import PlotTypeTwoWidget
from PlotTypeThreeWidget import PlotTypeThreeWidget
from CurveFormatDialog import CurveFormatDialog
import pyqtgraph as pg
import numpy as np
from utils import set_plot, show_message, check_two_equals, PLOT_ARGUMENTS,\
                  INSTALL_PATH, RUNS_PATH, DEFAULT_PLOTS, CURVE_LINE_FORMATS,\
                  CURVE_COLORS, dir_size
from exception_handling import handle_exception

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

NTYPE_PLOTS = 6

class postProcessWidget(QtWidgets.QWidget):
    def __init__(self, current_configuration, current_objects):
        QtWidgets.QWidget.__init__(self)
        self.ui_ppw = Ui_PostProcessWidget()
        self.ui_ppw.setupUi(self)
        self.current_objects = current_objects
        self.change_attributes(current_configuration, current_objects)
        self.current_run_dir = os.path.join(RUNS_PATH,self.current_configuration['folder_name'])
        self.apw = None
        self.tpw = None
        self.rpw = None
        self.cpw = None
        self.spw = None
        self.fpw = None
        self.plot_widgets   = []
        self.colours        = ['r', 'b', 'k', 'g', 'y', 'c','m']
        self.plots          = {}
        self.legends        = {}
        self.colour_plots   = {}
        self.open_archives  = {}
        self.run_attributes = {}
        self.run_attributes['rpms_folder_sizes'] = {}
        self.curve_attributes  = {}
        self.current_selected_curve = None
        self.ui_ppw.tabWidget_plots.setEnabled(False)
        self.current_attributes_changed = False
        self.default_postProcess_done = False
        return

    def change_attributes(self, current_configuration, current_objects):
        self.current_configuration = current_configuration
        self.current_run_dir = os.path.join(RUNS_PATH,self.current_configuration['folder_name'])
        self.current_objects = current_objects
        self.current_attributes_changed = True
        return

    def enable_ppw(self):
        # Primera vez, se verifica que todos los plots sean None
        if not self.plot_widgets:
            if os.path.isdir(self.current_run_dir):
                try:
                    (run_attributes,irpm_missing) = self.load_current_attributes()
                    self.run_attributes = run_attributes
                    # Si no hay ninguna RPM calculada, no vale la pena activar
                    if self.run_attributes['rpms']!=[]:
                        if irpm_missing:
                            msg = 'Cannot find the folders of the RPM(s) '
                            for irpm in irpm_missing:
                                msg = msg + str(irpm) + ' - '
                            msg = msg[0:-2]
                            show_message(msg,1)
                        self.set_plot_widgets()
                        self.ui_ppw.tabWidget_plots.setEnabled(True)
                    self.default_postProcess_done = False
                except:
                    show_message('Error in setting the PostProcess Tab')
                    return False
            else:
                return False
        else:
            if not os.path.isdir(self.current_run_dir):
                return False
            (run_attributes,irpm_missing) = self.load_current_attributes()
            if self.run_attributes != run_attributes or\
            self.run_attributes['rpms_folder_sizes'] != run_attributes['rpms_folder_sizes'] or\
            self.current_attributes_changed:
                self.run_attributes = run_attributes
                self.run_attributes['rpms_folder_sizes'] = run_attributes['rpms_folder_sizes']
                # If the run attributes or the current objects changed, it is possible
                # that also the open archives.. maybe an incomplete rpm is now complete
                self.open_archives = {}
                for ipw in self.plot_widgets:
                    ipw.change_attributes(run_attributes, self.current_objects)
                self.current_attributes_changed = False
        return True

    def load_current_attributes(self):
        # Attributes for getMasses of GeneralAttributes
        for icylinder in self.current_objects['Cylinders']:
            try:
                angleClose  = np.rad2deg(icylinder.object['intake_valves'][0]['angle_VC'])
                Q_fuel      = icylinder.object['fuel']['Q_fuel']
            except:
                angleClose  = 220.0
                Q_fuel      = 44300000.0
            icylinder.object['angleClose']  = angleClose
            icylinder.object['Q_fuel']      = Q_fuel

        # Attributes for PlotWidgets
        irpm_missing = []
        run_attributes = {}
        run_attributes['rpms']              = []
        run_attributes['final_times']       = []
        run_attributes['rpms_folder_sizes'] = {}

        calculated_rpms = [int(f.replace('RPM_','')) for f in os.listdir(self.current_run_dir) if 'RPM_' in f]

        # First, include the calculated ones
        for irpm in calculated_rpms:
            # This ones are not be changed by current simulation
            if irpm not in self.current_configuration['rpms']:
                self.current_configuration['rpms'].append(irpm)
        # Of the "set" one, check the ones that are not calculated
        for irpm in self.current_configuration['rpms']:
            rpm_folder = os.path.join(self.current_run_dir,"RPM_%s"%irpm)
            if not os.path.isdir(rpm_folder):
                irpm_missing.append(irpm)
                continue
            current_dir_size = dir_size(rpm_folder)
            # check if the size of the calculated ones changed, so run_attributes must change
            if not irpm in self.run_attributes['rpms_folder_sizes'].keys():
                run_attributes['rpms_folder_sizes'][irpm] = current_dir_size
            else:
                old_dir_size = self.run_attributes['rpms_folder_sizes'][irpm]
                run_attributes['rpms_folder_sizes'][irpm] = current_dir_size if \
                current_dir_size > old_dir_size else old_dir_size

            run_attributes['rpms'].append(irpm)

        # Order the rpms, because maybe the user simulates 1000-3000 and then 4000
        # If the list is not ordered, we can get [4000,1000,2000,3000]
        list.sort(run_attributes['rpms'])

        for irpm in run_attributes['rpms']:
            final_time = (60.0/irpm)*self.current_configuration['ncycles']*(self.current_configuration['nstroke'])/2.0
            run_attributes['final_times'].append(final_time)

        run_attributes['nstroke'] = self.current_configuration['nstroke']
        run_attributes['ncycles'] = self.current_configuration['ncycles']
        return (run_attributes,irpm_missing)

    def set_plot_widgets(self):
        if not self.apw:
            self.apw = PlotTypeOneWidget(self.plot, self.current_run_dir, self.run_attributes, \
                                         self.current_objects, 0, self.get_open_archives, self.set_open_archives)
            self.ui_ppw.widget_angle_layout.addWidget(self.apw)
            self.apw.setAutoFillBackground(True)
            self.plot_widgets.append(self.apw)
        if not self.tpw:
            self.tpw = PlotTypeOneWidget(self.plot, self.current_run_dir, self.run_attributes, \
                                         self.current_objects, 1, self.get_open_archives, self.set_open_archives)
            self.ui_ppw.widget_time_layout.addWidget(self.tpw)
            self.tpw.setAutoFillBackground(True)
            self.plot_widgets.append(self.tpw)
        if not self.rpw:
            self.rpw = PlotTypeOneWidget(self.plot, self.current_run_dir, self.run_attributes, \
                                         self.current_objects, 2, self.get_open_archives, self.set_open_archives)
            self.ui_ppw.widget_rpms_layout.addWidget(self.rpw)
            self.rpw.setAutoFillBackground(True)
            self.plot_widgets.append(self.rpw)
        if not self.cpw:
            self.cpw = PlotTypeOneWidget(self.plot, self.current_run_dir, self.run_attributes, \
                                         self.current_objects, 3, self.get_open_archives, self.set_open_archives)
            self.ui_ppw.widget_cycles_layout.addWidget(self.cpw)
            self.cpw.setAutoFillBackground(True)
            self.plot_widgets.append(self.cpw)
        if not self.spw:
            self.spw = PlotTypeTwoWidget(self.plot, self.current_run_dir, self.run_attributes, \
                                         self.current_objects, 4, self.get_open_archives, self.set_open_archives)
            self.ui_ppw.widget_space_layout.addWidget(self.spw)
            self.spw.setAutoFillBackground(True)
            self.plot_widgets.append(self.spw)
        if not self.fpw:
            self.fpw = PlotTypeThreeWidget(self.plot, self.current_run_dir, self.run_attributes, \
                                         self.current_objects, 5, self.get_open_archives, self.set_open_archives)
            self.ui_ppw.widget_free_layout.addWidget(self.fpw)
            self.fpw.setAutoFillBackground(True)
            self.plot_widgets.append(self.fpw)

        for ip in range(0,NTYPE_PLOTS):
            self.plots[ip]           = []
            self.legends[ip]         = []
            self.colour_plots[ip]    = []
        return True

    def advance_colour(self, current_plot, current_color_dict):
        current_color = current_color_dict[current_plot]
        index = self.colours.index(current_color)
        index = index+1 if index<len(self.colours)-1 else -1
        current_color_dict[current_plot] = self.colours[index]
        return

    def get_open_archives(self):
        return self.open_archives

    def set_open_archives(self,archive,data):
        self.open_archives[archive] = data
        return

    def choose_widgets(self, plot_type):
        if plot_type==0:
            tabWidget   = self.ui_ppw.tabWidget_figures_angles
            plotWidget  = self.apw
        elif plot_type==1:
            tabWidget   = self.ui_ppw.tabWidget_figures_time
            plotWidget  = self.tpw
        elif plot_type==2:
            tabWidget   = self.ui_ppw.tabWidget_figures_rpms
            plotWidget  = self.rpw
        elif plot_type==3:
            tabWidget   = self.ui_ppw.tabWidget_figures_cycles
            plotWidget  = self.cpw
        elif plot_type==4:
            tabWidget   = self.ui_ppw.tabWidget_figures_space
            plotWidget  = self.spw
        elif plot_type==5:
            tabWidget   = self.ui_ppw.tabWidget_figures_free
            plotWidget  = self.fpw
        return (tabWidget,plotWidget)

    def remove_figure(self, remove_plot, plot_type):
        try:
            (tabWidget,plotWidget) = self.choose_widgets(plot_type)
            for index,iplot in enumerate(self.plots[plot_type]):
                if remove_plot == iplot:
                    self.plots[plot_type].remove(iplot)
                    self.colour_plots[plot_type].pop(index)
                    self.legends[plot_type].pop(index)
                    tabWidget.removeTab(index)
                    del iplot
                    break

            # acomodar numeracion de tabWidgets que quedan y eliminar del combobox de figuras
            for indextab in range(index,tabWidget.count()):
                tabWidget.setTabText(indextab, 'Figure '+str(int(tabWidget.tabText(indextab)[-1])-1))
            plotWidget.ui.figure_number.removeItem(plotWidget.ui.figure_number.count()-1)
        except:
            show_message('An error has occurred. Cannot delete this figure')
        return

    def plot(self, current_data, title, legend_texts, xlabel, ylabel, xunits, yunits, figure_number, plot_type):

        # no permitir dos leyendas iguales en un misma plot, puesto que luego para borrar
        # una curva pyqtgraph usa el nombre
        try:
            legends_to_check = legend_texts
            if figure_number>=0:
                for item in self.legends[plot_type][figure_number].items:
                    legends_to_check.append(item[1].text)
            two_equals = check_two_equals(legend_texts)
            assert(not two_equals)
            from exception_handling import CURRENT_EXCEPTION
            assert(not CURRENT_EXCEPTION)
        except:
            handle_exception('There are two legends with the same name. Please, select another legend name for this selections')
            return

        pg.setConfigOptions(background='w')
        pg.setConfigOptions(foreground='k')
        added = False
        (tabWidget,plotWidget) = self.choose_widgets(plot_type)

        for index,idata in enumerate(current_data):

            xdata = []
            ydata = []

            for iidata in idata:
                xdata.append(iidata[0])
                ydata.append(iidata[1])

            if figure_number==-1 and not added:
                new_plot = pg.PlotWidget()
                set_plot(new_plot, xlabel, ylabel, title, xunits, yunits)
                new_plot.getPlotItem().getViewBox().menu.addAction("Delete Figure", lambda: self.remove_figure(new_plot,plot_type))
                new_plot.getPlotItem().getViewBox().keyPressEvent = self.key_pressed_viewbox
                tab = QtWidgets.QWidget()
                tabWidget.addTab(tab,'Figure '+str(len(self.plots[plot_type])))
                tab = tabWidget.widget(len(self.plots[plot_type]))
                self.plots[plot_type].append(new_plot)
                self.colour_plots[plot_type].append(self.colours[0])
                tab.setLayout(QtWidgets.QHBoxLayout())
                tab.layout().addWidget(new_plot)
                legend = pg.LegendItem(offset=(0,1))
                legend.setParentItem(self.plots[plot_type][-1].getPlotItem())
                self.legends[plot_type].append(legend)
                figure_number = len(self.plots[plot_type])-1
                added = True

            it = self.plots[plot_type][figure_number].plot(xdata, ydata,\
                                 pen={'color': self.colour_plots[plot_type][figure_number], 'width': 1})
            it.curve.setClickable(True)
            it.curve.sigClicked.connect(self.curve_clicked)

            self.advance_colour(len(self.plots[plot_type])-1,self.colour_plots[plot_type])
            self.legends[plot_type][figure_number].addItem(it.curve,legend_texts[index])
            self.curve_attributes[it.curve] = [legend_texts[index],plot_type,figure_number]
        return len(self.plots[plot_type])

    def key_pressed_viewbox(self, event):
        if not self.current_selected_curve:
            return
        if event.key() == QtCore.Qt.Key_Delete:
            msg = "Do you want to remove the selected curve?"
            reply = show_message(msg,4,QtWidgets.QMessageBox.Yes|QtWidgets.QMessageBox.No)
            if reply == QtWidgets.QMessageBox.Yes:
                self.remove_curve()
        elif event.key() == QtCore.Qt.Key_F:
            self.format_curve()
        return

    def curve_clicked(self, curve_item):
        """
        When a curve is clicked, mark it as selected curve (paint it in blue)
        """
        if self.current_selected_curve:
            self.current_selected_curve.setShadowPen(None)
        if self.current_selected_curve == curve_item:
            self.current_selected_curve = None
            return
        pen = {'color': 'b', 'width': 4, 'style': QtCore.Qt.SolidLine}
        curve_item.setShadowPen(pen)
        self.current_selected_curve = curve_item
        return

    def remove_curve(self):
        try:
            curve_item = self.current_selected_curve
            legend_text = self.curve_attributes[curve_item][0]
            plot_type   = self.curve_attributes[curve_item][1]
            figure_number = self.curve_attributes[curve_item][2]
            data_items = self.plots[plot_type][figure_number].listDataItems()
            data_item_to_erase = None
            for index,i_data_item in enumerate(data_items):
                if i_data_item.curve == curve_item:
                    data_item_to_erase = i_data_item
                    break
            self.plots[plot_type][figure_number].removeItem(data_item_to_erase)
            self.legends[plot_type][figure_number].removeItem(legend_text)
            del self.curve_attributes[curve_item]
            self.current_selected_curve = None
            show_message('Curve successfully erased!',1)
        except:
            show_message('An error has occurred. Cannot delete this curve')
        return

    def format_curve(self):
        curve_format_dialog = CurveFormatDialog()
        return_value = curve_format_dialog.exec_()
        if return_value:
            try:
                curve_item = self.current_selected_curve
                color = CURVE_COLORS[curve_format_dialog.ui_cfd.color.currentText()]
                line_format = CURVE_LINE_FORMATS[curve_format_dialog.ui_cfd.line_format.currentText()]
                width = curve_format_dialog.ui_cfd.width.value()
                pen = {'color': color, 'width': width, 'style': line_format}
                curve_item.setPen(pen)
                legend_text = self.curve_attributes[curve_item][0]
                plot_type   = self.curve_attributes[curve_item][1]
                figure_number = self.curve_attributes[curve_item][2]
                # When the curve style is modified, we need to have a reference to
                # the label that matches with the curve. This information is stored
                # in the dictionary curve_attributes. Pyqtgraph dont provide
                # methods to change the item, so I must erease and insert it again.
                self.legends[plot_type][figure_number].removeItem(legend_text)
                self.legends[plot_type][figure_number].addItem(curve_item,legend_text)
            except:
                show_message('Error trying to set the format of the curve')

    def save_postpro(self):
        name = QtWidgets.QFileDialog.getSaveFileName(self, 'Save Post Process As', "./", "Hierarchical Data Format Files (*.hdf)")
        filename = name[ 0 ]
        filename = filename+'.hdf' if filename.find('.hdf')==-1 else filename
        try:
            with h5py.File(filename, 'w') as outfile:
                for itypeplot in range(0,NTYPE_PLOTS):
                    for iplot in range(len(self.plots[itypeplot])):
                        # cada curva del plot, en formato (x,y)
                        plot_items = self.plots[itypeplot][iplot].getPlotItem().listDataItems()
                        plot_data = None
                        legends = []
                        for index,idataitem in enumerate(plot_items):
                            data = idataitem.getData()
                            data = [ [data[0][i],data[1][i]] for i in range(len(data[0])) ]
                            data = np.array(data)
                            plot_data = np.concatenate((plot_data, data), axis=0) if plot_data is not None else data
                            legends.append( self.legends[itypeplot][iplot].items[index][1].text )
                        plot_dataset = outfile.create_dataset(PLOT_ARGUMENTS[itypeplot]['title']+' '+str(iplot), data=plot_data)
                        plot_dataset.attrs['title']     = str(self.plots[itypeplot][iplot].getPlotItem().titleLabel.text)
                        plot_dataset.attrs['xlabel']    = str(self.plots[itypeplot][iplot].getPlotItem().getAxis('bottom').labelText)
                        plot_dataset.attrs['xunits']    = str(self.plots[itypeplot][iplot].getPlotItem().getAxis('bottom').labelUnits)
                        plot_dataset.attrs['ylabel']    = str(self.plots[itypeplot][iplot].getPlotItem().getAxis('left').labelText)
                        plot_dataset.attrs['yunits']    = str(self.plots[itypeplot][iplot].getPlotItem().getAxis('left').labelUnits)
                        plot_dataset.attrs['legends']   = legends
                        plot_dataset.attrs['nplots']    = len(plot_items)
            show_message('Post Process successfully saved!',1)
        except:
            show_message('Error saving the archive %s'%filename)
        return

    def exists_plots(self):
        for itp in range(0,NTYPE_PLOTS):
            if len(self.plots[itp]):
                return True
        return False

    def load_postpro(self):
        dialog = QtWidgets.QFileDialog(self)
        dialog.setNameFilter("Hierarchical Data Format Files (*.hdf)")
        dialog.setWindowTitle('Open a Post Process File')
        dialog.setDirectory(INSTALL_PATH)
        if dialog.exec_():
            filename = dialog.selectedFiles()[0]
            if self.exists_plots():
                msg = "Do you want to preserve all the current figures?"
                reply = show_message(msg,4,QtWidgets.QMessageBox.Yes|QtWidgets.QMessageBox.No)
                if reply == QtWidgets.QMessageBox.No:
                    for itp in range(0,NTYPE_PLOTS):
                        for ip in self.plots[itp]:
                            self.remove_figure(ip,itp)
            try:
                with h5py.File(filename, 'r') as openfile:
                    for ikey in openfile.keys():
                        plot_dataset    = openfile[ikey]
                        prange          = plot_dataset.shape[0]/plot_dataset.attrs['nplots']
                        datas           = []
                        legends         = []
                        for icurve in range(plot_dataset.attrs['nplots']):
                            iplot = []
                            for ip in range(prange):
                                iplot.append( plot_dataset[ip+(icurve*prange)] )
                            datas.append(iplot)
                            legends.append( plot_dataset.attrs['legends'][icurve] )
                        title = plot_dataset.attrs['title']
                        plot_type = 0 if 'Angle' in ikey else 1 if 'Time' in ikey else 2 if \
                                        'RPM' in ikey else 3 if 'Cycle' in ikey else 4 if 'Space' in ikey else 5
                        self.plot(datas, title, legends, plot_dataset.attrs['xlabel'],\
                                  plot_dataset.attrs['ylabel'], plot_dataset.attrs['xunits'], plot_dataset.attrs['yunits'], -1, plot_type)
                        (tabWidget,plotWidget) = self.choose_widgets(plot_type)
                        plotWidget.ui.figure_number.addItem('Figure '+str(len(self.plots[plot_type])-1))
                show_message('Post Process successfully loaded!',1)
            except:
                show_message('Error opening the archive %s'%filename)
        return

    def plot_defaults(self):
        """
        When a simulation finish, this routine reads a series of default lists with
        a particular configuration (in indexs):
        plot_list = [type_of_plot,component,node,[variable],[cycles],[rpms],units,title,figure,legend]
        Then it plot it (if possible)
        In rpms or cycle the negative values implies the last calculated values (-1 last, -2 last last, etc)
        """
        if not self.enable_ppw():
            show_message('Post Process not enabled.')
            return

        if self.default_postProcess_done:
            msg = "The default Post Process has already been carried out. Do you want to do it again?"
            reply = show_message(msg,4,QtWidgets.QMessageBox.Yes|QtWidgets.QMessageBox.No)
            if reply == QtWidgets.QMessageBox.No:
                return

        advance_progressBar = 100./len(DEFAULT_PLOTS)
        success = True
        for index,iplot in enumerate(DEFAULT_PLOTS):
            (tabWidget,plotWidget) = self.choose_widgets(iplot[0])
            plot_attributes = {}
            plot_attributes['component']        = iplot[1]
            plot_attributes['node']             = iplot[2]

            elements_to_plot = []
            if iplot[3]<0: # Negative case, all the elements
                for ielement in range(plotWidget.ui.element.count()):
                    elements_to_plot.append(ielement)
            else: # Positive case, just one element
                elements_to_plot.append(iplot[3])

            plot_attributes['variable']         = iplot[4]
            plot_attributes['units']            = iplot[5]
            plot_attributes['selected_cycles']  = []
            for icycle in iplot[6]:
                plot_attributes['selected_cycles'].append(icycle if icycle>0 else self.run_attributes['ncycles'])
            plot_attributes['selected_rpms']    = []
            for irpm in iplot[7]:
                plot_attributes['selected_rpms'].append(irpm if irpm>0 else self.run_attributes['rpms'][irpm])
            if plot_attributes['selected_rpms']==[]:
                plot_attributes['selected_rpms'] = self.run_attributes['rpms']
            plot_attributes['label']            = iplot[8]
            if type(plot_attributes['variable'])!=list:
                plot_attributes['variable_index'] = plotWidget.ui.variable.findText(plot_attributes['variable'])
            else:
                plot_attributes['variable_index'] = []
                plot_attributes['variable_index'].append(plotWidget.ui.x_variable.findText(plot_attributes['variable'][0]))
                plot_attributes['variable_index'].append(plotWidget.ui.y_variable.findText(plot_attributes['variable'][1]))
            plot_attributes['title']            = iplot[9]
            plot_attributes['figure_number']    = -1 if iplot[10]<0 else len(self.plots[iplot[0]])-1
            for ielement in elements_to_plot:
                try:
                    plotWidget.current_index_element    = ielement
                    plotWidget.prepare_plot(plot_attributes)
                    plot_attributes['figure_number']    = len(self.plots[iplot[0]])-1
                    plot_attributes['label']            = '%s_%s'%(iplot[8],ielement)
                    current_progress_value = self.ui_ppw.postPro_progressBar.value()
                    self.ui_ppw.postPro_progressBar.setValue(current_progress_value + advance_progressBar)
                    QtWidgets.QApplication.processEvents()
                    from exception_handling import CURRENT_EXCEPTION
                    assert(not CURRENT_EXCEPTION)
                except:
                    success = False
                    handle_exception('Cannot plot the default configuration number %s'%index)

        if success:
            show_message('Default Post Process sucessfully created!',1)
            self.default_postProcess_done = True
        self.ui_ppw.postPro_progressBar.setValue(0)
        return


# This files contains your custom actions which can be used to run
# custom Python code.
#
# See this guide on how to implement these action:
# https://rasa.com/docs/rasa/custom-actions

# This is a simple example for a custom action which utters "Hello World!"

# from typing import Any, Text, Dict, List
#
# from rasa_sdk import Action, Tracker
# from rasa_sdk.executor import CollectingDispatcher
#
#
# class ActionHelloWorld(Action):
#
#     def name(self) -> Text:
#         return "action_hello_world"
#
#     def run(self, dispatcher: CollectingDispatcher,
#             tracker: Tracker,
#             domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
#
#         dispatcher.utter_message(text="Hello World!")
#
#         return []

from typing import Text, List, Optional, Dict, Any

from rasa_sdk import Tracker, Action
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.forms import FormValidationAction
from dotenv import load_dotenv
import os
import requests
import json
import uuid

load_dotenv()

airtable_api_key = os.getenv("AIRTABLE_API_KEY")
base_id = os.getenv("BASE_ID")
table_name = os.getenv("TABLE_NAME")

def create_health_log(confirm_exercise, exercise, sleep, diet, stress, goal):
    request_url = f"https://api.airtable.com/v0/{base_id}/{table_name}"

    headers = {
        "Content-Type": "application/json",
        "Accept": "application/json",
        "Authorization": f"Bearer {airtable_api_key}",
    }

    data = {
        "fields": {
            "Id": str(uuid.uuid4()),
            "Exercised?": confirm_exercise,
            "Type of exercise": exercise,
            "Amount of sleep": sleep,
            "Stress": stress,
            "Diet": diet,
            "Goal": goal,
        }
    }

    print(request_url)
    print(headers)
    print(json.dumps(data))

    try:
        response = requests.post(
            request_url, headers=headers, data=json.dumps(data)
        )
        response.raise_for_status()
    except requests.exceptions.HTTPError as err:
        raise SystemExit(err)

    print(f"Response status code: {response.status_code}")
    return response

class ValidateHealthForm(FormValidationAction):
    def name(self) -> Text:
        return "validate_health_form"

    async def required_slots(
            self,
            slots_mapped_in_domain: List[Text],
            dispatcher: "CollectingDispatcher",
            tracker: "Tracker",
            domain: "DomainDict",
    ) -> Optional[List[Text]]:
        print(f"confirm_exercise is {tracker.get_slot('confirm_exercise')}")
        if not tracker.get_slot("confirm_exercise"):
            slots_mapped_in_domain.remove("exercise")

        print(slots_mapped_in_domain)
        return slots_mapped_in_domain

class SubmitHealthForm(Action):

    def name(self) -> Text:
        return "submit_health_form"

    async def run(
            self, dispatcher, tracker: Tracker, domain: Dict[Text, Any],
    ) -> List[Dict[Text, Any]]:
        confirm_exercise = tracker.get_slot("confirm_exercise")
        exercise = tracker.get_slot("exercise")
        sleep = tracker.get_slot("sleep")
        stress = tracker.get_slot("stress")
        diet = tracker.get_slot("diet")
        goal = tracker.get_slot("goal")

        response = create_health_log(
            confirm_exercise, exercise, sleep, stress, diet, goal)

        dispatcher.utter_message("Thanks, your answers have been recorded!")

        return []


# coding=utf8
from django.shortcuts import render
from django.http import JsonResponse,HttpResponseRedirect
from django.conf import settings
import json
import requests
import logging
from models import *
import datetime
from django.core.cache import cache
from functools import wraps
import sys
import os
import re
import math
import time
import xlwt
import datetime
reload(sys)
sys.setdefaultencoding('UTF-8')

def export(request):
    taskid = request.GET.get("id")
    u = User.objects.all().order_by("-like")
    fname = "data/data.xls"
    file = xlwt.Workbook()
    table = file.add_sheet('active',cell_overwrite_ok=True)
    table.write(0,0,'id')
    table.write(0,1,u'姓名')
    table.write(0,2,u'头像地址')
    table.write(0,3,u'参加理由')
    table.write(0,4,u'手机号')
    table.write(0,5,u'排名')
    table.write(0,6,u'喜欢')
    line = 1
    for i in u:
        table.write(line,0,i.id)
        table.write(line,1,i.name)
        table.write(line,2,i.avatar)
        table.write(line,3,i.desc)
        table.write(line,4,i.mobile)
        table.write(line,5,line)
        table.write(line,6,i.like)
        line += 1
    file.save(fname)
    return HttpResponseRedirect('/data/data.xls')

def getUserInformation(request):
    uid = request.GET.get("uid")
    date = request.GET.get("date")
    if uid:
        u = User.objects.get(id=uid)
        us = User.objects.all().order_by("-like")
        cnt = 0
        rank = 0
        for i in us:
            cnt += 1
            if i.id == uid:
                rank = cnt
                break
    if date:
        u = User.objects.get(dateline=date)
        us = User.objects.all().order_by("-like")
        cnt = 0
        rank = 0
        for i in us:
            cnt += 1
            if i.dateline == date:
                rank = cnt
                break
    return JsonResponse({
        "status" : "success",
        "desc" : u.desc,
        "avatar" : u.avatar,
        "like" : u.like,
        "rank" : rank,
        "date" : u.dateline
    })

def like(request):
    if request.GET.get("uid"):
        u = User.objects.get(id=request.GET.get("uid"))
    else :
        u = User.objects.get(dateline=request.GET.get("date"))
    u.like += 1
    u.save()

    return JsonResponse({
        "status": "success",
        "like" : u.like
    })

def submit(request):
    name = request.POST.get("name")
    mobile = request.POST.get("mobile")
    desc = request.POST.get("desc")
    f = request.FILES.get('file')
    date = request.POST.get("date")
    path = "data/"
    if not os.path.exists(path):
        os.mkdirs(path)
    ext = str(f).split(".")[-1]
    ext = ext.lower()
    path = 'data/' + str(time.time()) + "." + ext
    des = open(path,'wb+')
    for j in f.chunks():
        des.write(j)
    des.close()
    dateline = time.time()
    u = User.objects.filter(mobile=mobile).count()
    if not u:
        user = User(name=name,mobile=mobile,desc=desc,like=0,avatar=path,dateline=date)
        user.save()
        return JsonResponse({
            "status":"success"
        })
    else :
        return JsonResponse({
            "status":"fail",
            "reason":"您已经参加过了哦"
        })


import requests
from bs4 import BeautifulSoup

def getValues():
    url = '3dhubs.com'
    r = requests.get('http://' + url)
    data = r.text
    soup = BeautifulSoup(data, 'html.parser')

    elements = soup.find_all('p', 'h3d-stat')
    values = {}
    values['parts'] = elements[0].find(class_='h3d-stat__value').string
    values['services'] = elements[2].find(class_='h3d-stat__value').string
    # values['reviews_number'] = elements[3].find(class_='h3d-stat__label').string
    values['reviews'] = '95,462'

    return values


import os
import errno

##############################################################################
# Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This s taken from Spack.
##############################################################################

def mkdirp(*paths):
    """Creates a directory, as well as parent directories if needed."""
    for path in paths:
        if not os.path.exists(path):
            try:
                os.makedirs(path)
            except OSError as e:
                if e.errno != errno.EEXIST or not os.path.isdir(path):
                    raise e
        elif not os.path.isdir(path):
            raise OSError(errno.EEXIST, "File already exists", path)

def traverse_tree(source_root, dest_root, rel_path='', **kwargs):
    """Traverse two filesystem trees simultaneously.

    Walks the LinkTree directory in pre or post order.  Yields each
    file in the source directory with a matching path from the dest
    directory, along with whether the file is a directory.
    e.g., for this tree::

        root/
          a/
            file1
            file2
          b/
            file3

    When called on dest, this yields::

        ('root',         'dest')
        ('root/a',       'dest/a')
        ('root/a/file1', 'dest/a/file1')
        ('root/a/file2', 'dest/a/file2')
        ('root/b',       'dest/b')
        ('root/b/file3', 'dest/b/file3')

    Keyword Arguments:
        order (str): Whether to do pre- or post-order traversal. Accepted
            values are 'pre' and 'post'
        ignore (str): Predicate indicating which files to ignore
        follow_nonexisting (bool): Whether to descend into directories in
            ``src`` that do not exit in ``dest``. Default is True
        follow_links (bool): Whether to descend into symlinks in ``src``
    """
    follow_nonexisting = kwargs.get('follow_nonexisting', True)
    follow_links = kwargs.get('follow_link', False)

    # Yield in pre or post order?
    order = kwargs.get('order', 'pre')
    if order not in ('pre', 'post'):
        raise ValueError("Order must be 'pre' or 'post'.")

    # List of relative paths to ignore under the src root.
    ignore = kwargs.get('ignore', lambda filename: False)

    # Don't descend into ignored directories
    if ignore(rel_path):
        return

    source_path = os.path.join(source_root, rel_path)
    dest_path = os.path.join(dest_root, rel_path)

    # preorder yields directories before children
    if order == 'pre':
        yield (source_path, dest_path)

    for f in os.listdir(source_path):
        source_child = os.path.join(source_path, f)
        dest_child = os.path.join(dest_path, f)
        rel_child = os.path.join(rel_path, f)

        # Treat as a directory
        if os.path.isdir(source_child) and (
                follow_links or not os.path.islink(source_child)):

            # When follow_nonexisting isn't set, don't descend into dirs
            # in source that do not exist in dest
            if follow_nonexisting or os.path.exists(dest_child):
                tuples = traverse_tree(
                    source_root, dest_root, rel_child, **kwargs)
                for t in tuples:
                    yield t

        # Treat as a file.
        elif not ignore(os.path.join(rel_path, f)):
            yield (source_child, dest_child)

    if order == 'post':
        yield (source_path, dest_path)

class LinkTree(object):
    """Class to create trees of symbolic links from a source directory.

    LinkTree objects are constructed with a source root.  Their
    methods allow you to create and delete trees of symbolic links
    back to the source tree in specific destination directories.
    Trees comprise symlinks only to files; directries are never
    symlinked to, to prevent the source directory from ever being
    modified.

    """

    def __init__(self, source_root, maxdepth=1000):
        if not os.path.exists(source_root):
            raise IOError("No such file or directory: '%s'", source_root)

        self._root = source_root
        self._maxdepth=maxdepth
        self._linklist=[]

    def find_conflict(self, dest_root, **kwargs):
        """Returns the first file in dest that conflicts with src"""
        kwargs['follow_nonexisting'] = False
        for src, dest in traverse_tree(self._root, dest_root, **kwargs):
            if os.path.isdir(src):
                if os.path.exists(dest) and not os.path.isdir(dest):
                    return dest
            elif os.path.exists(dest):
                return dest
        return None

    def toodepth(self,path):
        listpath = os.path.normpath(path).lstrip(os.path.sep).split(os.path.sep)
        #print("aaaaaaa:",listpath,listpath.__len__())
        r = (self._maxdepth < listpath.__len__())
        if r  : self._linklist.append(path)
        self._link= (self._maxdepth == listpath.__len__())
        return (r)

    def merge(self, dest_root, link=os.symlink, **kwargs):
        """Link all files in src into dest, creating directories
           if necessary.
           If ignore_conflicts is True, do not break when the target exists but
           rather return a list of files that could not be linked.
           Note that files blocking directories will still cause an error.
        """
        kwargs['order'] = 'pre'
        kwargs['ignore'] = self.toodepth
        ignore_conflicts = kwargs.get("ignore_conflicts", False)
        existing = []
        for src, dest in traverse_tree(self._root, dest_root, **kwargs):
            if os.path.isdir(src):
                if not os.path.exists(dest):
                    if self._link:
                        print("link:",src)
                        link(src, dest)
                    else:
                        mkdirp(dest)
                    continue

                if not os.path.isdir(dest):
                    raise ValueError("File blocks directory: %s" % dest)

                # mark empty directories so they aren't removed on unmerge.
                #no_unmerge#if not os.listdir(dest):
                    #no_unmerge#    marker = os.path.join(dest, empty_file_name)
                    #no_unmerge#    touch(marker)

            else:
                if os.path.exists(dest):
                    if ignore_conflicts:
                        existing.append(src)
                    else:
                        raise AssertionError("File already exists: %s" % dest)
                else:
                    link(src, dest)
        if ignore_conflicts:
            return existing

#################
if __name__ == '__main__':
    print("__file__:" + os.path.realpath(__file__))
    root=os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))),'cache')
    print("root:" + root)
    l = LinkTree(root,maxdepth=2)
    l.merge('/tmp/cache')


from django.shortcuts import render,redirect
from ecom import settings

from shop.models import Watch,Category
from django.views import View

# Example of CBV (post and Get both using same function)
# Class Base View
# class watch(View):
#     def post(self, request):
#         prod = request.POST.get('product')
#         # print(prod)
#         cart = request.session.get('cart')
#         if cart:
#             quantity = cart.get(prod)
#             if quantity:
#                 cart[prod] = quantity+1
#             else:
#                 cart[prod] = 1
#         else:
#             cart = {}
#             cart[prod] = 1
#         request.session['cart'] = cart
#         print('cart' ,request.session['cart'])
#         return redirect('/shop/pag')

#     def get(self, request):
#         shp = None
#         # request.session.get('cart').clear()
#         catego = Category.objects.all()
#         categoryID = request.GET.get('category')

#         if categoryID:
#             shp = Watch.objects.filter(category_id = categoryID)
#         else:
#             shp = Watch.objects.all()
#         data = {}
#         data['shop'] = shp
#         data['categ'] = catego
#         data['BASE_URL'] = settings.BASE_URL
#         print('you are : ', request.session.get('email'))
#         return render(request,'shop/watch.html',data)

# Authnticate APIs
def new(request,id):
    prod = request.POST.get('product')
    remove = request.POST.get('remove')
    cart = request.session.get('cart')
    if cart:
        quantity = cart.get(prod)
        if quantity:
            if remove:
                if quantity<=1:
                    cart.pop(prod)
                else:
                    cart[prod] = quantity-1
            else:
                cart[prod] = quantity+1
        else:
            cart[prod] = 1
    else:
        cart = {}
        cart[prod] = 1
    request.session['cart'] = cart
    print('cart' ,request.session['cart'])
    # show add product in list
    ids = list(request.session.get('cart').keys())
    allimages = Watch.objects.filter(id__in=ids)
    return render(request,'pages/cart.html',{"BASE_URL":settings.BASE_URL,'images':allimages})

def watch(request):
    shp = None
    catego = Category.objects.all()
    categoryID = request.GET.get('category')

    if categoryID:
        shp = Watch.objects.filter(category_id = categoryID)
    else:
        shp = Watch.objects.all()
    data = {}
    data['shop'] = shp
    data['categ'] = catego
    data['BASE_URL'] = settings.BASE_URL
    print('you are : ', request.session.get('email'))
    return render(request,'shop/watch.html',data)

# For Product detail
def product_detail(request,id):
    allimages = Watch.objects.filter(id=id)
    return render(request,'letest/product_details.html',{"BASE_URL":settings.BASE_URL,'images':allimages})


"""
Copyright [2009-2019] EMBL-European Bioinformatics Institute
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
     http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

import os
import pathlib

"""
Any setting defined here can be overridden by:

Settings the appropriate environment variable, eg. to override FOOBAR, `export APP_FOOBAR="whatever"`.
This is useful in production for secrets you do not wish to save in code and
also plays nicely with docker(-compose). Settings will attempt to convert environment variables to match the
type of the value here. See also activate.settings.sh.

Or, passing the custom setting as a keyword argument when initialising settings (useful when testing)
"""

# producer folder, where media, static, templates and other subfolders are located
PROJECT_ROOT = pathlib.Path(__file__).parent.parent

CONSUMER_SUBMIT_JOB_URL = 'submit-job'
CONSUMER_SUBMIT_INFERNAL_JOB_URL = 'submit-infernal-job'

MIN_QUERY_LENGTH = 10
MAX_QUERY_LENGTH = 7000

ENVIRONMENT = os.getenv('ENVIRONMENT', 'LOCAL')

# add settings from environment-specific files
if ENVIRONMENT == "LOCAL":
    from .local import *
elif ENVIRONMENT == "TEST":
    from .test import *
elif ENVIRONMENT == "DOCKER-COMPOSE":
    from .docker_compose import *
elif ENVIRONMENT == "PRODUCTION":
    from .production import *

EBI_SEARCH_PROXY_URL = 'https://search.rnacentral.org/api/post-rnacentral-ids'

def substitute_environment_variables():
    """
    Substitute environment variables into settings.

    This function is stolen from the default project, generated by
    aiohttp-devtools 'adev start' command.
    """
    for attr_name in globals():
        env_var = os.getenv(attr_name, None)

        if attr_name.startswith('_') or attr_name.upper() != attr_name:
            continue
        elif env_var is not None:
            # convert environment variable to the same type as the variable in settings
            original_type = type(globals()[attr_name])
            if issubclass(original_type, bool):
                env_var = env_var.upper() in ('1', 'TRUE')
            elif issubclass(original_type, int):
                env_var = int(env_var)
            elif issubclass(original_type, float):
                env_var = float(env_var)
            elif issubclass(original_type, pathlib.Path):
                env_var = pathlib.Path(env_var)
            elif issubclass(original_type, bytes):
                env_var = env_var.encode()

            globals()[attr_name] = env_var

substitute_environment_variables()


import time
import os

oldFiles = []
now = time.time()

def delete(path):
  for (root, folders, files) in os.walk(path):
    for file in files:
      filePath = root+'\\'+file
      fileAge = os.stat(filePath).st_ctime
      if now - fileAge > 2592000:
        oldFiles.append(filePath)
  for folder in folders:
    delete(root+'\\'+folder)

while True:
  pathName = input('Enter folder path: ')
  if not os.path.exists(pathName):
    print('Path does not exist, try again.')
    time.sleep(2)
  elif os.path.exists(pathName):
    delete(pathName)
    break

print(str(len(oldFiles)), 'files older than 30 days (that is, 2925000 seconds) found.')
while True:
  time.sleep(2)
  a = input('Delete permanently? (Y/N): ')
  if a == "N" or a == "No" or a == "n" or a == "no":
    print('Deletion cancelled.')
    break
  elif a == "Y" or a=="Yes" or a == "y" or a == "yes":
    print('Deleting...')
    for file in oldFiles:
      os.remove(file)
    time.sleep(3)
    break
  else:
    print("Invalid: Enter Yes/No, or Y/N.")


from datetime import timedelta
import logging

from busy_beaver.clients import twitter
from busy_beaver.common.wrappers import KeyValueStoreClient, SlackClient
from busy_beaver.toolbox import utc_now_minus

LAST_TWEET_KEY = "last_posted_tweet_id"
logger = logging.getLogger(__name__)
kv_store = KeyValueStoreClient()

def fetch_tweets_post_to_slack(installation, channel_name, username):
    logger.info("Fetching tweets to post")
    tweets = get_tweets(installation, username)

    tweets_to_post = _exclude_tweets_inside_window(tweets, window=timedelta(minutes=30))

    logger.info("Grabbed {0} tweets".format(len(tweets_to_post)))
    # post 1 tweet at a time
    _post_to_slack(installation, channel_name, tweets_to_post[:1], username)

def get_tweets(installation, username):
    """Get latest tweets after last_posted_tweet_id"""
    tweets = twitter.get_user_timeline(username)
    last_posted_tweet_id = kv_store.get_int(installation.id, LAST_TWEET_KEY)
    recent_tweets = [tweet for tweet in tweets if tweet.id > last_posted_tweet_id]
    return list(reversed(recent_tweets))

def _exclude_tweets_inside_window(tweets, *, window: timedelta):
    """Buffer to delete tweets before retweeting to Slack"""
    boundary_dt = utc_now_minus(window)
    return [tweet for tweet in tweets if tweet.created_at <= boundary_dt]

def _post_to_slack(installation, channel_name, tweets, twitter_username):
    """Twitter Slack app unfurls URLs in Slack to show tweet details"""
    slack = SlackClient(installation.bot_access_token)

    url = "https://twitter.com/{username}/statuses/{id}"
    for tweet in tweets:
        tweet_url = url.format(username=twitter_username, id=tweet.id)
        slack.post_message(tweet_url, channel=channel_name)
        kv_store.put_int(installation.id, LAST_TWEET_KEY, tweet.id)