# Databricks notebook source
# MAGIC
# MAGIC %md-sandbox
# MAGIC
# MAGIC

# MAGIC
# MAGIC

# COMMAND ----------

# MAGIC %md
# MAGIC # Bronze to Silver - ETL into a Silver table
# MAGIC
# MAGIC We need to perform some transformations on the data to move it from bronze to silver tables.

# COMMAND ----------

# MAGIC %md
# MAGIC ## Notebook Objective
# MAGIC
# MAGIC In this notebook we:
# MAGIC 1. Ingest raw data using composable functions
# MAGIC 1. Use composable functions to write to the Bronze table
# MAGIC 1. Develop the Bronze to Silver Step
# MAGIC    - Extract and transform the raw string to columns
# MAGIC    - Quarantine the bad data
# MAGIC    - Load clean data into the Silver table
# MAGIC 1. Update the status of records in the Bronze table

# COMMAND ----------

# MAGIC %md
# MAGIC ## Step Configuration

# COMMAND ----------

# MAGIC %run ./includes/configuration

# COMMAND ----------

# MAGIC %md
# MAGIC ## Import Operation Functions

# COMMAND ----------

# MAGIC %run ./includes/main/python/operations

# COMMAND ----------

# MAGIC %md
# MAGIC ### Display the Files in the Bronze Paths

# COMMAND ----------

display(dbutils.fs.ls(bronzePath))

# COMMAND ----------

# MAGIC %md
# MAGIC ## Land More Raw Data
# MAGIC
# MAGIC Before we get started with this lab, let's land some more raw data.
# MAGIC
# MAGIC In a production setting, we might have data coming in every
# MAGIC hour. Here we are simulating this with the function
# MAGIC `ingest_classic_data`.
# MAGIC
# MAGIC 😎 Recall that we did this in the notebook `00_ingest_raw`.

# COMMAND ----------

# MAGIC %md
# MAGIC
# MAGIC **EXERCISE:** Land ten hours using the utility function, `ingest_classic_data`.

# COMMAND ----------

# ANSWER
ingest_classic_data(hours=10)

# COMMAND ----------

# MAGIC %md
# MAGIC ## Current Delta Architecture
# MAGIC Next, we demonstrate everything we have built up to this point in our
# MAGIC Delta Architecture.
# MAGIC
# MAGIC We do so not with the ad hoc queries as written before, but now with
# MAGIC composable functions included in the file `classic/includes/main/python/operations`.
# MAGIC You should check this file for the correct arguments to use in the next
# MAGIC three steps.
# MAGIC
# MAGIC 🤔 You can refer to `plus/02_bronze_to_silver` if you are stuck.

# COMMAND ----------

# MAGIC %md
# MAGIC ### Step 1: Create the `rawDF` DataFrame
# MAGIC
# MAGIC **Exercise:** Use the function `read_batch_raw` to ingest the newly arrived
# MAGIC data.

# COMMAND ----------

# ANSWER
rawDF = read_batch_raw(spark, rawPath)

# COMMAND ----------

# MAGIC %md
# MAGIC ### Step 2: Transform the Raw Data
# MAGIC
# MAGIC **Exercise:** Use the function `transform_raw` to ingest the newly arrived
# MAGIC data.

# COMMAND ----------

# ANSWER
transformedRawDF = transform_raw(rawDF)

# COMMAND ----------

# MAGIC %md
# MAGIC ## Verify the Schema with an Assertion
# MAGIC
# MAGIC The DataFrame `transformedRawDF` should now have the following schema:
# MAGIC
# MAGIC ```
# MAGIC datasource: string
# MAGIC ingesttime: timestamp
# MAGIC value: string
# MAGIC status: string
# MAGIC p_ingestdate: date
# MAGIC ```

# COMMAND ----------

from pyspark.sql.types import *

assert transformedRawDF.schema == StructType(
    [
        StructField("datasource", StringType(), False),
        StructField("ingesttime", TimestampType(), False),
        StructField("status", StringType(), False),
        StructField("value", StringType(), True),
        StructField("p_ingestdate", DateType(), False),
    ]
)
print("Assertion passed.")

# COMMAND ----------

# MAGIC %md
# MAGIC ### Step 3: Write Batch to a Bronze Table
# MAGIC
# MAGIC **Exercise:** Use the function `batch_writer` to ingest the newly arrived
# MAGIC data.
# MAGIC
# MAGIC **Note**: you will need to begin the write with the `.save()` method on
# MAGIC your writer.
# MAGIC
# MAGIC 🤖 **Be sure to partition on `p_ingestdate`**.

# COMMAND ----------

# ANSWER
rawToBronzeWriter = batch_writer(dataframe=transformedRawDF, partition_column="p_ingestdate")

rawToBronzeWriter.save(bronzePath)

# COMMAND ----------

# MAGIC %md
# MAGIC ## Purge Raw File Path
# MAGIC
# MAGIC Manually purge the raw files that have already been loaded.

# COMMAND ----------

dbutils.fs.rm(rawPath, recurse=True)

# COMMAND ----------

# MAGIC %md
# MAGIC ## Display the Bronze Table
# MAGIC
# MAGIC If you have ingested 16 hours you should see 160 records.

# COMMAND ----------

# MAGIC %sql
# MAGIC SELECT * FROM health_tracker_classic_bronze

# COMMAND ----------

# MAGIC %md
# MAGIC ## Bronze to Silver Step
# MAGIC
# MAGIC Let's start the Bronze to Silver step.

# COMMAND ----------

# MAGIC %md
# MAGIC ## Make Notebook Idempotent

# COMMAND ----------

dbutils.fs.rm(silverPath, recurse=True)

# COMMAND ----------

# MAGIC %md
# MAGIC ## Load New Records from the Bronze Records
# MAGIC
# MAGIC **EXERCISE**
# MAGIC
# MAGIC Load all records from the Bronze table with a status of `"new"`.

# COMMAND ----------

# ANSWER

bronzeDF = spark.read.table("health_tracker_classic_bronze").filter("status = 'new'")

# COMMAND ----------

# MAGIC %md
# MAGIC ## Extract the Nested JSON from the Bronze Records

# COMMAND ----------

# MAGIC %md
# MAGIC ### Step 1: Extract the Nested JSON from the `value` column
# MAGIC **EXERCISE**
# MAGIC
# MAGIC Use `pyspark.sql` functions to extract the `"value"` column as a new
# MAGIC column `"nested_json"`.

# COMMAND ----------

# ANSWER
from pyspark.sql.functions import from_json

json_schema = """
    time TIMESTAMP,
    name STRING,
    device_id STRING,
    steps INTEGER,
    day INTEGER,
    month INTEGER,
    hour INTEGER
"""

bronzeAugmentedDF = bronzeDF.withColumn("nested_json", from_json(col("value"), json_schema))

# COMMAND ----------

# MAGIC %md
# MAGIC ### Step 2: Create the Silver DataFrame by Unpacking the `nested_json` Column
# MAGIC
# MAGIC Unpacking a JSON column means to flatten the JSON and include each top level attribute
# MAGIC as its own column.
# MAGIC
# MAGIC 🚨 **IMPORTANT** Be sure to include the `"value"` column in the Silver DataFrame
# MAGIC because we will later use it as a unique reference to each record in the
# MAGIC Bronze table

# COMMAND ----------

# ANSWER
silver_health_tracker = bronzeAugmentedDF.select("value", "nested_json.*")

# COMMAND ----------

# MAGIC %md
# MAGIC ## Verify the Schema with an Assertion
# MAGIC
# MAGIC The DataFrame `silver_health_tracker` should now have the following schema:
# MAGIC
# MAGIC ```
# MAGIC value: string
# MAGIC time: timestamp
# MAGIC name: string
# MAGIC device_id: string
# MAGIC steps: integer
# MAGIC day: integer
# MAGIC month: integer
# MAGIC hour: integer
# MAGIC ```
# MAGIC
# MAGIC 💪🏼 Remember, the function `_parse_datatype_string` converts a DDL format schema string into a Spark schema.

# COMMAND ----------

from pyspark.sql.types import _parse_datatype_string

assert silver_health_tracker.schema == _parse_datatype_string(
    """
  value STRING,
  time TIMESTAMP,
  name STRING,
  device_id STRING,
  steps INTEGER,
  day INTEGER,
  month INTEGER,
  hour INTEGER
"""
)
print("Assertion passed.")

# COMMAND ----------

# MAGIC %md
# MAGIC ## Transform the Data
# MAGIC
# MAGIC 1. Create a column `p_eventdate DATE` from the column `time`.
# MAGIC 1. Rename the column `time` to `eventtime`.
# MAGIC 1. Cast the `device_id` as an integer.
# MAGIC 1. Include only the following columns in this order:
# MAGIC    1. `value`
# MAGIC    1. `device_id`
# MAGIC    1. `steps`
# MAGIC    1. `eventtime`
# MAGIC    1. `name`
# MAGIC    1. `p_eventdate`
# MAGIC
# MAGIC 💪🏼 Remember that we name the new column `p_eventdate` to indicate
# MAGIC that we are partitioning on this column.
# MAGIC
# MAGIC 🕵🏽♀ Remember that we are keeping the `value` as a unique reference to values
# MAGIC in the Bronze table.

# COMMAND ----------

# ANSWER
from pyspark.sql.functions import col

silver_health_tracker = silver_health_tracker.select(
    "value",
    col("device_id").cast("integer").alias("device_id"),
    "steps",
    col("time").alias("eventtime"),
    "name",
    col("time").cast("date").alias("p_eventdate"),
)

# COMMAND ----------

# MAGIC %md
# MAGIC ## Verify the Schema with an Assertion
# MAGIC
# MAGIC The DataFrame `silver_health_tracker_data_df` should now have the following schema:
# MAGIC
# MAGIC ```
# MAGIC value: string
# MAGIC device_id: integer
# MAGIC heartrate: double
# MAGIC eventtime: timestamp
# MAGIC name: string
# MAGIC p_eventdate: date```
# MAGIC
# MAGIC 💪🏼 Remember, the function `_parse_datatype_string` converts a DDL format schema string into a Spark schema.

# COMMAND ----------

from pyspark.sql.types import _parse_datatype_string

assert silver_health_tracker.schema == _parse_datatype_string(
    """
  value STRING,
  device_id INTEGER,
  steps INTEGER,
  eventtime TIMESTAMP,
  name STRING,
  p_eventdate DATE
"""
), "Schemas do not match"
print("Assertion passed.")

# COMMAND ----------

# MAGIC %md
# MAGIC ## Quarantine the Bad Data
# MAGIC
# MAGIC Recall that at step, `00_ingest_raw`, we identified that some records were coming in
# MAGIC with device_ids passed as uuid strings instead of string-encoded integers.
# MAGIC Our Silver table stores device_ids as integers so clearly there is an issue
# MAGIC with the incoming data.
# MAGIC
# MAGIC In order to properly handle this data quality issue, we will quarantine
# MAGIC the bad records for later processing.

# COMMAND ----------

# MAGIC %md
# MAGIC Check for records that have nulls - compare the output of the following two cells

# COMMAND ----------

silver_health_tracker.count()

# COMMAND ----------

silver_health_tracker.na.drop().count()

# COMMAND ----------

# MAGIC %md
# MAGIC ### Split the Silver DataFrame

# COMMAND ----------

silver_health_tracker_clean = silver_health_tracker.filter("device_id IS NOT NULL")
silver_health_tracker_quarantine = silver_health_tracker.filter("device_id IS NULL")

# COMMAND ----------

# MAGIC %md
# MAGIC ### Display the Quarantined Records

# COMMAND ----------

display(silver_health_tracker_quarantine)

# COMMAND ----------

# MAGIC %md
# MAGIC ## WRITE Clean Batch to a Silver Table
# MAGIC
# MAGIC **EXERCISE:** Batch write `silver_health_tracker_clean` to the Silver table path, `silverPath`.
# MAGIC
# MAGIC 1. Use format, `"delta"`
# MAGIC 1. Use mode `"append"`.
# MAGIC 1. Do **NOT** include the `value` column.
# MAGIC 1. Partition by `"p_eventdate"`.

# COMMAND ----------

# ANSWER
(
    silver_health_tracker_clean.select("device_id", "steps", "eventtime", "name", "p_eventdate")
    .write.format("delta")
    .mode("append")
    .partitionBy("p_eventdate")
    .save(silverPath)
)

# COMMAND ----------

spark.sql(
    """
DROP TABLE IF EXISTS health_tracker_classic_silver
"""
)

spark.sql(
    f"""
CREATE TABLE health_tracker_classic_silver
USING DELTA
LOCATION "{silverPath}"
"""
)

# COMMAND ----------

# MAGIC %md
# MAGIC ## Verify the Schema with an Assertion

# COMMAND ----------

silverTable = spark.read.table("health_tracker_classic_silver")
expected_schema = """
  device_id INTEGER,
  steps INTEGER,
  eventtime TIMESTAMP,
  name STRING,
  p_eventdate DATE
"""

assert silverTable.schema == _parse_datatype_string(expected_schema), "Schemas do not match"
print("Assertion passed.")

# COMMAND ----------

# MAGIC %sql
# MAGIC
# MAGIC SELECT * FROM health_tracker_classic_silver

# COMMAND ----------

# MAGIC %md
# MAGIC ## Update Bronze table to Reflect the Loads
# MAGIC
# MAGIC **EXERCISE:** Update the records in the Bronze table to reflect updates.
# MAGIC
# MAGIC ### Step 1: Update Clean records
# MAGIC Clean records that have been loaded into the Silver table and should have
# MAGIC    their Bronze table `status` updated to `"loaded"`.
# MAGIC
# MAGIC 💃🏽 **Hint** You are matching the `value` column in your clean Silver DataFrame
# MAGIC to the `value` column in the Bronze table.

# COMMAND ----------

# ANSWER
from delta.tables import DeltaTable

bronzeTable = DeltaTable.forPath(spark, bronzePath)
silverAugmented = silver_health_tracker_clean.withColumn("status", lit("loaded"))

update_match = "bronze.value = clean.value"
update = {"status": "clean.status"}

(
    bronzeTable.alias("bronze")
    .merge(silverAugmented.alias("clean"), update_match)
    .whenMatchedUpdate(set=update)
    .execute()
)

# COMMAND ----------

# MAGIC %md
# MAGIC **EXERCISE:** Update the records in the Bronze table to reflect updates.
# MAGIC
# MAGIC ### Step 2: Update Quarantined records
# MAGIC Quarantined records should have their Bronze table `status` updated to `"quarantined"`.
# MAGIC
# MAGIC 🕺🏻 **Hint** You are matching the `value` column in your quarantine Silver
# MAGIC DataFrame to the `value` column in the Bronze table.

# COMMAND ----------

# ANSWER
silverAugmented = silver_health_tracker_quarantine.withColumn("status", lit("quarantined"))

update_match = "bronze.value = quarantine.value"
update = {"status": "quarantine.status"}

(
    bronzeTable.alias("bronze")
    .merge(silverAugmented.alias("quarantine"), update_match)
    .whenMatchedUpdate(set=update)
    .execute()
)

# COMMAND ----------

# MAGIC %md-sandbox
# MAGIC © 2021 Databricks, Inc. All rights reserved.

# MAGIC Apache, Apache Spark, Spark and the Spark logo are trademarks of the Apache Software Foundation.

# MAGIC

# MAGIC Privacy Policy | Terms of Use | Support


import cv2
import os
import json
from pathlib import Path

# Get the input filename
rootFolder = Path(os.path.dirname(os.path.realpath(__file__)))
outFolder = rootFolder / "out"
tilesFolder = rootFolder / "../common/tiles"
dataFilePath = outFolder / "data.json"

# Create an output folder if it doesn't already exist
if not os.path.isdir(outFolder):
    os.mkdir(outFolder)

# Calculate and return the average color for the given image
def getAverageColor(img):
    ################################################
    # Your code here
    ################################################
    pass

# Create a list of metadata objects (see handout) and save it as a JSON file
def generateMetadata():
    # Iterate thorugh the tile images
    for imgName in os.listdir(tilesFolder):
        img_path = tilesFolder / imgName
        print(img_path.resolve())

        ################################################
        # Your code here
        ################################################

# Check if the output file exists
if os.path.isfile(dataFilePath):
    print("File already exists, overwrite existing file? y/n")
    ans = input()
    # Overwrite the file if the user inputs 'y'
    if ans == "y" or ans == "Y":
        generateMetadata()
    else:
        print("Quitting.")
else:
    generateMetadata()


from bs4 import BeautifulSoup
import requests
import re
import operator

def find_between(s, first, last):
    return re.search(first + r'(.*)' + last, s, re.DOTALL | re.MULTILINE).group(1)

def get_teams(teams=[]):
    page = 0;

    while True:
        page += 1
        soup = BeautifulSoup(requests.get("http://www.gosugamers.net/dota2/rankings?page=" + str(page)).text)

        for index, data in enumerate(soup.find_all(class_="main no-game")):
            html = str(data)

            country = re.findall(r'\"(.+?)\"', html)[2]
            team = find_between(html, '', "")
            rank = index + ((page -1) * 50)
            show_rank = str(rank + 1)
            teams.insert(rank, {"rank": show_rank, "irank": (rank + 1), "country": country, "name": team})

            #Somehow this stops the loop if it reaches the end - no idea why
            try:
                if teams[rank] is None:
                    pass
            except IndexError:
                teams.pop(len(teams) - 1)
                teams.reverse()
                return teams

def get_games(teams, games=[]):
    # Need to complete team names which end in ...
    # teams is an optional parameter as there is no need to load the teams twice
    page = 0
    nows = 0

    while True:
        page += 1
        soup = BeautifulSoup(requests.get("http://www.gosugamers.net/dota2/gosubet?u-page=" + str(page)).text)
        for index, data in enumerate(soup.find_all(class_="match hover-background")):
            html = str(data)

            #Finding the time the match starts at
            time_html = data.parent.parent.find(class_="live-in")

            if time_html is None:
                if data.parent.parent.find(class_="score-wrap") is None:
                    if page is 1:
                        time = "Now"
                    else:
                        continue
                else:
                    continue
            else:
                time = str(time_html.text).rstrip().replace('\n', '')

            #Finds the first team and auto completes if name ends with ...
            team1 = find_between(html, "", "", " ")
            if team2.endswith("..."):
                for team in teams:
                    if team["name"].startswith(team2.strip("...")):
                        team2 = team["name"]
                        break

            #time_test = find_between(time_html, '\n', '')

            rank = index + ((page - 1) * 15)

            games.insert(rank, {"position": rank, "team1": team1, "team2": team2, "time": time})

            #Somehow this stops the loop if it reaches the end - no idea why
            try:
                if games[rank] is None:
                    pass
            except IndexError:
                games.pop(len(games) - 1)
                games.reverse()
                return games

def get_team(name, teams):
    for team in teams:
        if team["name"] == name:
            return team

def get_next_match(team_name, teams, games):
    games.sort(key=operator.itemgetter('position'))
    for game in games:
        if (game["team1"] == team_name) | (game["team2"] == team_name):
            games.reverse()
            return game


import paramiko

# ip = '2600:1f16:e7a:a088:51b:4369:e4e3:6ff8'
# name ='ubuntu'
# key_path='/home/drl/Jerry/tool/aws_ohio.pem'
#
# key=paramiko.RSAKey.from_private_key_file(key_path )
#
# #建立一个加密的管道
# scp=paramiko.Transport((ip,22))
#
#
# #建立连接
# scp.connect(username=name,pkey=key)
# #建立一个sftp客户端对象，通过ssh transport操作远程文件
# sftp=paramiko.SFTPClient.from_transport(scp)
# #Copy a remote file (remotepath) from the SFTP server to the local host
# sftp.get('/home/ubuntu/README','log-files/')
# # #Copy a local file (localpath) to the SFTP server as remotepath
# # sftp.put('/root/crash-6.1.6.tar.gz','/tmp/crash-6.1.6.tar.gz')
# scp.close()
# #2402:f000:6:3801:2d55:548f:d03c:ccad/64

import paramiko,datetime,os
import socket
hostname='2600:1f16:e7a:a088:805d:16d6:f387:62e5'
username='ubuntu'

key_path='/home/drl/Jerry/tool/aws_ohio.pem'
key=paramiko.RSAKey.from_private_key_file(key_path )

port=22

local_dir='/home/drl/PycharmProjects/DeployedProjects/CR_CPG/Hyper_lab/tmp/model'
remote_dir='/home/ubuntu/jerry/examples/tmp'
try:
    t=paramiko.Transport((hostname,port))
    t.connect(username=username,  pkey=key)
    sftp=paramiko.SFTPClient.from_transport(t)
    #files=sftp.listdir(dir_path)
    files=sftp.listdir(remote_dir)
    for f in files:
        print('')
        print( '#########################################')
        print('Beginning to download file from %s %s ' % (hostname,datetime.datetime.now()) )
        print( 'Downloading file:',os.path.join(remote_dir,f))
        sftp.get(os.path.join(remote_dir,f),os.path.join(local_dir,f))#下载

        #sftp.put(os.path.join(local_dir,f),os.path.join(remote_dir,f))#上传
        print ('Download file success %s ' % datetime.datetime.now())
        print ('')
        print ('##########################################')
    t.close()

except Exception:
    print ("connect error!")
#
# import paramiko
# import os
# from stat import S_ISDIR as isdir
#
#
# def down_from_remote(sftp_obj, remote_dir_name, local_dir_name):
#     """远程下载文件"""
#     remote_file = sftp_obj.stat(remote_dir_name)
#     if isdir(remote_file.st_mode):
#         # 文件夹，不能直接下载，需要继续循环
#         check_local_dir(local_dir_name)
#         print('开始下载文件夹：' + remote_dir_name)
#         for remote_file_name in sftp.listdir(remote_dir_name):
#             sub_remote = os.path.join(remote_dir_name, remote_file_name)
#             sub_remote = sub_remote.replace('\\', '/')
#             sub_local = os.path.join(local_dir_name, remote_file_name)
#             sub_local = sub_local.replace('\\', '/')
#             down_from_remote(sftp_obj, sub_remote, sub_local)
#     else:
#         # 文件，直接下载
#         print('开始下载文件：' + remote_dir_name)
#         sftp.get(remote_dir_name, local_dir_name)
#
# def put_to_remote(sftp_obj, remote_dir_name, local_dir_name):
#     """远程下载文件"""
#     remote_file = sftp_obj.stat(remote_dir_name)
#     if isdir(remote_file.st_mode):
#         # 文件夹，不能直接下载，需要继续循环
#         check_local_dir(local_dir_name)
#         print('开始上传文件夹：' + remote_dir_name)
#         for remote_file_name in sftp.listdir(remote_dir_name):
#             sub_remote = os.path.join(remote_dir_name, remote_file_name)
#             sub_remote = sub_remote.replace('\\', '/')
#             sub_local = os.path.join(local_dir_name, remote_file_name)
#             sub_local = sub_local.replace('\\', '/')
#             down_from_remote(sftp_obj, sub_remote, sub_local)
#     else:
#         # 文件，直接下载
#         print('开始下载文件：' + remote_dir_name)
#         sftp.put(local_dir_name,remote_dir_name )
#
# def check_local_dir(local_dir_name):
#     """本地文件夹是否存在，不存在则创建"""
#     if not os.path.exists(local_dir_name):
#         os.makedirs(local_dir_name)
#
#
# if __name__ == "__main__":
#     """程序主入口"""
#     # 服务器连接信息
#     host_name = hostname
#     user_name = username
#
#     port = 22
#     # 远程文件路径（需要绝对路径）
#     remote_dir =  remote_dir
#     # 本地文件存放路径（绝对路径或者相对路径都可以）
#     local_dir = local_dir
#
#     # 连接远程服务器
#     t = paramiko.Transport((host_name, port))
#     t.connect(username=user_name, pkey=key)
#     sftp = paramiko.SFTPClient.from_transport(t)
#
#     # 远程文件开始下载
#    # down_from_remote(sftp, remote_dir, local_dir)
#     put_to_remote(sftp, remote_dir, local_dir)
#     # 关闭连接
#     t.close()


from hypothesis import strategies as st
import numpy as np

# local
import ivy
import ivy_tests.test_ivy.helpers as helpers
from ivy_tests.test_ivy.helpers import handle_test

# vorbis_window
@handle_test(
    fn_tree="functional.ivy.experimental.vorbis_window",
    dtype_and_x=helpers.dtype_and_values(
        available_dtypes=helpers.get_dtypes("integer"),
        max_num_dims=0,
        min_value=1,
        max_value=10,
    ),
    dtype=helpers.get_dtypes("float", full=False),
    test_gradients=st.just(False),
    test_instance_method=st.just(False),
)
def test_vorbis_window(
    *, dtype_and_x, dtype, test_flags, backend_fw, fn_name, on_device
):
    input_dtype, x = dtype_and_x
    helpers.test_function(
        input_dtypes=input_dtype,
        test_flags=test_flags,
        atol_=1e-02,
        backend_to_test=backend_fw,
        fn_name=fn_name,
        on_device=on_device,
        window_length=int(x[0]),
        dtype=dtype[0],
    )

# TODO: fix return precision problem when dtype=bfloat16
# hann_window
@handle_test(
    fn_tree="functional.ivy.experimental.hann_window",
    dtype_and_x=helpers.dtype_and_values(
        available_dtypes=helpers.get_dtypes("integer"),
        max_num_dims=0,
        min_value=1,
        max_value=10,
    ),
    periodic=st.booleans(),
    dtype=helpers.get_dtypes("float", full=False),
    test_gradients=st.just(False),
    test_instance_method=st.just(False),
)
def test_hann_window(
    *, dtype_and_x, periodic, dtype, test_flags, backend_fw, fn_name, on_device
):
    input_dtype, x = dtype_and_x
    helpers.test_function(
        input_dtypes=input_dtype,
        test_flags=test_flags,
        backend_to_test=backend_fw,
        atol_=0.015,
        fn_name=fn_name,
        on_device=on_device,
        size=int(x[0]),
        periodic=periodic,
        dtype=dtype[0],
    )

# kaiser_window
@handle_test(
    fn_tree="functional.ivy.experimental.kaiser_window",
    dtype_and_x=helpers.dtype_and_values(
        available_dtypes=helpers.get_dtypes("integer"),
        max_num_dims=0,
        min_value=1,
        max_value=10,
    ),
    periodic=st.booleans(),
    beta=st.floats(min_value=0, max_value=5),
    dtype=helpers.get_dtypes("float", full=False),
    test_gradients=st.just(False),
    test_instance_method=st.just(False),
)
def test_kaiser_window(
    *, dtype_and_x, periodic, beta, dtype, test_flags, backend_fw, fn_name, on_device
):
    input_dtype, x = dtype_and_x
    helpers.test_function(
        input_dtypes=input_dtype,
        test_flags=test_flags,
        backend_to_test=backend_fw,
        fn_name=fn_name,
        on_device=on_device,
        window_length=int(x[0]),
        periodic=periodic,
        beta=beta,
        dtype=dtype[0],
    )

# kaiser_bessel_derived_window
@handle_test(
    fn_tree="functional.ivy.experimental.kaiser_bessel_derived_window",
    dtype_and_x=helpers.dtype_and_values(
        available_dtypes=helpers.get_dtypes("integer"),
        max_num_dims=0,
        min_value=1,
        max_value=10,
    ),
    beta=st.floats(min_value=1, max_value=5),
    dtype=helpers.get_dtypes("float", full=False),
    test_gradients=st.just(False),
    test_instance_method=st.just(False),
)
def test_kaiser_bessel_derived_window(
    *, dtype_and_x, beta, dtype, test_flags, backend_fw, fn_name, on_device
):
    input_dtype, x = dtype_and_x
    helpers.test_function(
        input_dtypes=input_dtype,
        test_flags=test_flags,
        backend_to_test=backend_fw,
        fn_name=fn_name,
        on_device=on_device,
        window_length=int(x[0]),
        beta=beta,
        dtype=dtype[0],
    )

# hamming_window
@handle_test(
    fn_tree="functional.ivy.experimental.hamming_window",
    dtype_and_x=helpers.dtype_and_values(
        available_dtypes=helpers.get_dtypes("integer"),
        max_num_dims=0,
        min_value=1,
        max_value=10,
    ),
    periodic=st.booleans(),
    dtype_and_f=helpers.dtype_and_values(
        available_dtypes=helpers.get_dtypes("float"),
        max_num_dims=0,
        num_arrays=2,
        min_value=0,
        max_value=5,
    ),
    dtype=helpers.get_dtypes("float", full=False),
    test_gradients=st.just(False),
    test_instance_method=st.just(False),
)
def test_hamming_window(
    *,
    dtype_and_x,
    periodic,
    dtype_and_f,
    dtype,
    test_flags,
    backend_fw,
    fn_name,
    on_device,
):
    input_dtype1, x = dtype_and_x
    input_dtype2, f = dtype_and_f
    helpers.test_function(
        input_dtypes=input_dtype1 + input_dtype2,
        test_flags=test_flags,
        backend_to_test=backend_fw,
        atol_=2e-06,
        fn_name=fn_name,
        on_device=on_device,
        window_length=int(x[0]),
        periodic=periodic,
        alpha=float(f[0]),
        beta=float(f[1]),
        dtype=dtype[0],
    )

@handle_test(
    fn_tree="functional.ivy.experimental.tril_indices",
    dtype_and_n=helpers.dtype_and_values(
        available_dtypes=helpers.get_dtypes("integer"),
        max_num_dims=0,
        num_arrays=2,
        min_value=0,
        max_value=10,
    ),
    k=helpers.ints(min_value=-11, max_value=11),
    test_with_out=st.just(False),
    test_gradients=st.just(False),
    test_instance_method=st.just(False),
)
def test_tril_indices(*, dtype_and_n, k, test_flags, backend_fw, fn_name, on_device):
    input_dtype, x = dtype_and_n
    helpers.test_function(
        input_dtypes=input_dtype,
        test_flags=test_flags,
        backend_to_test=backend_fw,
        on_device=on_device,
        fn_name=fn_name,
        n_rows=int(x[0]),
        n_cols=int(x[1]),
        k=k,
    )

# eye_like
@handle_test(
    fn_tree="functional.ivy.experimental.eye_like",
    dtype_and_x=helpers.dtype_and_values(
        available_dtypes=helpers.get_dtypes("valid"),
        min_num_dims=1,
        max_num_dims=1,
        min_dim_size=1,
        max_dim_size=5,
    ),
    k=helpers.ints(min_value=-10, max_value=10),
    test_gradients=st.just(False),
    number_positional_args=st.just(1),
)
def test_eye_like(*, dtype_and_x, k, test_flags, backend_fw, fn_name, on_device):
    dtype, x = dtype_and_x
    helpers.test_function(
        input_dtypes=dtype,
        test_flags=test_flags,
        on_device=on_device,
        backend_to_test=backend_fw,
        fn_name=fn_name,
        x=x[0],
        k=k,
        dtype=dtype[0],
        device=on_device,
    )

# ndenumerate
@handle_test(
    fn_tree="functional.ivy.experimental.ndenumerate",
    dtype_and_x=helpers.dtype_and_values(
        available_dtypes=helpers.get_dtypes("valid"),
        min_num_dims=1,
    ),
)
def test_ndenumerate(dtype_and_x):
    values = dtype_and_x[1][0]
    for (index1, x1), (index2, x2) in zip(
        np.ndenumerate(values), ivy.ndenumerate(values)
    ):
        assert index1 == index2 and x1 == x2.to_numpy()

# ndindex
@handle_test(
    fn_tree="functional.ivy.experimental.ndindex",
    dtype_x_shape=helpers.dtype_and_values(
        available_dtypes=helpers.get_dtypes("valid"),
        min_num_dims=1,
        ret_shape=True,
    ),
)
def test_ndindex(dtype_x_shape):
    shape = dtype_x_shape[2]
    for index1, index2 in zip(np.ndindex(shape), ivy.ndindex(shape)):
        assert index1 == index2

# indices
@handle_test(
    fn_tree="functional.ivy.experimental.indices",
    ground_truth_backend="numpy",
    shape=helpers.get_shape(
        allow_none=False,
        min_num_dims=1,
        max_num_dims=5,
        min_dim_size=1,
        max_dim_size=10,
    ),
    dtypes=helpers.get_dtypes(
        "numeric",
        full=False,
    ),
    sparse=st.booleans(),
    container_flags=st.just([False]),
    test_instance_method=st.just(False),
    test_with_out=st.just(False),
    test_gradients=st.just(False),
)
def test_indices(*, shape, dtypes, sparse, test_flags, backend_fw, fn_name, on_device):
    helpers.test_function(
        input_dtypes=[],
        test_flags=test_flags,
        on_device=on_device,
        backend_to_test=backend_fw,
        fn_name=fn_name,
        dimensions=shape,
        dtype=dtypes[0],
        sparse=sparse,
    )

@st.composite
def valid_unsorted_segment_min_inputs(draw):
    while True:
        dtype = draw(st.sampled_from([ivy.int32, ivy.int64, ivy.float32, ivy.float64]))
        segment_ids_dim = draw(st.integers(min_value=3, max_value=10))
        num_segments = draw(st.integers(min_value=2, max_value=segment_ids_dim))

        data_dim = draw(
            helpers.get_shape(
                min_dim_size=segment_ids_dim,
                max_dim_size=segment_ids_dim,
                min_num_dims=1,
                max_num_dims=4,
            )
        )
        data_dim = (segment_ids_dim,) + data_dim[1:]

        data = draw(
            helpers.array_values(
                dtype=dtype,
                shape=data_dim,
                min_value=1,
                max_value=10,
            )
        )

        segment_ids = draw(
            helpers.array_values(
                dtype=ivy.int32,
                shape=(segment_ids_dim,),
                min_value=0,
                max_value=num_segments + 1,
            )
        )
        if data.shape[0] == segment_ids.shape[0]:
            if np.max(segment_ids) < num_segments:
                return (dtype, ivy.int32), data, num_segments, segment_ids

# unsorted_segment_min
@handle_test(
    fn_tree="functional.ivy.experimental.unsorted_segment_min",
    d_x_n_s=valid_unsorted_segment_min_inputs(),
    test_with_out=st.just(False),
    test_gradients=st.just(False),
)
def test_unsorted_segment_min(
    *,
    d_x_n_s,
    test_flags,
    backend_fw,
    fn_name,
    on_device,
):
    dtypes, data, num_segments, segment_ids = d_x_n_s
    helpers.test_function(
        input_dtypes=dtypes,
        backend_to_test=backend_fw,
        test_flags=test_flags,
        on_device=on_device,
        fn_name=fn_name,
        data=data,
        segment_ids=segment_ids,
        num_segments=num_segments,
    )

@handle_test(
    fn_tree="functional.ivy.experimental.unsorted_segment_sum",
    d_x_n_s=valid_unsorted_segment_min_inputs(),
    test_with_out=st.just(False),
    test_gradients=st.just(False),
)
def test_unsorted_segment_sum(
    *,
    d_x_n_s,
    test_flags,
    backend_fw,
    fn_name,
    on_device,
):
    dtypes, data, num_segments, segment_ids = d_x_n_s
    helpers.test_function(
        input_dtypes=dtypes,
        test_flags=test_flags,
        on_device=on_device,
        fw=backend_fw,
        fn_name=fn_name,
        data=data,
        segment_ids=segment_ids,
        num_segments=num_segments,
    )

@handle_test(
    fn_tree="functional.ivy.experimental.unsorted_segment_sum",
    d_x_n_s=valid_unsorted_segment_min_inputs(),
    test_with_out=st.just(False),
    test_gradients=st.just(False),
)
def test_unsorted_segment_sum(
    *,
    d_x_n_s,
    test_flags,
    backend_fw,
    fn_name,
    on_device,
):
    dtypes, data, num_segments, segment_ids = d_x_n_s
    helpers.test_function(
        input_dtypes=dtypes,
        test_flags=test_flags,
        on_device=on_device,
        fw=backend_fw,
        fn_name=fn_name,
        data=data,
        segment_ids=segment_ids,
        num_segments=num_segments,
    )

@st.composite
def _random_tucker_data(draw):
    shape = draw(
        st.lists(helpers.ints(min_value=1, max_value=5), min_size=2, max_size=4)
    )
    rank = []
    for dim in shape:
        rank.append(draw(helpers.ints(min_value=1, max_value=dim)))
    dtype = draw(helpers.get_dtypes("float", full=False))
    full = draw(st.booleans())
    orthogonal = draw(st.booleans())
    seed = draw(st.one_of((st.just(None), helpers.ints(min_value=0, max_value=2000))))
    non_negative = draw(st.booleans())
    return shape, rank, dtype[0], full, orthogonal, seed, non_negative

@handle_test(
    fn_tree="functional.ivy.experimental.random_tucker",
    data=_random_tucker_data(),
    test_with_out=st.just(False),
    test_instance_method=st.just(False),
)
def test_random_tucker(
    *,
    data,
    test_flags,
    backend_fw,
    fn_name,
    on_device,
):
    shape, rank, dtype, full, orthogonal, seed, non_negative = data
    results = helpers.test_function(
        input_dtypes=[],
        backend_to_test=backend_fw,
        test_flags=test_flags,
        on_device=on_device,
        fn_name=fn_name,
        shape=shape,
        rank=rank,
        dtype=dtype,
        full=full,
        orthogonal=orthogonal,
        seed=seed,
        non_negative=non_negative,
        test_values=False,
    )

    ret_np, ret_from_gt_np = results

    if full:
        reconstructed_tensor = helpers.flatten_and_to_np(ret=ret_np, backend=backend_fw)
        reconstructed_tensor_gt = helpers.flatten_and_to_np(
            ret=ret_from_gt_np, backend=test_flags.ground_truth_backend
        )
        for x, x_gt in zip(reconstructed_tensor, reconstructed_tensor_gt):
            assert np.prod(shape) == np.prod(x.shape)
            assert np.prod(shape) == np.prod(x_gt.shape)

    else:
        core = helpers.flatten_and_to_np(ret=ret_np[0], backend=backend_fw)
        factors = helpers.flatten_and_to_np(ret=ret_np[1], backend=backend_fw)
        core_gt = helpers.flatten_and_to_np(
            ret=ret_from_gt_np[0], backend=test_flags.ground_truth_backend
        )
        factors_gt = helpers.flatten_and_to_np(
            ret=ret_from_gt_np[1], backend=test_flags.ground_truth_backend
        )

        for c, c_gt in zip(core, core_gt):
            assert np.prod(c.shape) == np.prod(rank)
            assert np.prod(c_gt.shape) == np.prod(rank)

        for f, f_gt in zip(factors, factors_gt):
            assert np.prod(f.shape) == np.prod(f_gt.shape)


'''
Paramecium counter

check this
https://github.com/opencv/opencv_attic/blob/master/opencv/samples/cpp/fitellipse.cpp
https://stackoverflow.com/questions/42206042/ellipse-detection-in-opencv-python
http://docs.opencv.org/3.1.0/dd/d49/tutorial_py_contour_features.html
'''
import matplotlib.pyplot as plt
from skimage import data, color, img_as_ubyte
from skimage.io import imread
from skimage.feature import canny
from skimage.transform import hough_ellipse
from skimage.draw import ellipse_perimeter

filename = "/Users/Romain/Dropbox/Projects/New computational neuroscience/Biological models/Paramecium/Experiments/paramecie in drop on agar.jpg"

img = imread(filename)
image_gray = imread(filename, as_grey = True)
edges = canny(image_gray, sigma=2.0,low_threshold=0.55, high_threshold=0.8)

result = hough_ellipse(edges, accuracy=20, threshold=250,min_size=100, max_size=120)
result.sort(order='accumulator')

# Estimated parameters for the ellipse
best = list(result[-1])
yc, xc, a, b = [int(round(x)) for x in best[1:5]]
orientation = best[5]

# Draw the ellipse on the original image
cy, cx = ellipse_perimeter(yc, xc, a, b, orientation)
img[cy, cx] = (0, 0, 255)
# Draw the edge (white) and the resulting ellipse (red)
edges = color.gray2rgb(img_as_ubyte(edges))
edges[cy, cx] = (250, 0, 0)

fig2, (ax1, ax2) = plt.subplots(ncols=2, nrows=1, figsize=(8, 4), sharex=True,
                                sharey=True,
                                subplot_kw={'adjustable':'box-forced'})

ax1.set_title('Original picture')
ax1.imshow(img)

ax2.set_title('Edge (white) and result (red)')
ax2.imshow(edges)

#img = cv2.medianBlur(img,11)
#edges = cv2.Canny(img,10,80)
#th = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,15,2)
#contours, hierarchy = cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#cv2.drawContours(edges,contours,0,(0,0,255))

#plt.imshow(img, cmap='gray')
#plt.axis('off')
ax2.show()

#cv2.imshow('Image', img)
#cv2.waitKey(0)
#cv2.destroyAllWindows()


# coding=utf-8
import os
import re
import logging.handlers
from threading import Lock

"""
日志模块
理论这个地方应该是独立的
不与任何地方依赖的
"""
def _get_logger(logger_name, log_level):
    logger = logging.getLogger(logger_name)
    logger.setLevel(log_level)
    return logger

def __str_list_compose(str_list, sep_character='', end_index=None):
    result = ""
    if end_index is None:
        end_index = len(str_list) - 1
    else:
        if 0 > end_index or end_index == len(str_list):
            raise Exception("Invalid end index %s when compose" % end_index)
    for index, str_element in enumerate(str_list):
        if index > end_index:
            return result
        if str_element is None or len(str_element) == 0:
            continue
        if result == "":
            result = str_element
            continue
        result = result + sep_character + str_element
    return result

def _get_absolute_path_parent_path(path):
    """
    获取绝对路径的的父路径
    :param path:
    :return:
    """
    # 检测 '/' 和 非法路径
    if len(path) < 2:
        raise Exception("Can't get parent path by path '%s'" % path)
    # 获取路径层级
    path_list = path.split(os.sep)
    path_list_length = len(path_list)
    # 拼接路径
    return os.sep + __str_list_compose(path_list, os.sep, path_list_length - 2)

class PLog(object):
    # 打印日志级别
    _STREAM_HANDLER_LEVEL = logging.INFO
    # 文件日志级别
    _FILE_HANDLER_LEVEL = None
    # 上一次打印的日志是否为系统日志 是的话会在业务日志前增加换行符
    _LAST_LOG_IS_SYSTEM_LOG = None

    # 保证日志顺序绝对一致且分散所使用的锁
    _FORCE_ORDER_LOG_LOCK = Lock()

    _LOGGER = _get_logger("PAVA_LOGGER", logging.DEBUG)

    _STREAM_HANDLER = logging.StreamHandler()
    # 默认打印日志级别
    _STREAM_HANDLER.setLevel(_STREAM_HANDLER_LEVEL)
    _STREAM_HANDLER.setFormatter(logging.Formatter(
        "[%(asctime)s] [%(process)d] [%(levelname)s] [%(module)s.%(funcName)s] [%(filename)s:%(lineno)d] - %("
        "message)s"
    ))
    _LOGGER.addHandler(_STREAM_HANDLER)

    # 如果开启文件日志 则 _FILE_HANDLER 是其对应的 Handler
    _FILE_HANDLER = None

    # 业务日志分割器
    _BUSINESS_LOGGER = _get_logger("PAVA_LOGGER_BUSINESS", logging.INFO)
    _BUSINESS_STREAM_HANDLER = logging.StreamHandler()
    _BUSINESS_STREAM_HANDLER.setLevel(logging.INFO)
    _BUSINESS_STREAM_HANDLER.setFormatter(logging.Formatter("%(message)s"))
    _BUSINESS_LOGGER.addHandler(_BUSINESS_STREAM_HANDLER)

    # 在 Web App 的情况下禁用 RootLogger 防止二次输出
    _LOGGER.propagate = False
    _BUSINESS_LOGGER.propagate = False

    @classmethod
    def add_file_handler(cls, file_path, backup_count=2):
        parent_file_path = _get_absolute_path_parent_path(file_path)
        if not os.path.exists(parent_file_path):
            os.makedirs(parent_file_path)

        file_handler = logging.handlers.TimedRotatingFileHandler(
            filename=file_path,
            when="MIDNIGHT",
            interval=1,
            backupCount=backup_count,
        )

        # 设置日志级别
        file_logger_handler_level = logging.INFO
        cls._FILE_HANDLER_LEVEL = file_logger_handler_level
        file_handler.setLevel(file_logger_handler_level)

        # 日志文件格式
        file_handler.suffix = "%Y-%m-%d.log"
        file_handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}.log$")
        file_handler.setFormatter(
            logging.Formatter(
                "[%(asctime)s] [%(process)d] [%(levelname)s] [%(module)s.%(funcName)s] [%(filename)s:%(lineno)d] - %("
                "message)s "
            )
        )

        business_file_handler = logging.handlers.TimedRotatingFileHandler(
            filename=file_path,
            when="MIDNIGHT",
            interval=1,
            backupCount=backup_count,
        )
        business_file_handler.setLevel(logging.INFO)
        business_file_handler.suffix = "%Y-%m-%d.log"
        business_file_handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}.log$")
        business_file_handler.setFormatter(logging.Formatter("%(message)s"))
        cls._BUSINESS_LOGGER.addHandler(business_file_handler)

        cls._LOGGER.addHandler(file_handler)
        cls._FILE_HANDLER = file_handler

    @classmethod
    def set_print_logger_level(cls, print_logger_level):
        cls._STREAM_HANDLER_LEVEL = print_logger_level
        cls._STREAM_HANDLER.setLevel(print_logger_level)
        cls._BUSINESS_STREAM_HANDLER.setLevel(print_logger_level)

    @classmethod
    def set_file_logger_level(cls, file_logger_level):
        if cls._FILE_HANDLER is None:
            raise Exception("[PLog] File handler is None, must do add_file_handler() before set_file_logger_level()")
        cls._FILE_HANDLER.setLevel(file_logger_level)
        cls._FILE_HANDLER_LEVEL = file_logger_level

    @classmethod
    def log_level_is_debug(cls):
        return logging.DEBUG == cls._STREAM_HANDLER_LEVEL or logging.DEBUG == int(cls._FILE_HANDLER_LEVEL)

    @classmethod
    def log_level_is_info(cls):
        return logging.INFO >= cls._STREAM_HANDLER_LEVEL or logging.INFO >= int(cls._FILE_HANDLER_LEVEL)

    @classmethod
    def gets(cls):
        """
        打印 系统级别 (或中间件级别) 日志
        :return:
        """
        # 将 业务日志 与 中间件日志 分开
        if cls._LAST_LOG_IS_SYSTEM_LOG is not None and not cls._LAST_LOG_IS_SYSTEM_LOG and cls.log_level_is_info():
            cls._BUSINESS_LOGGER.info("")
        cls._LAST_LOG_IS_SYSTEM_LOG = True
        with PLog._FORCE_ORDER_LOG_LOCK:
            return cls._LOGGER

    @classmethod
    def get(cls):
        """
        打印 业务系统类型日志
        :return:
        """
        # 将 业务日志 与 中间件日志 分开
        if cls._LAST_LOG_IS_SYSTEM_LOG is not None and cls._LAST_LOG_IS_SYSTEM_LOG and cls.log_level_is_info():
            cls._BUSINESS_LOGGER.info("")
        cls._LAST_LOG_IS_SYSTEM_LOG = False
        with PLog._FORCE_ORDER_LOG_LOCK:
            return cls._LOGGER


import sys
sys.path.append(f'/home/nathan-burns/Projects/Sports-Text')
sys.path.append(f'/home/nathan-burns/Projects/Sports-Text/Dodgers')
sys.path.append(f'/Users/nathanburns/Projects/Sports-Text')
sys.path.append(f'/Users/nathanburns/Projects/Sports-Text/Dodgers')

import requests
import datetime
from twilio.rest import Client
import keys

from dodgersMorningModel import DodgersMorningModel
from dodgersMorningText import dodgersMorningText
from MLBTeams import MLBTeams

espnUrl = "http://site.api.espn.com/apis/site/v2/sports/baseball/mlb/teams/" + str(MLBTeams.LosAngelesDodgers.value)
espn = requests.get(espnUrl)
espnData = espn.json()

message = ""

client = Client(keys.account_sid, keys.auth_token)

if espn.status_code == 200:
    try:
        awayTeam = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][1]["team"]["displayName"]
        homeTeam = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][0]["team"]["displayName"]
        if (awayTeam == "Los Angeles Dodgers"):
            win = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][1]["winner"]
            dodgersScore = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][1]["score"]["displayValue"]
            oponentScore = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][0]["score"]["displayValue"]
        else:
            win = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][0]["winner"]
            dodgersScore = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][0]["score"]["displayValue"]
            oponentScore = espnData["team"]["nextEvent"][0]["competitions"][0]["competitors"][1]["score"]["displayValue"]
        boxScoreLink = espnData["team"]["nextEvent"][0]["links"][4]["href"]
        place = espnData["team"]["standingSummary"]
        record = espnData["team"]["record"]["items"][0]["summary"]

        morningModel = DodgersMorningModel(awayTeam, homeTeam, win, dodgersScore, oponentScore, boxScoreLink, place, record)
        morningText = dodgersMorningText(morningModel)
        message = morningText.MorningText()
        print(morningText.message)
    except:
        morningText = dodgersMorningText()
        message = morningText.MorningTextNoGame()
        print(morningText.message)

message = client.messages.create(
    body=message,
    to=keys.target_number,
    from_=keys.twilio_number,
)

print(message.body)


from devices import *
from serial import SerialException

__all__ = ['init_device']

def init_device(devtype, armdev):
    """
    Initialization of microscope and arm
    :param devtype: controller
    :param armdev: devices controlling the arm
    :return:
    """

    if devtype == 'SM5':
        try:
            dev = LuigsNeumann_SM5('COM3')
            devmic = Leica()
            microscope = XYMicUnit(dev, devmic, [7, 8])
        except:
            raise SerialException("L&N SM-5 not found.")
    elif devtype == 'SM10':
        try:
            dev = LuigsNeumann_SM10()
            microscope = XYZUnit(dev, [7, 8, 9])
        except SerialException:
            raise SerialException("L&N SM-10 not found.")
    else:
        raise SerialException("No supported device detected")

    if armdev == 'dev1':
        arm = XYZUnit(dev, [1, 2, 3])
    elif armdev == 'dev2':
        arm = XYZUnit(dev, [4, 5, 6])
    elif armdev == 'Arduino':
        try:
            # arduino = appel classe manipulateur arduino
            #arm = XYZUnit(arduino, [1, 2, 3])
            arm = 0
        except SerialException:
            raise SerialException("Arduino not found.")
    else:
        raise NameError('Unknown device for arm control.')

    # Adjust ramp length for accuracy
    microscope.set_ramp_length([0, 1, 2], 3)
    arm.set_ramp_length([0, 1, 2], 3)

    return dev, microscope, arm


# (c) Nelen & Schuurmans.  GPL licensed, see LICENSE.rst.
# -*- coding: utf-8 -*-
"""
Popup info rendering
--------------------

A WMS source has FeatureLines. Clicking on the map opens a popup that shows
all the lines from the WMS GetFeatureInfo call. Every line can be configured
to be rendered in a certain way. This module contains the various renderers.

"""
from __future__ import unicode_literals
from __future__ import print_function
import datetime
import json
import logging

from django.utils.translation import ugettext_lazy as _
# ^^^ Note: the lasy ugettext as choices() is used in a model.
from django.utils.safestring import mark_safe

from lizard_wms.chart import google_column_chart_url

# Keep these constants in the order of their value.
# They need to be one character long, btw.
RENDER_TWO_DECIMALS = 'A'
RENDER_INTEGER = 'B'
RENDER_GC_COLUMN = 'C'
RENDER_IMAGE = 'I'
RENDER_IMAGE_FULLWIDTH = 'J'
RENDER_URL_MORE_LINK = 'M'
RENDER_TEXT = 'T'
RENDER_URL = 'U'
RENDER_URL_LIKE = 'W'
RENDER_XLS_DATE = 'X'

#: The default renderer for a popup item: as text.
DEFAULT_RENDERER = RENDER_TEXT

#: Choices for popup rendering: every FeatureLine can choose how it wants to be
#: displayed.
POPUP_RENDER_CHOICES = (
    (RENDER_TEXT, _("Text")),
    (RENDER_IMAGE, _("Link to an image")),
    (RENDER_IMAGE_FULLWIDTH, _("Link to an image, full table width")),
    (RENDER_INTEGER, _("Integer")),
    (RENDER_TWO_DECIMALS, _("Float with two decimals")),
    (RENDER_XLS_DATE, _("Excel date format")),
    (RENDER_URL, _("URL")),
    (RENDER_URL_LIKE, _("URL-like text")),
    (RENDER_URL_MORE_LINK, _("URL shown as 'click here' link")),
    (RENDER_GC_COLUMN, _("Google column chart")),
    )

LINK_TEMPLATE = '''
%(link_text)s
'''

logger = logging.getLogger(__name__)

def choices():
    """Return choices for the FeatureLine model.

    See :ref:`popup-choices` for the available choices.
    """
    return POPUP_RENDER_CHOICES

def xls_date_to_string(xldate):
    """Return iso-formatted date from an excel float date.

    The method is adapted from http://stackoverflow.com/a/1112664/27401 with
    the assumption that it is a 1900-based date instead of a 1904 one...

    """
    dt = datetime.datetime(1899, 12, 30) + datetime.timedelta(days=xldate)
    return dt.isoformat()[:10]  # Yes, this can be formatted more nicely.

def popup_info(feature_line, value):
    """Return dict with info for the WMS popup.

    It should return a dict with three items:

    - **label_on_separate_line**: the output is normally a two-column
      table. When this option is set to True, the label is printed on a line
      of its own with the value on a whole line of its own, below. Used for
      big google graphs.

    - **label**: the label. Shown in the first column.

    - **value**: the value to show. Use ``mark_safe()`` when returning a bunch
      of html. Note that we do some html rendering here ourselves instead of
      in the template as we know which rendering methods to use here in this
      file. The template *used* to be littered with exceptions, being tightly
      coupled to the constants in this file. Not anymore.

    The value is rendered based on the ``render_as`` attribute of the
    featureline. See :ref:`popup-choices` for the available choices.

    """
    render_as = feature_line.render_as
    replacement_link_text = None
    label = feature_line.description or feature_line.name
    if render_as in [RENDER_GC_COLUMN, RENDER_IMAGE_FULLWIDTH]:
        label_on_separate_line = True
    else:
        label_on_separate_line = False

    # First some special cases that "convert" themselves to other renderers.
    if render_as == RENDER_GC_COLUMN:
        try:
            json_data = json.loads(value)
            if json_data is None:
                # See https://github.com/nens/deltaportaal/issues/4
                logger.warn(
                    "https://github.com/nens/deltaportaal/issues/4 "
                    "hits again")
                raise ValueError("Somehow the json data doesn't exist???")
            value = google_column_chart_url(json_data)
        except (TypeError, ValueError):
            logger.exception(
                "Exception when loading json google chart data")
            value = ''
        if value != '':
            render_as = RENDER_IMAGE
        else:
            render_as = RENDER_TEXT
            value = _("Error converting data to a graph")
    elif render_as == RENDER_XLS_DATE:
        try:
            date_value = float(value)
        except ValueError:
            logger.warn("Not a float-like value for XLS date: %r", value)
            return
        value = xls_date_to_string(date_value)
        render_as = RENDER_TEXT
    elif render_as == RENDER_URL_LIKE:
        # Quite brittle, but equal to the code from the template that it
        # replaces.
        value = 'http://' + value
        render_as = RENDER_URL
    elif render_as == RENDER_URL_MORE_LINK:
        replacement_link_text = _("Click here for more information")
        if not 'http://' in value:
            value = 'http://' + value
            # Yes, this means we could do the same for RENDER_URL_LIKE
            # options, but I'm leaving that one alone for the moment.
        render_as = RENDER_URL
    elif render_as == RENDER_INTEGER:
        try:
            value = float(value)
        except ValueError:
            logger.warn("Not a number-like value: %r", value)
            return
        value = unicode(int(round(value)))
        render_as = RENDER_TEXT
    elif render_as == RENDER_TWO_DECIMALS:
        try:
            value = float(value)
        except ValueError:
            logger.warn("Not a number-like value: %r", value)
            return
        value = '%0.2f' % value
        render_as = RENDER_TEXT

    # OK, now the actual rendering. Only text, url and image renderers are
    # left.
    if render_as == RENDER_TEXT:
        pass  # value is fine.
    elif render_as == RENDER_IMAGE:
        value = mark_safe('' % value)
    elif render_as == RENDER_IMAGE_FULLWIDTH:
        value = mark_safe('' % value)
    elif render_as == RENDER_URL:
        link_text = replacement_link_text or value
        value = mark_safe(LINK_TEMPLATE % {'url': value,
                                           'link_text': link_text})

    return {
        'label': label,
        'label_on_separate_line': label_on_separate_line,
        'value': value,
        }


import logging
import time

import requests

from curie import charon_agent_interface_pb2
from curie.agent_rpc_client import AgentRpcClient
from curie.curie_error_pb2 import CurieError
from curie.exception import CurieException
from curie.util import CurieUtil

log = logging.getLogger(__name__)

class CurieUnixVmMixin(object):
  """
  Mixin providing functionality for Unix VMs hosting CurieUnixAgent.
  """

  def is_accessible(self):
    "See Vm.is_accessible documentation."
    if not self._vm_ip:
      log.debug("VM '%s' (node_id: %r), IP address not set (got: %r)",
                self, self._node_id, self._vm_ip)
      return False
    try:
      # Access a URL served by the curie_unix_agent that the VM should
      # eventually be running.
      url = "http://%s:5001" % self._vm_ip
      resp = requests.head(url, timeout=10)
      # Check that the response code is not an error.
      resp.raise_for_status()
      return True
    except requests.exceptions.RequestException:
      return False

  def path_exists(self, path):
    exit_status, stdout, stderr = self.execute_sync(str(time.time()),
                                                    "ls %s" % path,
                                                    120)
    if exit_status == 0:
      return True
    else:
      return False

  def transfer_to(self,
                  local_path,
                  remote_path,
                  timeout_secs,
                  recursive=False):
    """See Vm.transfer_to documentation.
    """
    result = self._scp_client.transfer_to(local_path,
                                          remote_path,
                                          timeout_secs,
                                          recursive=recursive)
    if result:
      log.debug("Transferred %s to %s:%s", local_path, self, remote_path)
    else:
      log.error("Failed to transfer %s to %s:%s",
                local_path, self, remote_path)
    return result

  def transfer_from(self,
                    remote_path,
                    local_path,
                    timeout_secs,
                    recursive=False):
    """See Vm.transfer_from documentation.
    """
    if not recursive:
      # If we're fetching a single file, use a FileGet RPC which is much faster
      # than forking and running scp.
      rpc_client = AgentRpcClient(self._vm_ip)
      arg = charon_agent_interface_pb2.FileGetArg()
      arg.path = remote_path
      try:
        ret, err = rpc_client.FileGet(arg)
      except CurieException as ex:
        log.debug("Caught CurieException during FileGet")
        ret, err = None, ex.error_msg
      if err is not None:
        log.exception("Error fetching file %s from %s",
                      remote_path, self._vm_ip)
        result = False
      else:
        open(local_path, "w").write(ret.data)
        result = True
    else:
      result = self._scp_client.transfer_from(remote_path,
                                              local_path,
                                              timeout_secs,
                                              recursive=recursive)
    if result:
      log.debug("Transferred %s from %s:%s", local_path, self, remote_path)
    else:
      log.error("Failed to transfer %s from %s:%s",
                local_path, self, remote_path)
    return result

  def execute_async(self, cmd_id, cmd, user="nutanix"):
    "See Vm.execute_async documentation."
    rpc_client = AgentRpcClient(self._vm_ip)
    arg = charon_agent_interface_pb2.CmdExecuteArg()
    arg.user = user
    arg.cmd_id = cmd_id
    arg.cmd = cmd
    log.debug("%s executing async command: %s", self, cmd)
    ret, err = rpc_client.CmdExecute(arg)
    if err is not None:
      raise CurieException(err.error_codes[0],
                            "Command %s (%s) failed, err %s" %
                            (cmd, cmd_id, err))

  def execute_sync(self,
                   cmd_id,
                   cmd,
                   timeout_secs,
                   user="nutanix",
                   include_output=False):
    "See Vm.execute_sync documentation."
    rpc_client = AgentRpcClient(self._vm_ip)
    arg = charon_agent_interface_pb2.CmdExecuteArg()
    arg.user = user
    arg.cmd_id = cmd_id
    arg.cmd = cmd
    log.debug("%s executing synchronous command: %s", self, cmd)
    exit_status, stdout, stderr = \
      rpc_client.cmd_execute_sync(arg,
                                  timeout_secs,
                                  include_output=include_output)
    if exit_status != 0:
      raise CurieException(CurieError.kInternalError,
                            "Command %s (%s) failed, exit_status %d, %s, %s" %
                            (cmd, cmd_id, exit_status, stdout, stderr))
    return (exit_status, stdout, stderr)

  def stop_cmd(self, cmd_id):
    """Stop a command running on this VM.

    The command specified by cmd_id must already be running.

    Args:
      cmd_id: (str) ID of the command to stop.

    Raises:
      CurieException: If stopping the command fails.
    """
    rpc_client = AgentRpcClient(self._vm_ip)
    arg = charon_agent_interface_pb2.CmdStopArg()
    arg.cmd_id = cmd_id
    log.debug("Stopping command with id: %s", cmd_id)
    ret, err = rpc_client.CmdStop(arg)
    if err is not None:
      raise CurieException(CurieError.kInternalError,
                            "Stopping command with id '%s' failed: %s" %
                            (cmd_id, err))


from PIL import Image
import numpy
im = Image.open('test.jpg')

iterations = 10
adjustment = 50

for i in range(0, iterations):
    pix = im.load()
    im2 = im.copy()
    im3 = im.copy()
    size = im.size

    #Calculating the Energy of Each Pixel: Result = im2
    for x in range(0, im.size[0]):
        for y in range(0, im.size[1]):
            pixel1 = pix[x,y]
            if y == 0:
                sumupvalue = 0
            else:
                pixelup = pix[x,y - 1]
                upvalueR = abs(pixel1[0] - pixelup[0])
                upvalueG = abs(pixel1[1] - pixelup[1])
                upvalueB = abs(pixel1[2] - pixelup[2])
                sumupvalue = upvalueR + upvalueG + upvalueB
            if y == size[1] - 1:
                sumdownvalue = 0
            else:
                pixeldown = pix[x, y + 1]
                downvalueR = abs(pixel1[0] - pixeldown[0])
                downvalueG = abs(pixel1[1] - pixeldown[1])
                downvalueB = abs(pixel1[2] - pixeldown[2])
                sumdownvalue = downvalueR + downvalueG + downvalueB
            if x == 0:
                sumleftvalue = 0
            else:
                pixelleft = pix[x - 1, y]
                leftvalueR = abs(pixel1[0] - pixelleft[0])
                leftvalueG = abs(pixel1[1] - pixelleft[1])
                leftvalueB = abs(pixel1[2] - pixelleft[2])
                sumleftvalue = leftvalueR + leftvalueG + leftvalueB
            if x == size[0] - 1:
                sumrightvalue = 0
            else:
                pixelright = pix[x + 1, y]
                rightvalueR = abs(pixel1[0] - pixelright[0])
                rightvalueG = abs(pixel1[1] - pixelright[1])
                rightvalueB = abs(pixel1[2] - pixelright[2])
                sumrightvalue = rightvalueR + rightvalueG + rightvalueB
            pixelenergy = sumupvalue + sumdownvalue + sumleftvalue + sumrightvalue
            im2.putpixel((x, y), (0, 0, int((pixelenergy)/adjustment)))

    #Bottom Row Starting Cumulative Energy
    pix2 = im2.load()
    pix3 = im3.load()
    for x2 in range(0, im.size[0]):
        pe2 = pix2[x2, im.size[1]-1]
        initial = pe2[2]
        im3.putpixel((x2, im.size[1]-1), (initial, 0 , 0))
    #Rest of the Image Cumulative Energy: Result = im3
    for y3 in reversed(range(0, im.size[1] - 1)):
        for x3 in range(0, im.size[0]):
            pe3 = pix2[x3, y3]
            if x3 == 0:
                pe3below_middle = pix3[x3, y3 + 1]
                pe3below_right = pix3[x3 + 1, y3 + 1]
                p2me = pe3below_middle[0]
                p2re = pe3below_right[0]
                choice = [p2me, p2re]
                decision = min(choice)
            elif x3 == im.size[0] - 1:
                pe3below_left = pix3[x3 - 1, y3 + 1]
                pe3below_middle = pix3[x3, y3 + 1]
                p2me = pe3below_middle[0]
                p2re = pe3below_right[0]
                choice = [p2me, p2re]
                decision = min(choice)
            else:
                pe3below_left = pix3[x3 - 1, y3 + 1]
                pe3below_middle = pix3[x3, y3 + 1]
                pe3below_right = pix3[x3 + 1, y3 + 1]
                p2le = pe3below_left[0]
                p2me = pe3below_middle[0]
                p2re = pe3below_right[0]
                choice = [p2le, p2me, p2re]
                decision = min(choice)
            cumulative3 = ((pe3[2] + decision))
            im3.putpixel((x3, y3), (int(cumulative3), 0, 0))

    #Finding Starting Point to Remove Slice
    im5 = im3.copy()
    startval = []
    for x4 in range(0, im.size[0]):
        pe4 = pix3[x4, 0]
        startval.append(pe4[0])
    xstart = min(startval)
    route = []
    while True:
        for x4 in range(0, im.size[0]):
            pe4 = pix3[x4, 0]
            if  pe4[0] != xstart:
                continue
            else:
                startco_ord = x4
                break
        break
    #Finding Actual Slice to Remove: Result = im5
    for y5 in range(0, im.size[1]):
            if y5 == im.size[1] - 1:
                im5.putpixel((startco_ord, y5), (0, 100, 0))
                route.append(startco_ord)
            else:
                if startco_ord == 0:
                    pe5below_middle = pix3[startco_ord, y5 + 1]
                    pe5below_right = pix3[startco_ord + 1, y5 + 1]
                    p5me = pe5below_middle[0]
                    p5re = pe5below_right[0]
                    p5le = -1
                    choice2 = [p5me, p5re]
                    decision2 = min(choice2)

                elif startco_ord == im.size[0] - 1:
                    pe5below_left = pix3[startco_ord - 1, y5 + 1]
                    pe5below_middle = pix3[startco_ord, y5 + 1]
                    p5le = pe5below_left[0]
                    p5me = pe5below_middle[0]
                    p5re = -1
                    choice2 = [p5me, p5le]
                    decision2 = min(choice2)

                else:
                    pe5below_left = pix3[startco_ord - 1, y5 + 1]
                    pe5below_middle = pix3[startco_ord, y5 + 1]
                    pe5below_right = pix3[startco_ord + 1, y5 + 1]
                    p5le = pe5below_left[0]
                    p5me = pe5below_middle[0]
                    p5re = pe5below_right[0]
                    choice2 = [p5me, p5re, p5le]
                    decision2 = min(choice2)

                im5.putpixel((startco_ord, y5), (0, 100, 0))
                if decision2 == p5me:
                    startco_ord = startco_ord
                    route.append(startco_ord)
                elif decision2 == p5le:
                    startco_ord = startco_ord - 1
                    route.append(startco_ord)
                elif decision2 == p5re:
                    startco_ord = startco_ord + 1
                    route.append(startco_ord)
    im5.show()

    #Editing Original Image: Result = im
    for y8 in range(0, im.size[1]):
        for x8 in range(0, im.size[0]):
            if x8 == im.size[0] - 1:
                im.putpixel((x8, y8), (0, 100, 0))
            elif x8 > route[y8]:
                shift = pix[x8 + 1, y8]
                im.putpixel((x8, y8), shift)
            elif x8 < route[y8]:
                continue

    a = numpy.array(im)
    b = numpy.delete(a, -1, axis=1)
    im = Image.fromarray(b)

im.show()


"""
微博爬虫，输入某关键字就爬取对应用户
将微博名，关注数，粉丝数，微博数提取
bs4方式爬取
"""
import requests
import csv,codecs
from bs4 import BeautifulSoup

class MovieSpider(object):

    def __init__(self):
        self.url='https://s.weibo.com/user?q=健康&Refer=weibo_user&page={}'
        self.headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
        }
        self.li=[]

    def get_page_from_url(self,url):
        """
        提取url
        :param url:
        :return:
        """
        html = requests.get(url, headers=self.headers).content
        return html

    def get_data_from_page(self,page):
        """
        提取数据
        :param page:
        :return:
        """
        data_list=[]
        soup = BeautifulSoup(page, 'html.parser')
        list_info = soup.find_all(class_="info")
        # item['wbname'] = wbname
        for list in list_info:
            # print(list)
            # 格式都是字符串
            item={}
            item['wbname'] = list.find(class_="name").text
            item['focus'] = list.select('span')[0].a.get_text()
            item['follow'] = list.select('span')[1].a.get_text()
            item['weibo'] = list.select('span')[2].a.get_text()
            data_list.append(item)
        print('data_list',data_list)
        return data_list

    def save_data(self,data_list):
        """
        保存数据
        :param data_list:
        :return:
        """
        for data in data_list:
            # print(data)
            f = open('weibo.csv','w',encoding='utf-8-sig')
            writer = csv.writer(f)
            # 将微博名，关注数，粉丝数，微博数提取，转成写入格式
            wbname=data['wbname']
            follow=data['follow']
            focus=data['focus']
            weibo=data['weibo']

            # print('follow:',follow) # 是一个个字符串
            t = (wbname,focus,follow,weibo)
            self.li.append(t)
            # 列表格式 ：[('xxx',), ('xxx',)]
            # print('list:',self.li)
            # writerows保存多行，格式是[('xxx',), ('xxxx',)] writerow保存单行，格式['a','b']
            writer.writerows([['微博名','关注数','粉丝数','微博数']])
            writer.writerows(self.li)

    def run(self):
        for i in range(1, 50):
            # 获取url
            url=self.url.format(i)
            # 解析url
            page = self.get_page_from_url(url)
            # 获取数据
            data_list = self.get_data_from_page(page)
            # 保存数据为csv
            self.save_data(data_list)

if __name__ == '__main__':

    mm = MovieSpider()
    mm.run()


from dataset import get_dataset
import torch.utils.data
import torch
import torchvision.transforms.functional as TF
import network_new
import os

join = os.path.join
from PIL import Image

def show_result(G, x_):
    G.eval()
    G.cpu()
    x_ = x_.cpu()
    test_images = G(x_)

    for i in range(x_.shape[0]):
        # img_np = (test_images[i].cpu().data.numpy().transpose(1, 2, 0) + 1) / 2
        # img = Image.fromarray(img_np)
        img = TF.to_pil_image(test_images[i])
        img.save('./save{:0>4}.png'.format(i))
        img.show()

pixel_set = get_dataset('new_data/train/pixel', 256)
photo_set = get_dataset('new_data/train/photo', 256)

fixed_xs = []
for i in range(6):
    fixed_xs.append(photo_set[i].unsqueeze(0))
fixed_x_ = torch.cat(fixed_xs, dim=0)

filter_count = 64
G = network_new.generator(d=filter_count)

stat_dict = torch.load('./generator_param1.pkl')
G.load_state_dict(stat_dict)

show_result(G, fixed_x_)


import discord
import requests
from discord.ext import commands
from discord.ext import tasks
from tinydb import TinyDB, Query
from getGEXP import storeGEXP, getPlayerGEXPMessage, getWeeklyGEXPTopMessage, getDailyGEXPTopMessage
from infoCommand import getGuildInfoMessage

token = 'BOT_TOKEN'
apiKey = 'API_KEY'
cmdPrefix = '$'
bot = commands.Bot(command_prefix=cmdPrefix)
bot.remove_command('help')
dataDB = TinyDB('dataDB.json')
noName = discord.Embed(title='No Name Provided', description='Please provide a username after the command, or link your Discord user ID with your Minecraft name with the command **link**.', color=11141120
                       ).set_footer(text='Krypton Bot made by Yuushi#5964')

@bot.event
async def on_ready():
    await bot.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.watching, name="your GEXP | $help"))
    getEXP.start()
    setRoles.start()
    print('Krypton Bot is ready.')

@tasks.loop(minutes=15)
async def getEXP():
    clearDB()
    storeGEXP()
    guild = bot.get_guild(714335785469345793)
    unlinkRole = discord.utils.get(guild.roles, name='Unlinked')
    linkRole = discord.utils.get(guild.roles, name='Linked')
    botRole = discord.utils.get(guild.roles, name='Bots')
    for member in guild.members:
        if botRole in member.roles:
            pass
        elif not dataDB.get(Query()['userID'] == member.id):
            await member.add_roles(unlinkRole)
            await member.remove_roles(linkRole)
        else:
            await member.add_roles(linkRole)
            await member.remove_roles(unlinkRole)

# @tasks.loop(hours=1)
# async def remindLink():
#    guild = bot.get_guild(714335785469345793)
#    unlinkRole = discord.utils.get(guild.roles, name='Unlinked')
#    unlink_channel = bot.get_channel(728366357455962153)
#    await unlink_channel.send(content='<@&' + str(unlinkRole.id) + '>')
#    await unlink_channel.send(embed=discord.Embed(title='Link your Account', description='Please make sure to link your Minecraft username with your Discord account so that your guild role can be updated automatically. You can do so by going into the <#714643693738655804> channel and typing `$link <ign>`.',
#                                                  color=11141120).set_footer(text='Krypton Bot made by Yuushi#5964'))

@tasks.loop(minutes=15)
async def setRoles():
    guild = bot.get_guild(714335785469345793)
    bot_channel = bot.get_channel(728296239518580846)
    for member in guild.members:
        if dataDB.get(Query()['userID'] == member.id):
            search = dataDB.get(Query()['userID'] == member.id)
            weeklyEXP = search.get('weeklyEXP')
            if 0 <= weeklyEXP < 100000:
                rank = 'Initiate'
            elif 100000 <= weeklyEXP < 200000:
                rank = 'Experienced'
            else:
                rank = 'Krypt Gods'
            role = discord.utils.get(guild.roles, name=rank)
            if role not in member.roles:
                await delete_role(member, rank, guild)
                await member.add_roles(role)
                await bot_channel.send('<@' + str(member.id) + '>', embed=discord.Embed(title=':diamond_shape_with_a_dot_inside: You\'re shining!', description='Your rank has been changed to **' + rank + '** because of the total of Guild Experience you earned this week. \n **Total Weekly GEXP**: ' + format(weeklyEXP,
                                                                                ',d') + ' exp',
                                                                                color=43520).set_footer(text='Krypton Bot made by Yuushi#5964'))

async def delete_role(member, rank, guild):
    if rank == 'Krypt Gods':
        await member.remove_roles(discord.utils.get(guild.roles, name='Initiate'), discord.utils.get(guild.roles, name='Experienced'))
    elif rank == 'Experienced':
        await member.remove_roles(discord.utils.get(guild.roles, name='Initiate'), discord.utils.get(guild.roles, name='Krypt Gods'))
    elif rank == 'Initiate':
        await member.remove_roles(discord.utils.get(guild.roles, name='Experienced'), discord.utils.get(guild.roles, name='Krypt Gods'))

def getName(ctx):
    userID = ctx.message.author.id
    if dataDB.get(Query()['userID'] == userID):
        search = dataDB.get(Query()['userID'] == userID)
        uuid = search.get('uuid')
        return uuid
    else:
        return None

def clearDB():
    guildData = requests.get('https://api.hypixel.net/guild?key=' +
                             apiKey + '&id=5ef336138ea8c950b6cb73f2').json()
    apiUUID = []
    for i in range(len(guildData["guild"]["members"])):
        apiUUID.append(guildData["guild"]["members"][i]["uuid"])
    for i in range(len(dataDB)):
        dbUUID = dataDB.all()[i]['uuid']
        if dbUUID not in apiUUID:
            dataDB.remove(Query()['uuid'] == dbUUID)

@bot.command()
async def help(ctx):
    helpMessage = discord.Embed(title='Help Menu', description='`' + cmdPrefix + 'help` + bring up this help menu \n `' + cmdPrefix + 'link <ign>` + link your Discord ID to your Minecraft name (not case sensitive) \n '
                                                               '`' + cmdPrefix + 'info` + get Krypton\'s guild info \n `' +
                                cmdPrefix + 'exp <ign>` + get a member\'s GEXP \n '
                                                               '`' + cmdPrefix + 'daily` + get the daily GEXP leaderboard \n `' + cmdPrefix + 'weekly` + get the weekly GEXP leaderboard')
    helpMessage.set_footer(text='Krypton Bot made by Yuushi#5964')
    await ctx.send(embed=helpMessage)

@bot.command()
async def link(ctx, name=None):
    if name is None:
        await ctx.send(embed=discord.Embed(title='No Username Provided', description='Please provide your Minecraft username to be linked with your Discord user ID.', color=11141120
                                           ).set_footer(text='Krypton Bot made by Yuushi#5964'))
    else:
        userID = ctx.message.author.id
        uuid = requests.get('https://api.mojang.com/users/profiles/minecraft/' + name).json()["id"]
        guildData = requests.get('https://api.hypixel.net/guild?key=' +
                                 apiKey + '&id=5ef336138ea8c950b6cb73f2').json()
        uuidList = []
        for i in range(len(guildData["guild"]["members"])):
            uuidList.append(guildData["guild"]["members"][i]["uuid"])
        if uuid in uuidList:
            guild = bot.get_guild(714335785469345793)
            unlinkRole = discord.utils.get(guild.roles, name='Unlinked')
            linkRole = discord.utils.get(guild.roles, name='Linked')
            memberRole = discord.utils.get(guild.roles, name='Member')
            guestRole = discord.utils.get(guild.roles, name='Guest')
            initiateRole = discord.utils.get(guild.roles, name='Initiate')
            guildMemberRole = discord.utils.get(guild.roles, name='----Guild Member----')
            dataDB.update({'userID': userID}, Query().uuid == uuid)
            await ctx.send(embed=discord.Embed(title='Username Linked',
                                               description='Your Discord user ID has been linked with your Minecraft username, hence your role will automatically be updated depending on your weekly Guild Experience.',
                                               color=43520
                                               ).set_footer(text='Krypton Bot made by Yuushi#5964'))
            member = guild.get_member(userID)
            await member.remove_roles(unlinkRole)
            await member.remove_roles(guestRole)
            await member.add_roles(memberRole)
            await member.add_roles(guildMemberRole)
            await member.add_roles(initiateRole)
            await member.add_roles(linkRole)
        else:
            await ctx.send(embed=discord.Embed(title='Impersonator!',
                                               description='You are not a member of the Krypton\'s guild so you can\'t link your Minecraft name to the guild\'s bot. Don\'t try to impersonate us!',
                                               color=11141120
                                               ).set_footer(text='Krypton Bot made by Yuushi#5964'))

@bot.command()
async def exp(ctx, name=None):
    if name is None:
        uuid = getName(ctx)
        name = requests.get('https://api.hypixel.net/player?key=' + apiKey +
                            '&uuid=' + uuid).json()["player"]["displayname"]
        if name is None:
            await ctx.send(embed=noName)
    if name is not None:
        uuid = requests.get('https://api.mojang.com/users/profiles/minecraft/' + name).json()["id"]
        await ctx.send(embed=getPlayerGEXPMessage(uuid))

@bot.command()
async def daily(ctx):
    await ctx.send(embed=getDailyGEXPTopMessage())

@bot.command()
async def weekly(ctx):
    await ctx.send(embed=getWeeklyGEXPTopMessage())

@bot.command()
async def info(ctx):
    await ctx.send(embed=getGuildInfoMessage())

@bot.command()
async def list(ctx):
    guild = bot.get_guild(714335785469345793)
    unlinkRole = discord.utils.get(guild.roles, name='Unlinked')
    content1 = ''
    content2 = ''
    unlinked_mem = []
    if (ctx.message.author.id == 272553041826414593) or (ctx.message.author.id == 193425484799803395):
        for member in guild.members:
            if unlinkRole in member.roles:
                unlinked_mem.append(member.id)
        for i in range(round(len(unlinked_mem) / 2)):
            content1 = content1 + '`-` <@' + str(unlinked_mem[i]) + '> \n'
        for i in range(round(len(unlinked_mem) / 2), len(unlinked_mem)):
            content2 = content2 + '`-` <@' + str(unlinked_mem[i]) + '> \n'
        unlist = discord.Embed(title='Unlinked Members')
        unlist.add_field(name='List of Unlinked members', value=content1)
        unlist.add_field(name='Total: ' + str(len(unlinked_mem)), value=content2)
        await ctx.message.author.send(embed=unlist)
    else:
        await ctx.send(embed=discord.Embed(title='An error has occured', description='This command is reserved to the guild owner <@' + str(272553041826414593) + '> and to the developer of the bot <@' + str(193425484799803395) + '>.', color=11141120).set_footer(text='Krypton Bot made by Yuushi#5964'))

bot.run(token)


import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton
from PyQt6.QtCore import Qt
from widgets.sensorUI import SensorUI

class HomePage(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Home Page")

        layout = QVBoxLayout()

        sensor_button = QPushButton("Sensor UI")
        sensor_button.clicked.connect(self.open_sensor_ui)
        layout.addWidget(sensor_button)

        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

    def open_sensor_ui(self):
        self.sensor_ui = SensorUI()
        self.sensor_ui.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    home_page = HomePage()
    home_page.show()
    sys.exit(app.exec())


import boto3
from botocore.errorfactory import ClientError
import json
import os

from io import BytesIO
import PIL
from PIL import Image

import csv
from requests import get

class Bucket():
    def __init__(self, prefix, name, suffix):
        self.bucket_name = f'{prefix}{name}{suffix}'

    def __str__(self):
        return self.bucket_name

class ImageAWS():

    def __init__(self, src, bucket_name, path, dst_name):
        response = get(src)
        self.bucket = bucket_name
        self.path = path

        self.image = PIL.Image.open(BytesIO(response.content))
        file_name, self.file_extension = os.path.splitext(src)
        self.dst_name = dst_name

    def path_section(self, suffix):
        self.path_section = suffix

    def save(self, folder, size):
        file_name = self.dst_name + self.file_extension.lower()
        key = f'{self.path}/{folder}{file_name}'

        try:
            s3 = boto3.client('s3')
            objs = s3.head_object(Bucket=self.bucket, Key=key)
        except ClientError:
            dst = boto3.resource('s3')
            bucket = dst.Bucket(self.bucket)

            file_stream = self.image
            fstream = BytesIO()
            file_stream.thumbnail(size)

            if self.file_extension[1:].upper() == 'JPG':
                mime_type = 'JPEG'
            else:
                mime_type = self.file_extension[1:].upper()

            file_stream.save(fstream, mime_type, optimize=True)
            tmp = bucket.Object(key)
            txt = tmp.put(ACL='public-read', Body=fstream.getvalue())

            return txt

def lambda_handler(event, context):
    thumbnail_size = (64, 64)
    small_size = (200, 200)
    default_size = (350, 350)
    large_size = (1000, 1000)

    body = json.loads(event['body'])

    if type(body) is list:
        for img in body:
            bucket = Bucket(img['bucket_prefix'], img['bucket_name'], img['bucket_suffix'])
            product_id = img['product_id']
            path = f'products/{product_id}'
            image = ImageAWS(img['url'], str(bucket), path, img['name'])

            large_rsp = image.save('large/', large_size)
            print("<[RSP]> large ", large_rsp)
            default_rsp = image.save('', default_size)
            print("<[RSP]> default ", default_rsp)
            small_rsp = image.save('small/', small_size)
            print("<[RSP]> small ", small_rsp)
            thumbnail_rsp = image.save('thumbnail/', thumbnail_size)
            print("<[RSP]> thumbnail ", thumbnail_rsp)

        return f"[200]"
    else:
        return "[504]"


"""init

Revision ID: acc8b8a37ccd
Revises:
Create Date: 2021-10-06 08:00:00.000000

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = "acc8b8a37ccd"
down_revision = None
branch_labels = None
depends_on = None

def upgrade():
    op.create_table(
        "offer",
        sa.Column("id", sa.INTEGER(), nullable=True),
        sa.Column("product_id", sa.INTEGER(), nullable=True),
        sa.Column("check_interval", sa.INTEGER(), nullable=True),
        sa.Column("url", sa.VARCHAR(), nullable=False),
        sa.ForeignKeyConstraint(
            ["product_id"],
            ["product.id"],
        ),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("ix_offer_url", "offer", ["url"], unique=False)
    op.create_index("ix_offer_product_id", "offer", ["product_id"], unique=False)
    op.create_index("ix_offer_id", "offer", ["id"], unique=False)
    op.create_index(
        "ix_offer_check_interval", "offer", ["check_interval"], unique=False
    )
    op.create_table(
        "product",
        sa.Column("id", sa.INTEGER(), nullable=True),
        sa.Column("category", sa.VARCHAR(), nullable=False),
        sa.Column("name", sa.VARCHAR(), nullable=False),
        sa.Column("image", sa.VARCHAR(), nullable=True),
        sa.Column("description", sa.VARCHAR(), nullable=True),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("ix_product_name", "product", ["name"], unique=False)
    op.create_index("ix_product_image", "product", ["image"], unique=False)
    op.create_index("ix_product_id", "product", ["id"], unique=False)
    op.create_index("ix_product_description", "product", ["description"], unique=False)
    op.create_index("ix_product_category", "product", ["category"], unique=False)
    op.create_table(
        "history",
        sa.Column("id", sa.INTEGER(), nullable=True),
        sa.Column("offer_id", sa.INTEGER(), nullable=True),
        sa.Column("datetime", sa.INTEGER(), nullable=False),
        sa.Column("availability", sa.INTEGER(), nullable=False),
        sa.Column("price", sa.INTEGER(), nullable=False),
        sa.Column("price_currency", sa.VARCHAR(), nullable=False),
        sa.ForeignKeyConstraint(
            ["offer_id"],
            ["offer.id"],
        ),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        "ix_history_price_currency", "history", ["price_currency"], unique=False
    )
    op.create_index("ix_history_price", "history", ["price"], unique=False)
    op.create_index("ix_history_offer_id", "history", ["offer_id"], unique=False)
    op.create_index("ix_history_id", "history", ["id"], unique=False)
    op.create_index("ix_history_datetime", "history", ["datetime"], unique=False)
    op.create_index(
        "ix_history_availability", "history", ["availability"], unique=False
    )

def downgrade():
    op.drop_index("ix_history_availability", table_name="history")
    op.drop_index("ix_history_datetime", table_name="history")
    op.drop_index("ix_history_id", table_name="history")
    op.drop_index("ix_history_offer_id", table_name="history")
    op.drop_index("ix_history_price", table_name="history")
    op.drop_index("ix_history_price_currency", table_name="history")
    op.drop_table("history")
    op.drop_index("ix_product_category", table_name="product")
    op.drop_index("ix_product_description", table_name="product")
    op.drop_index("ix_product_id", table_name="product")
    op.drop_index("ix_product_image", table_name="product")
    op.drop_index("ix_product_name", table_name="product")
    op.drop_table("product")
    op.drop_index("ix_offer_check_interval", table_name="offer")
    op.drop_index("ix_offer_id", table_name="offer")
    op.drop_index("ix_offer_product_id", table_name="offer")
    op.drop_index("ix_offer_url", table_name="offer")
    op.drop_table("offer")


import json

import argparse
from pathlib import Path

from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split

def _download_data(args):

    x, y = load_boston(return_X_y=True)
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)

    data = {'x_train' : x_train.tolist(),
            'y_train' : y_train.tolist(),
            'x_test' : x_test.tolist(),
            'y_test' : y_test.tolist()}

    data_json = json.dumps(data)

    with open(args.data, 'w') as out_file:
        json.dump(data_json, out_file)

if __name__ == '__main__':

    parser = argparse.ArgumentParser()
    parser.add_argument('--data', type=str)

    args = parser.parse_args()

    Path(args.data).parent.mkdir(parents=True, exist_ok=True)

    _download_data(args)


#!/usr/bin/python
import pyowm
import datetime
from Settings import Settings

#fetch user settings using the Settings class
settings_file = Settings()
API_KEY = settings_file.api_key
lat = settings_file.latitude
lon = settings_file.longitude
owm = pyowm.OWM(API_KEY)

class Weather(object):
    def __init__(self, api_weather_details=None):
        self.hours_after_sunrise_to_full_brightness = settings_file.hours_after_sunrise_to_full_brightness
        self.hours_before_sunset_to_start_dimmer = settings_file.hours_before_sunset_to_start_dimmer

        if api_weather_details:
            ## See https://github.com/csparpa/pyowm/blob/master/pyowm/docs/usage-examples.md for pyowm details
            ##
            ## For future weather alerts
            ## weather_condition = w.get_detailed_status()

            self.weather_condition = api_weather_details.get_status()

            ## Get temperature data
            temperature_data = api_weather_details.get_temperature("fahrenheit")
            self.min_temperature = int(temperature_data["temp_min"])
            self.max_temperature = int(temperature_data["temp_max"])
            self.current_temperature = int(temperature_data["temp"])

            ## Get sunrise hour and minute
            sunrise_time = api_weather_details.get_sunrise_time()
            self.sunrise_hour = self.getUsableTime(sunrise_time, '%H')
            self.sunrise_minute = self.getUsableTime(sunrise_time, '%M')

            ## Get sunset hour and minute
            sunset_time = api_weather_details.get_sunset_time()
            self.sunset_hour = self.getUsableTime(sunset_time, '%H')
            self.sunset_minute = self.getUsableTime(sunset_time, '%M')

            self.good_weather_fetch = True

        else:
            self.weather_condition = "N/A"
            self.current_temperature = 0
            self.sunrise_hour = settings_file.default_sunrise_hour
            self.sunrise_minute = settings_file.default_sunrise_minute
            self.sunset_hour = settings_file.default_sunset_hour
            self.sunset_minute = settings_file.default_sunset_minute

            self.good_weather_fetch = False

    def getUsableTime(self, time, unit):
        usable_time = datetime.datetime.fromtimestamp(int(time)).strftime(unit)
        return int(usable_time)

def getWeatherData(call_api=True):
    if call_api:
        try:
            ## Call the API
            weather_details = owm.weather_at_coords(lat, lon)
            weather = Weather(weather_details.get_weather())

        except:
            weather = Weather()
    else:
        weather = Weather()

    return weather


from django import forms
from Vacunation_app.forms.p import PForm
from Vacunation_app.models import Vacunacion

class NoTurnForm(PForm,forms.ModelForm):

    dni = forms.CharField(label='',
            widget=forms.TextInput(attrs={'placeholder': 'DNI'}))

    email = forms.EmailField(
        label=(""),
        max_length=254,
        widget=forms.EmailInput(attrs={"autocomplete": "email",'placeholder':"Email"}),
    )

    class Meta:
        model = Vacunacion
        fields = ["vacuna"]
        labels = {
            "vacuna": "Vacuna",
        }