from urllib import response

# formulas
# from utils.numbers import *
from utils.integers import *

# login key generator
import uuid

# telebot
from telebot import TeleBot, types

# States (for menu routing)
from telebot.handler_backends import State, StatesGroup

# States storage
from telebot.storage import StateMemoryStorage

# Storage init
state_storage = StateMemoryStorage()
import random

# Rest api things
import requests
import json

# server url
api_url = "http://localhost:5000/api"

# bot object init
app = TeleBot(
    token="5426412733:AAG6272BW7o3A478pipnm8i8H1kBceG-YjA", state_storage=state_storage
)

def menu_buttons_add(markup_reply_resize):
    markup_reply_resize.add(
        types.KeyboardButton("START GAME"),
        types.KeyboardButton("OPTIONS"),
    )

# START
@app.message_handler(commands=["start"])
def start_command(message):
    chat = message.chat.id

    response = requests.get(api_url + f"/users/{message.from_user.id}")
    response_json = response.json()
    pretty = json.dumps(response_json, indent=4)
    result = response_json["user_id"]
    print(result)
    if result == message.from_user.id:
        markup_reply_resize = types.ReplyKeyboardMarkup(
            resize_keyboard=True, one_time_keyboard=True
        )
        menu_buttons_add(markup_reply_resize)  # MENU BUTTONS ADD
        msg = app.send_message(chat, "HELLO AGAIN", reply_markup=markup_reply_resize)

        app.register_next_step_handler(msg, menu_listener)
    if result == []:
        # add BUTTONS
        markup_reply_resize = types.ReplyKeyboardMarkup(
            resize_keyboard=True, one_time_keyboard=True
        )
        markup_reply_resize.add(types.KeyboardButton("YES"), types.KeyboardButton("NO"))
        # helper handler (for new step)
        msg = app.send_message(
            chat,
            "HELLO BOY, IT'S A LOCATION GAME BOT. YOUR LOCATION WILL NOT BE SAVED. OKAY?",
            reply_markup=markup_reply_resize,
        )
        # next step handler
        app.register_next_step_handler(msg, user_answer)

def user_answer(message):
    chat = message.chat.id

    if message.text == "YES":
        msg = app.send_message(chat, "ENTER YOUR NAME")
        app.register_next_step_handler(msg, user_registration)

    if message.text == "NO":
        app.send_message(chat, "no means no, okay :(")

# REGISTRATION
def user_registration(message):
    chat = message.chat.id
    user_name = message.text

    def postUserData():
        user_id = message.from_user.id
        user_login_key = str(uuid.uuid4())
        users_url = api_url + "/users"
        payload = {
            "user_name": user_name,
            "user_id": user_id,
            "user_login_key": user_login_key,
        }
        response = requests.post(users_url, json=(payload))
        if response.status_code == 201:
            app.send_message(
                chat,
                f"NAME {user_name} SAVED",
            )

    postUserData()

    markup_reply_resize = types.ReplyKeyboardMarkup(
        resize_keyboard=True, one_time_keyboard=True
    )
    menu_buttons_add(markup_reply_resize)  # MENU BUTTONS ADD

    msg = app.send_message(chat, "MENU", reply_markup=markup_reply_resize)
    app.register_next_step_handler(msg, menu_listener)

def menu_listener(message):
    if message.text == "START GAME":
        # add BUTTONS
        markup_reply_resize = types.ReplyKeyboardMarkup(
            resize_keyboard=True, one_time_keyboard=True
        )
        markup_reply_resize.add(
            types.KeyboardButton("GIVE MY LOCATION", request_location=True)
        )

        msg = app.send_message(
            message.chat.id, "GIVE YOUR LOCATION", reply_markup=markup_reply_resize
        )

        app.register_next_step_handler(msg, start_the_game)

    if message.text == "OPTIONS":
        # add BUTTONS
        markup_reply_resize = types.ReplyKeyboardMarkup(
            resize_keyboard=True, one_time_keyboard=True
        )
        markup_reply_resize.add(
            types.KeyboardButton("EDIT NAME"),
            types.KeyboardButton("SHOW MY SCORE"),
            types.KeyboardButton("GO TO LEADER BOARD PAGE"),
            types.KeyboardButton("DELETE MY PROFILE"),
        )

        msg = app.send_message(
            message.chat.id, "SELECT OPTION", reply_markup=markup_reply_resize
        )
        app.register_next_step_handler(msg, options_menu_listener)

# GAME CREATING
def start_the_game(message):
    chat = message.chat.id
    coords = {}
    if message.location:
        # init coords
        coords = {
            "latitude": message.location.latitude,
            "longitude": message.location.longitude,
        }
        # new coords

        new_location = point_at_distance(coords)
        coords["latitude"] = new_location["latitude"]
        coords["longitude"] = new_location["longitude"]
        app.send_message(
            chat,
            f"POINT CREATED",
        )

        def post_thegame_data():
            payload = {
                "user_id": message.from_user.id,
                "latitude": coords["latitude"],
                "longitude": coords["longitude"],
                "status": "in_progress",
            }

            thegame_url = api_url + "/thegame"
            response = requests.post(thegame_url, json=(payload))

            if response.status_code == 201:
                app.send_message(
                    chat,
                    f"POINT SAVED. REACH THE POINT",
                )
                # add BUTTONS
                markup_reply_resize = types.ReplyKeyboardMarkup(
                    resize_keyboard=True, one_time_keyboard=True
                )
                markup_reply_resize.add(
                    types.KeyboardButton("CHECK LOCATION", request_location=True),
                    types.KeyboardButton("STOP THE GAME"),
                )

                msg = app.send_message(
                    chat,
                    "THE GAME HAS STARTED",
                    reply_markup=markup_reply_resize,
                )
                app.send_location(chat, coords["latitude"], coords["longitude"])

                app.register_next_step_handler(msg, game_process)

            if response.status_code == 500:
                app.send_message(
                    chat,
                    f"YOUR ID IS NOT EXISTS",
                )
                msg = app.send_message(chat, "ENTER YOUR NAME")
                app.register_next_step_handler(msg, user_registration)

        post_thegame_data()

def game_process(message):
    chat = message.chat.id
    the_game_id_url = api_url + f"/thegame/{message.from_user.id}"

    if message.location:
        user_current_coords = {
            "latitude": message.location.latitude,
            "longitude": message.location.longitude,
        }
        response = requests.get(the_game_id_url)
        response_json = response.json()
        print(response_json)
        game_current_point = {
            "latitude": response_json["latitude"],
            "longitude": response_json["longitude"],
        }
        print(game_current_point)
        # IF USER IN AREA
        if distance_between(user_current_coords, game_current_point) < 1:
            user_current_coords = {}  # clear the user location
            payload = {
                "status": "done",
            }
            response = requests.put(the_game_id_url, json=(payload))
            result = response.status_code
            if result == 200:
                app.send_message(chat, "GAME ENDED. SCORE + 1")
                # add buttons
                markup_reply_resize = types.ReplyKeyboardMarkup(
                    resize_keyboard=True, one_time_keyboard=True
                )
                menu_buttons_add(markup_reply_resize)  # MENU BUTTONS ADD

                msg = app.send_message(chat, "MENU", reply_markup=markup_reply_resize)
                app.register_next_step_handler(msg, menu_listener)

        # IFb
        #  USER NOT IN AREA
        if distance_between(user_current_coords, game_current_point) > 1:
            # add BUTTONS
            markup_reply_resize = types.ReplyKeyboardMarkup(
                resize_keyboard=True, one_time_keyboard=True
            )
            markup_reply_resize.add(
                types.KeyboardButton("CHECK LOCATION", request_location=True),
                types.KeyboardButton("STOP THE GAME"),
            )

            msg = app.send_message(chat, "GET CLOSER", reply_markup=markup_reply_resize)
            app.register_next_step_handler(msg, game_process)

    if message.text == "STOP THE GAME":
        response = requests.delete(the_game_id_url)
        # add buttons
        markup_reply_resize = types.ReplyKeyboardMarkup(
            resize_keyboard=True, one_time_keyboard=True
        )
        menu_buttons_add(markup_reply_resize)  # MENU BUTTONS ADD
        app.send_message(chat, "CANCELLATION")
        msg = app.send_message(chat, "MENU", reply_markup=markup_reply_resize)
        app.register_next_step_handler(msg, menu_listener)

def options_menu_listener(message):
    chat = message.chat.id
    if message.text == "EDIT NAME":
        msg = app.send_message(chat, "ENTER NEW NAME")
        app.register_next_step_handler(msg, user_registration)

    if message.text == "SHOW MY SCORE":
        response = requests.get(api_url + f"/thegame/{message.from_user.id}")
        response_json = response.json()
        result = response_json["score"]
        msg = app.send_message(chat, f"YOUR SCORE: {result}")
        # add buttons
        markup_reply_resize = types.ReplyKeyboardMarkup(
            resize_keyboard=True, one_time_keyboard=True
        )
        menu_buttons_add(markup_reply_resize)  # MENU BUTTONS ADD

        # go to menu
        msg = app.send_message(chat, "MENU", reply_markup=markup_reply_resize)
        app.register_next_step_handler(msg, menu_listener)
    # not use:
    # if message.text == "GET ME MY LOGIN KEY":
    #     response = requests.get(api_url + f"/users/{message.from_user.id}")
    #     response_json = response.json()
    #     login_key = response_json["login_key"]
    #     app.send_message(chat, f"YOUR LOGIN KEY: {login_key}")

    #     # add buttons
    #     markup_reply_resize = types.ReplyKeyboardMarkup(
    #         resize_keyboard=True, one_time_keyboard=True
    #     )
    #     menu_buttons_add(markup_reply_resize)  # MENU BUTTONS ADD

    #     # go to menu
    #     msg = app.send_message(chat, "MENU", reply_markup=markup_reply_resize)
    #     app.register_next_step_handler(msg, menu_listener)

    if message.text == "GO TO LEADER BOARD PAGE":
        # leader board page
        app.send_message(chat, "http://localhost:3000")

        # add buttons
        markup_reply_resize = types.ReplyKeyboardMarkup(
            resize_keyboard=True, one_time_keyboard=True
        )
        menu_buttons_add(markup_reply_resize)  # MENU BUTTONS ADD

        # go to menu
        msg = app.send_message(chat, "MENU", reply_markup=markup_reply_resize)
        app.register_next_step_handler(msg, menu_listener)

    if message.text == "DELETE MY PROFILE":
        msg = app.send_message(message.chat.id, "ALL DATA DELETED. RESTART BOT")
        requests.delete(api_url + f"/users/{message.from_user.id}")
        requests.delete(api_url + f"/thegame/{message.from_user.id}")

    if message.text == "BACK TO MENU":
        # add buttons
        markup_reply_resize = types.ReplyKeyboardMarkup(
            resize_keyboard=True, one_time_keyboard=True
        )
        menu_buttons_add(markup_reply_resize)  # MENU BUTTONS ADD

        # go to menu
        msg = app.send_message(chat, "MENU", reply_markup=markup_reply_resize)
        app.register_next_step_handler(msg, menu_listener)

app.enable_save_next_step_handlers(delay=2)
# app.load_next_step_handlers()
app.infinity_polling(skip_pending=True)


import pigpio
pi = pigpio.pi()

#open an i2c connection to the BNO055
SDA = 2
SCL= 3
baud = 10000
i2c_address = 0x28  #0x29 is alternate if COM3 pin is changed
#OPR_MODE_reg = ?
NDOF_MODE_VAL=0b1100
mode_switch_time = 0.010 #wait ten milliseconds for the mode to change
END = 0
ESCAPE = 1
START = 2
STOP = 3
ADDRESS = 4
FLAGS = 5
READ = 6
WRITE = 7
WRITE_MASK = 0b0
READ_MASK = 0b1
ST_RESULT_ADDRESS = 0x3E    # in page 0

i2c_bus = pi.bb_i2c_open(SDA, SCL, baud)

#things to do
# 1. check Power On Self Test reg ST_RESULT for a bit set (self test passed)
print(pi.bb_i2c_zip(SDA, [ADDRESS,i2c_address,START,WRITE,1,((i2c_address<<1)|WRITE_MASK),WRITE,1,ST_RESULT_ADDRESS,START,WRITE,1,((i2c_address<<1)|READ_MASK),READ,1,STOP]))
# 2. run Build in Self Test. Check ST_RESULT.
# 3. set power mode (optional, defaults to normal)
# 4. Set calibration values (obtain from IMU_calibration.py)
# 5. Axis remap (optional)
# 6. Set Euler angles to Degrees
# 7. Set Data output format
# 8. change calibration offsets (optional)
# 9. set operation mode to fusion mode NDOF (set by writing to [OPR_MODE] register)
#    starts in config mode
# 10. wait for operation mode to change from config mode (7 ms)
# 11. start polling IMU at 100Hz.
# 12. get temp (optional)

#close the i2c bus
pi.bb_i2c_close(SDA)


import requests
import pprint
from bs4 import BeautifulSoup
res=requests.get('https://news.ycombinator.com/news?p=2')
soup=BeautifulSoup(res.text, 'html.parser')
votes=soup.select('.score')
links=soup.select('.storylink')

def custom_nletter(links,votes):
    hn=[]
    for idx,itm in enumerate(links):
        Title=links[idx].getText()
        href=links[idx].get('href',None)
        points=int(votes[idx].getText().replace(' points', ''))
        if points>50:
            hn.append({'title':Title,'link':href,'points':points})
    return hn

pprint.pprint(custom_nletter(links,votes))


from subprocess import check_output

# Hyper-parameters
table = "cnn_tuning"
target = "surv_mo_6"
channels = [500]
dropouts = [0.2, 0.5, 0.8]
weight_decays = [0]
lrs = [0.00001, 0.00005, 0.0001]
# best seems to be 0.8 dropout with 0.00005 lr

# Check the other survival lengths, e.g. with 0.00001, 0.00005, 0.0001 and 0.2, 0.5, 0.8 dropout.
for channel in channels:
    for dropout in dropouts:
        for weight_decay in weight_decays:
            for lr in lrs:
                command = f'python -m models.cnn --target {target} ' \
                          f'--table {table} --output-channel {channel} --weight-decay {weight_decay} --lr {lr}' \
                          f' --dropout {dropout}'
                print(f'executing command: {command}')
                check_output(command, shell=True)


""" Database models """

### Python imports ###
import uuid
from enum import Enum
from datetime import datetime, timedelta

### Django imports ###
from django.db import models
from django.utils.html import escape, mark_safe, format_html
from django.contrib.auth.models import User
from django.template.defaultfilters import truncatechars
from django.conf import settings
from django.urls import reverse

### Third Party imports ###
from phone_field import PhoneField
from ckeditor.fields import RichTextField
from auditlog.registry import auditlog
from gsheets import mixins

class ImageCategory(models.TextChoices):
    """Image Category: Internal, Customer, Marketing"""

    INTERNAL = "Internal"
    CUSTOMER = "Customer"
    MARKETING = "Marketing"

class NextActionItemStatus(models.TextChoices):
    """Status choices for Next Action Item."""

    PAST_DUE = "Past Due"
    TO_DO = "To Do"
    COMPLETED = "Completed"

class ServiceCategory(Enum):
    """ Enum for service category the customer is seeking. """

    IT = "IT"
    STEEL_VIKING = "Steel Viking"
    IT_AND_STEEL_VIKING = "It and Steel Viking"
    NOT_SET = "Not set"
    OTHER = "Other"

class ContactStatus(Enum):
    """ Enum for the status of a customer contact. """

    NOT_SET = "Not Set"
    BAD_NUMBER = "Bad Number"
    VOICEMAIL = "Voicemail"
    SETUP_CALLBACK = "Setup Callback"
    WARM = "Warm"
    HOT = "Hot"

class BusinessType(Enum):
    """ Enum for the status of a customer contact. """

    OTHER = "Other"
    MANUFACTURING = "Manufacturing"
    HEALTHCARE = "Healthcare"
    FINANCE = "Finance"

class RelationshipType(Enum):
    """ Enum for the status of a customer contact. """

    CUSTOMER = "Customer"
    PROSPECT = "Prospect"
    PARTNER = "Partner"
    OTHER = "Other"
    NOT_SET = "Not Set"

class InterestLevel(Enum):
    """ Enum for the level of interest of a customer contact. """

    ONE = "1 – No interest, initial prospect, some interest in the past but has cooled"
    TWO = "2 – Promising and ongoing interaction with prospect, meetings happening, possible work identified"
    THREE = "3 – Work identified and statement made that prospect wants to ultimately work with us – path forward"
    FOUR = "4 – Real opportunity for work under consideration, specific work and timeframe identified, Fidelis identified as serious contender"
    FIVE = "5 – Nearing work approval"

class Customer(mixins.SheetPushableMixin, models.Model):
    """ The core of the app. Our customer """

    # Google Sheets API settings
    spreadsheet_id = settings.GSHEETS_CUSTOMER_SHEET_ID
    sheet_id_field = "Customer ID"
    sheet_name = "Customers"

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    source = models.CharField(
        max_length=200,
        null=True,
        blank=True,
        help_text="This is the source of the lead.",
    )
    master_company = models.CharField(max_length=200, verbose_name="Master company", null=True, blank=True)
    company = models.CharField(max_length=200, null=True, blank=True)
    role = models.CharField(max_length=200, null=True, blank=True)
    first_name = models.CharField(max_length=200, blank=True)
    last_name = models.CharField(max_length=200, blank=True)
    email = models.EmailField(max_length=254)
    phone = PhoneField(blank=True, help_text="Contact phone number", null=True, max_length=50)
    address = models.CharField(max_length=200, null=True, blank=True)
    city = models.CharField(max_length=200, null=True, blank=True)
    state = models.CharField(max_length=200, null=True, blank=True)
    zip_code = models.CharField(max_length=20, null=True, blank=True)
    last_contacted = models.DateField(
        verbose_name="Last contacted",
        null=True,
        blank=True,
        help_text="This is the last time the Customer was contacted.",
    )
    next_action_item = models.TextField(
        null=True,
        blank=True,
        help_text="This is for solid, defined next actions. Use the Description field for general notes.",
    )
    target_date = models.DateField(
        null=True,
        blank=True,
        verbose_name="Target date",
        help_text="This is the Target Date for the Next Action Item. This should only be used if there is a Next Action Item.",
    )
    assignee = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        verbose_name="Assignee",
        related_name="assignee",
        help_text="The person assigned to complete the Next Action Item.",
    )
    description = models.TextField(
        null=True,
        blank=True,
        help_text="This is for general descriptions, notes, or any info you want to add about the contact.",
    )
    relationship_type = models.CharField(
        max_length=256,
        choices=[(relationship.name, relationship.value) for relationship in RelationshipType],
        default=RelationshipType.PROSPECT.name,
        null=True,
        blank=True,
    )
    service_category = models.CharField(
        max_length=256,
        choices=[(service.name, service.value) for service in ServiceCategory],
        default=ServiceCategory.IT.name,
        null=True,
        blank=True,
    )
    interest_level = models.CharField(
        max_length=256,
        choices=[(level.name, level.value) for level in InterestLevel],
        default=InterestLevel.ONE.name,
        null=True,
        blank=True,
    )
    primary_contact = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
        verbose_name="Primary contact",
        related_name="primary_contact",
        help_text="The Customer's primary contact at Fidelis.",
    )
    secondary_contact = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
        related_name="secondary_contact",
        help_text="The Customer's secondary contact at Fidelis.",
    )
    contact_status = models.CharField(
        max_length=256,
        choices=[(status.name, status.value) for status in ContactStatus],
        default=ContactStatus.NOT_SET.name,
        null=True,
        blank=True,
        verbose_name="Phone contact status",
        help_text="This is the status from the last sales call.",
    )
    business_type = models.CharField(
        max_length=256,
        choices=[(business.name, business.value) for business in BusinessType],
        default=BusinessType.MANUFACTURING.name,
        null=True,
        blank=True,
    )
    website = models.URLField(max_length=200, null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)

    def __str__(self):
        """ Returns a string representation of all Customer fields for a nicer display. """
        return f"{self.company}"

    def last_emailed_at(self):
        """Queries this customers EmailMessage to find the
        timestamp of the last email we sent.
        """
        sent_emails = EmailMessage.objects.filter(customer=self, send_succeeded=True).order_by("created_at").all()
        if len(sent_emails) > 0:
            return sent_emails[0].created_at
        return None

    def is_dnc(self):
        """Queries this customers EmailMessage to determine if
        they've unsubsubscribe in response to any of them.
        """
        return EmailMessage.objects.filter(customer=self, unsubscribed=True).count() > 0

    @property
    def short_description(self):
        """ Truncates the description field to the specified length. """
        return truncatechars(self.description, 100)

class ImageResource(models.Model):
    """Database record of image resources. Creating a relationship with
    this class will allow for the reusage of the same image resource in
    mass email batches.
    """

    token = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    uploaded_at = models.DateTimeField(auto_now_add=True, blank=True)
    description = models.CharField(max_length=512)
    image = models.ImageField(upload_to="email_images", help_text="Select an image file")
    category = models.CharField(choices=ImageCategory.choices, max_length=16, default=ImageCategory.MARKETING.value)
    archived = models.BooleanField(
        default=False,
        help_text="If checked, this Image will be archived and hidden from the default list view.",
    )

    def __str__(self):
        return f"Image file: {self.description}"

    def image_tag(self):
        return mark_safe('' % escape(self.image.url))

    image_tag.short_description = "Image"
    image_tag.allow_tags = True

class EmailTemplate(Enum):
    """ Enum mapping available email templates to files. """

    SIMPLE = "simple.html"
    MODERN_STANDARD = "modern_standard.html"

# TODO: return the correct default image url here
DEFAULT_IMAGE_URL = "https://cdn0.iconfinder.com/data/icons/feather/96/no-512.png"

class EmailMessage(models.Model):
    """ Persistence for an email we've sent to customer. """

    token = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True, blank=True)
    send_succeeded = models.BooleanField(
        default=False,
        blank=True,
        help_text="Indicates that an email has been sent and whether it succeeded or failed.",
    )
    template_file = models.CharField(
        max_length=256,
        choices=[(templ.value, templ.name) for templ in EmailTemplate],
        default=EmailTemplate.MODERN_STANDARD.value,
    )
    subject = models.CharField(max_length=256, null=True)

    company_logo = models.ForeignKey(
        ImageResource,
        related_name="company_logo_emails",
        on_delete=models.DO_NOTHING,
        help_text="Primary Company logo",
    )
    alt_company_logo = models.ForeignKey(
        ImageResource,
        on_delete=models.DO_NOTHING,
        help_text="If one is not chosen, the above Company Logo will be used.",
        verbose_name="Secondary Company logo",
        null=True,
        blank=True,
    )
    title = RichTextField(null=True, blank=True)
    primary_image = models.ForeignKey(
        ImageResource,
        null=True,
        blank=True,
        related_name="primary_image_emails",
        on_delete=models.DO_NOTHING,
        help_text="The primary marketing image for the email.",
    )

    # ckeditor Rich Text Field
    custom_message = RichTextField(null=True, blank=True)
    call_to_action_button_text = models.CharField(max_length=256, default="Learn More")
    call_to_action_button_link = models.CharField(max_length=256, default="http://www.fidelis-partners.com/")

    # Results filled by customer interaction with email
    unsubscribed = models.BooleanField(default=False, blank=True)

    batch = models.ForeignKey(
        "EmailBatch",
        related_name="email_messages",
        null=True,
        blank=True,
        on_delete=models.DO_NOTHING,
    )

    def __str__(self):
        return f"Email sent to {self.customer}"

    @property
    def get_company_logo_absolute_url(self):
        if self.company_logo is None:
            return DEFAULT_IMAGE_URL
        return self.company_logo.image.url

    @property
    def get_company_secondary_logo_absolute_url(self):
        """Returns alt_company_logo if there is one, otherwise returns company_logo."""
        if self.alt_company_logo is not None:
            return self.alt_company_logo.image.url
        else:
            return self.company_logo.image.url

    @property
    def get_primary_image_absolute_url(self):
        if self.primary_image is None:
            return DEFAULT_IMAGE_URL
        return self.primary_image.image.url

class EmailBatch(models.Model):
    """Stores the parameters of a mass email batch. This is mostly
    the same as what is on each `EmailMessage` but allows for future
    batches to be sent containing the same form data.
    """

    token = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    created_at = models.DateTimeField(auto_now_add=True, blank=True)
    batch_title = models.CharField(
        max_length=50,
    )

    #
    # Parameters of the batch
    #

    template_file = models.CharField(
        max_length=256,
        choices=[(templ.value, templ.name) for templ in EmailTemplate],
        default=EmailTemplate.MODERN_STANDARD.value,
    )

    subject = models.CharField(max_length=256, null=True)
    title = RichTextField(null=True)
    custom_message = RichTextField(null=True)
    call_to_action_button_text = models.CharField(
        max_length=256,
        help_text="This will be the text used for the main Call To Action button in the email. You want to make it something short and attention-grabbing.",
    )
    call_to_action_button_link = models.CharField(
        max_length=256,
        help_text="This will be the link that a user is sent to after clicking the main Call To Action button in the email.",
    )
    company_logo = models.ForeignKey(
        ImageResource,
        related_name="company_logo_batches",
        on_delete=models.DO_NOTHING,
        help_text="Primary company logo.",
    )
    alt_company_logo = models.ForeignKey(
        ImageResource,
        on_delete=models.DO_NOTHING,
        help_text="If one is not chosen, the above Company Logo will be used.",
        verbose_name="Secondary company logo",
        null=True,
        blank=True,
    )
    primary_image = models.ForeignKey(
        ImageResource,
        related_name="primary_image_batches",
        on_delete=models.DO_NOTHING,
        help_text="The primary marketing image for the email.",
    )
    emails_initiated = models.IntegerField(default=0, help_text="The number of emails that were sent in this batch.")
    emails_skipped = models.IntegerField(
        default=0,
        help_text="The number of emails skipped in this batch due to Customers that have unsubscribed.",
    )
    archived = models.BooleanField(
        default=False,
        help_text="If checked, this Email Batch will be archived and hidden from the default list view.",
    )

    def __str__(self):
        return f"Email batch: {self.batch_title}"

    def emails_sent(self):
        """Queries for the number of emails that succeeded to
        send for this batch.
        """
        return EmailMessage.objects.filter(batch=self, send_succeeded=True).count()

    def unsubscribe_count(self):
        """Queries for the number of emails in this batch that customers
        have used to unsubscribe.
        """
        return EmailMessage.objects.filter(batch=self, unsubscribed=True).count()

    def create_email_message(self, customer: Customer):
        """Uses the values stored in this instance to create a new
        EmailMessage object. It has NOT been saved to the DB yet tho,
        so edits may still take place.
        """
        return EmailMessage(
            customer=customer,
            template_file=self.template_file,
            subject=self.subject,
            title=self.title,
            custom_message=self.custom_message,
            call_to_action_button_text=self.call_to_action_button_text,
            call_to_action_button_link=self.call_to_action_button_link,
            company_logo=self.company_logo,
            alt_company_logo=self.alt_company_logo,
            company_logo_id=self.company_logo_id,
            primary_image=self.primary_image,
            primary_image_id=self.primary_image_id,
            batch=self,
        )

    def clone(self, new_batch_title: str):
        """Constructs a new EmailBatch instance with all the same
        field values except for the `batch_title`. It does not get
        saved to the Db.
        """
        return EmailBatch(
            batch_title=new_batch_title,
            template_file=self.template_file,
            subject=self.subject,
            title=self.title,
            custom_message=self.custom_message,
            call_to_action_button_text=self.call_to_action_button_text,
            call_to_action_button_link=self.call_to_action_button_link,
            company_logo=self.company_logo,
            company_logo_id=self.company_logo_id,
            alt_company_logo=self.alt_company_logo,
            primary_image=self.primary_image,
            primary_image_id=self.primary_image_id,
        )

    @property
    def preview_link(self):
        preview_url = reverse("preview_batch", kwargs={"batch_token": self.pk})
        return mark_safe(f'Preview')  # noqa

    class Meta:
        verbose_name = "Email batch"
        verbose_name_plural = "Email batches"

class NextActionItem(models.Model):
    """Model definition for NextActionItem."""

    customer = models.ForeignKey(
        Customer,
        on_delete=models.CASCADE,
        verbose_name="Customer",
        help_text="The Customer this Next Action Item relates to.",
    )
    description = models.TextField(max_length=256, help_text="Describe this Next Action Item.")
    assignee = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
        verbose_name="Assignee",
        help_text="The person assigned to complete this Next Action Item.",
    )
    target_date = models.DateField(help_text="The Target Date for this Next Action Item.", verbose_name="Target date")
    completed = models.DateTimeField(
        default=None,
        null=True,
        blank=True,
        verbose_name="Completed",
        help_text="IMPORTANT: Add the completed time once this Next Action Item is completed.",
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="Created at")

    class Meta:
        """Meta definition for NextActionItem."""

        verbose_name = "Next Action Item"
        verbose_name_plural = "Next Action Items"

    """Method definitions for NextActionItem."""

    def __str__(self):
        """Unicode representation of NextActionItem."""
        return f"Next Action Item: {self.customer} {self.target_date}"

    @property
    def short_description(self):
        """Truncates the description field to the specified length."""
        return truncatechars(self.description, 50)

    @property
    def status(self):
        """ Returns Next Action Item Status: Past Due, Completed, or To Do."""
        if self.completed is not None:
            return mark_safe(
                f'
{NextActionItemStatus.COMPLETED}
'
            )  # noqa
        elif self.completed is None and self.target_date < datetime.now().date():
            return mark_safe(
                f'
{NextActionItemStatus.PAST_DUE}
'
            )  # noqa
        else:
            return mark_safe(
                f'
{NextActionItemStatus.TO_DO}
'
            )  # noqa

    status.fget.short_description = "Status"

auditlog.register(Customer)
auditlog.register(EmailBatch)
auditlog.register(EmailMessage)
auditlog.register(NextActionItem)


#!/usr/bin/env python
'''code description'''
# pylint: disable = I0011, E0401, C0103, C0321

class Solution(object):
    '''Solution description'''
    def helper(self, total_res, part_res, options, t):
        '''solution helper'''
        if sum(part_res) > t: return
        elif sum(part_res) < t:
            for i, e in list(enumerate(options)):
                self.helper(total_res, part_res+[e], options[i:], t)
        else: total_res.append(part_res)

    def func(self, candidates, target):
        '''Solution function description'''
        res = []
        self.helper(res, [], candidates, target)
        return res

def main():
    '''main function'''
    _solution = Solution()
    inp = [([2,3,6,7], 7)]
    for i in inp:
        print(_solution.func(i[0], i[1]))

if __name__ == "__main__":
    main()


from flask import Flask, render_template, url_for
import glob
MyApp = Flask(__name__, static_url_path="", static_folder="public")

helpers = {
    "dashboard_title": "Open OnDemand",
    "dashboard_url": "/pun/sys/dashboard/",
    "title": "Autoscale Log"
}

@MyApp.route("/")
def view_autoscale_log():
    items = []
    try:
        with open("/var/log/slurm/autoscale.log") as file:
            items = [
                [ x.strip() for x in line.split("#") ]
                for line in file.readlines()
            ]
    except IOError:
        pass

    return render_template('index.html', items=items[::-1], **helpers)

@MyApp.route("/<log>")
def view_azlog(log):
    g = glob.glob("/var/log/slurm/*_"+log+".log")
    if len(g):
        with open(g[0]) as file:
            content = file.read()
    else:
        content = "<empty_file>"

    return render_template('azlog.html', content=content, **helpers)

if __name__ == "__main__":
	MyApp.run()


from dataclasses import dataclass
from dataclasses import field
from typing import Any

from behaviors.behavior_tree import BT

@dataclass
class Coefficients:
    """Coefficients for tuning the fitness function."""

    position: float = -1.0
    pos_acc: float = 0.1
    depth: float = 0.0
    length: float = -0.01
    ticks: float = 0.0
    failed: float = -5.0
    timeout: float = -1.0
    hand_not_empty: float = 0.0
    targets: list = field(default_factory=list)

def compute_fitness(
    world_interface: Any,
    py_tree: BT,
    ticks: int,
    coeff: 'Coefficients' = None,
    verbose: bool = False
) -> float:
    """Retrieve values and compute fitness."""
    if coeff is None:
        coeff = Coefficients()

    depth = py_tree.bt.depth()
    length = py_tree.bt.length()

    fitness = coeff.length * length + coeff.depth * depth + coeff.ticks * ticks
    if verbose:
        print('Fitness from length:', fitness)

    if coeff.position != 0.0:
        for i in range(len(coeff.targets)):
            fitness += coeff.position * max(
                0, world_interface.distance(i, coeff.targets[i]) - coeff.pos_acc)
            if verbose:
                print('Fitness:', fitness)
                print(i, ': ', world_interface.get_object_position(i))

    if py_tree.failed:
        fitness += coeff.failed
        if verbose:
            print('Failed: ', fitness)
    if py_tree.timeout:
        fitness += coeff.timeout
        if verbose:
            print('Timed out: ', fitness)
    if coeff.hand_not_empty != 0.0 and world_interface.get_picked() is not None:
        fitness += coeff.hand_not_empty
        if verbose:
            print('Hand not empty: ', fitness)

    # Just to ensure that binary approximation doesn't affect fitness ranking
    return round(fitness, 10)


import os
import numpy as np
from surprise import accuracy

def get_evaluate(is_svd, movies):
    predictions = [[str(movie.user_id), str(movie.movie_id),
                    movie.ground_truth, movie.predict, False] for movie in movies]
    ratings = [movie.ground_truth for movie in movies]
    avg_rating = np.mean(ratings)
    # print(f'average rating: {avg_rating}')
    rmse = accuracy.rmse(predictions, verbose=True)
    # print(f'user_rmse: {rmse}')
    if is_svd:
        with open('svd_rmse.csv', mode='a', newline='', encoding='utf8') as cfa:
            cfa.write(str(rmse) + '\n')
    else:
        with open('knn_rmse.csv', mode='a', newline='', encoding='utf8') as cfa:
            cfa.write(str(rmse) + '\n')
    if not os.path.exists('knn_rmse.csv'):
        knn_rmse = []
    else:
        with open('knn_rmse.csv', 'r') as fr:
            knn_lines = fr.readlines()
        knn_rmse = [float(knn.rstrip('\n')) for knn in knn_lines]
    if not os.path.exists('svd_rmse.csv'):
        svd_rmse = []
    else:
        with open('svd_rmse.csv', 'r') as fr:
            svd_lines = fr.readlines()
        svd_rmse = [float(svd.rstrip('\n')) for svd in svd_lines]
    return knn_rmse, svd_rmse, avg_rating

def rm_file(knn_rmse, svd_rmse):
    if len(knn_rmse) >= 2:
        os.remove('knn_rmse.csv')
    if len(svd_rmse) >= 2:
        os.remove('svd_rmse.csv')


# Author: Jason Lu

name = input("name:")
age = int(input("age:"))
print(type(age))
print(type(str(age)))
str_agr = str(age)
print(type(str_agr))

job = input("job:")
salary = input("salary:")

info = '''
-------- info of %s ------
Name: %s
Age: %d
Job: %s
Salary: %s
''' % (name, name, age, job, salary)
print(info)

info2 = '''
-------- info2 of {_name} ------
Name: {_name}
Age: {_age}
Job: {_job}
Salary: {_salary}
'''.format(_name=name,
           _age=age,
           _job=job,
           _salary=salary)

print(info2)

info3 = '''
-------- info3 of {0} ------
Name: {0}
Age: {1}
Job: {2}
Salary: {3}
'''.format(name,age,job,salary)

print(info3)

print("this is {} format {}".format("test", "output"))


import pygame
import time
import newgame2
import random

pygame.init()
RES = (1200,900)
w = 1200
h = 900
size=(w,h)
screen = pygame.display.set_mode((w, h))
c = pygame.time.Clock() # create a clock object for timing
count = 0 #keep track of number of game iterations

#load all the images into variables
fix=pygame.image.load("fixation.png")
ready=pygame.image.load("readyscreen.png")
high=pygame.image.load("win_high.png")
low=pygame.image.load("win_low.png")
lose=pygame.image.load("lose.png")
mvc = -1

while count != 15:

        #show fixation cross for 2 seconds
        # screen.blit(fix,(0,0))
        # pygame.display.flip() # update the display
        # pygame.time.wait(1000)

        #show ready screen for 2 seconds

        # screen.blit(ready,(0,0))
        # pygame.display.flip()
        # pygame.time.wait(1000)

        #start game
        if count == 0:
                decisionRange, mvc = newgame2.main(count, 0)
        else:
                decisionRange = newgame2.main(count, mvc)[0]

        #if only calibrate once, feed in count as a param to main, if count = 1
        #calibrate and return decisionRange, mvc in main
        #else dont calibrate and return decisionRange, null in main, adjust and call
        #newgame2.main with paramter of mvc returned in first trial
        print("decisionRange", decisionRange)
        print("mvc", mvc)
        rand = random.uniform(0, 1)
        print("rand", rand)

        #display rewards
        if decisionRange == "LR":
                if rand <= .5:
                        screen.blit(low,(0,0))
                        pygame.display.flip()
                        pygame.time.wait(2000)
                else:
                        screen.blit(lose,(0,0))
                        pygame.display.flip()
                        pygame.time.wait(2000)
        elif decisionRange == "HR":
                 if rand <= .5:
                        screen.blit(high,(0,0))
                        pygame.display.flip()
                        pygame.time.wait(2000)
                 else:
                        screen.blit(lose,(0,0))
                        pygame.display.flip()
                        pygame.time.wait(2000)
        elif decisionRange == "calibration":
                count += 1
                continue
        else:
                screen.blit(lose,(0,0))
                pygame.display.flip()
                pygame.time.wait(2000)

        count+=1

pygame.display.quit()


from flask import Flask, request, render_template, url_for, send_file, redirect, make_response, jsonify, abort
from flask_cors import CORS
import json
import datetime as dt
import mods.api as api
import createDB
from settings import DEFAULT_RANDOMIZER
import time
import re

app = Flask(__name__)
CORS(app)

@app.route('/')
def get_home():
    """
    Homepage
    """
    return render_template('index.html')

@app.route('/<short_url>/outdated')
def get_outdated(short_url):
    """
    Page that loads if remaining references of a link is 0
    """

    return render_template('index.html')

@app.route('/<short_url>')
def redirect_user(short_url):
    # search for short url
    connection = api.connect_db()
    cursor = connection.cursor(buffered=True)
    # new_path = api.prettify_string(request.path)
    # app.logger.warning(new_path)

    query = f"SELECT reference_url FROM link WHERE short_url='{short_url}'"
    cursor.execute(query)
    for row in cursor:
        app.logger.warning(row)
        if row is not None:
            x = api.check_limit(short_url, connection)
            cursor.close()
            connection.close()
            return redirect(row[0], code=302)
    cursor.close()
    connection.close()
    abort(404)
    # return redirect("/404", code=302)

@app.route('/<short_url>/safe')
def redirect_safe(short_url):
    # search for short url
    connection = api.connect_db()
    cursor = connection.cursor(buffered=True)
    # new_path = request.path
    new_path= request.path[1:-(len(request.path)-5)]
    app.logger.warning(new_path)
    app.logger.warning(short_url)
    query = f"SELECT reference_url FROM link WHERE short_url='{short_url}'"
    cursor.execute(query)
    for row in cursor:
        app.logger.warning(row)
        if row is not None:
            x = api.check_limit(short_url, connection)
            cursor.close()
            connection.close()
            url=row[0]
            app.logger.warning(f"sicher aufgerufene url: {url}")
            # return render_template("index.html", surl=url, code=200)
            return redirect(f"/safeView/{url}", code=302)
    cursor.close()
    connection.close()
    abort(404)
    # return app.send_static_file("index.html")
    # return redirect("/404", 302)

@app.route("/safeView/<path:short_url>")
def show_view(short_url):
    return render_template("index.html"),200

@app.route('/api/create', methods=["GET"])
def use_api():
    """
    for creation of a new shortened url
    """
    #return make_response(jsonify({"message": "hi"}), 200)
    url = request.args.get('url')
    custom_tag = request.args.get('custom')
    random_method = request.args.get('random_method')
    is_private = request.args.get('private')
    refs_available = request.args.get('refs_available')
    if url is None or not(type(url) == str):
        return make_response(jsonify({"message":"Param url is required as string"}), 406)
    else:
        url = re.sub(r"[^\w/.:]","", url) # TODO to prevent sql injections

    if not(is_private is None):
        app.logger.warning(is_private)
        try:
            is_private = int(is_private)
        except:
            return make_response(jsonify({"message":"Error in API Syntax"}), 406)
    elif is_private is None:
        is_private = 0

    if not(random_method is None):
        app.logger.warning(random_method)
        try:
            random_method = int(random_method)
        except:
            return make_response(jsonify({"message":"Error in API Syntax"}), 406)
        app.logger.warning(type(random_method))

    elif random_method is None:
        random_method = DEFAULT_RANDOMIZER

    if not(type(refs_available)==int) and not(refs_available is None):
        try:
            refs_available = int(refs_available)
        except:
            return make_response(jsonify({"message":"Error in API Syntax"}), 406)
    elif refs_available is None:
        refs_available = -1
    if not(custom_tag is None):
        custom_tag = re.sub(r"\W", '', custom_tag)
    link = api.create_url(url, int(is_private), custom_tag, int(refs_available), int(random_method))
    app.logger.warning({"message": f"Your url {link} was created", "url": link})
    return make_response(jsonify({"message": f"Your url {link} was created", "url": link}), 201)

@app.route('/api/statistics')
def get_statistic():
    """
    returns: JSON {short:str, reference:str, frequency:int}
    """
    connection = api.connect_db()
    res = api.get_statistics(connection)
    app.logger.warning(res)
    return make_response(jsonify(res), 200)

@app.route('/images/logo/light')
def get_logo():
    return send_file("static/images/PerVerSo32x32.png")

@app.route('/images/logo/dark')
def get_logo_dark():
    return send_file("static/images/PerVerSo32x32_dark.png")

@app.route('/images/404')
def get_404_image():
    return send_file("static/images/404.png")

@app.route('/error/404')
def error404():
    return render_template("index.html"),404

@app.errorhandler(404)
def not_found(e):
    return redirect("/error/404", code=302)

if __name__ == '__main__':
    time.sleep(10)
    createDB.create_db_schema()
    time.sleep(5)
    app.run(host='0.0.0.0', port=5000, use_reloader=False, debug=False)


# Given an integer n, return a string array answer (1-indexed) where:

# answer[i] == "FizzBuzz" if i is divisible by 3 and 5.
# answer[i] == "Fizz" if i is divisible by 3.
# answer[i] == "Buzz" if i is divisible by 5.
# answer[i] == i if non of the above conditions are true.

def fizz(n):
    lst = []
    for i in range (1, n + 1):
        if i % 3  == 0 and i % 5 == 0:
            lst.append('FizzBuzz')
        elif i % 3 == 0:
            lst.append('Fizz')
        elif i % 5 == 0:
            lst.append('Buzz')
        else:
            lst.append(str(i))
    print(lst)

print(fizz(15))

#         else i /= 3
#         i == 'fizz'

# ex1:
# Input: n = 3
# Output: ["1","2","Fizz"]

# ex2:
# Input: n = 5
# Output: ["1","2","Fizz","4","Buzz"]

# ex3:
# Input: n = 15
# Output: ["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","FizzBuzz"]


import os
import re
import sys
import uuid
import codecs
import logging
import warnings
import multiprocessing

from typing import Dict
from logging import FileHandler
from multiprocessing import current_process

from stat import S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IROTH, S_IWOTH

from glycan_profiling import task
from glycan_profiling.config import config_file

logging_levels = {
    'CRITICAL': 50,
    'DEBUG': 10,
    'ERROR': 40,
    'INFO': 20,
    'NOTSET': 0,
    'WARN': 30,
    'WARNING': 30
}

LOG_FILE_NAME = "glycresoft-log"
LOG_FILE_MODE = 'w'
LOG_LEVEL = 'INFO'

user_config_data = config_file.get_configuration()
try:
    LOG_FILE_NAME = user_config_data['environment']['log_file_name']
except KeyError:
    pass
try:
    LOG_FILE_MODE = user_config_data['environment']['log_file_mode']
except KeyError:
    pass
try:
    LOG_LEVEL = user_config_data['environment']['log_level']
    LOG_LEVEL = str(LOG_LEVEL).upper()
except KeyError:
    pass

LOG_FILE_NAME = os.environ.get("GLYCRESOFT_LOG_FILE_NAME", LOG_FILE_NAME)
LOG_FILE_MODE = os.environ.get("GLYCRESOFT_LOG_FILE_MODE", LOG_FILE_MODE)
LOG_LEVEL = str(os.environ.get("GLYCRESOFT_LOG_LEVEL", LOG_LEVEL)).upper()

log_multiprocessing = False
try:
    log_multiprocessing = bool(user_config_data['environment']['log_multiprocessing'])
except KeyError:
    pass

log_multiprocessing = bool(int(os.environ.get(
    "GLYCRESOFT_LOG_MULTIPROCESSING", log_multiprocessing)))

LOGGING_CONFIGURED = False

class ProcessAwareFormatter(logging.Formatter):
    def format(self, record: logging.LogRecord) -> str:
        d: Dict[str, str] = record.__dict__
        try:
            d['filename'] = d['filename'].replace(".py", '').ljust(13)[:13]
        except KeyError:
            d['filename'] = ''
        try:
            if d['processName'] == "MainProcess":
                d['maybeproc'] = ''
            else:
                d['maybeproc'] = ":%s " % d['processName'].replace(
                    "Process", '')
        except KeyError:
            d['maybeproc'] = ''
        return super(ProcessAwareFormatter, self).format(record)

class LevelAwareColoredLogFormatter(ProcessAwareFormatter):
    try:
        from colorama import Fore, Style, init
        init()
        GREY = Fore.WHITE
        BLUE = Fore.BLUE
        GREEN = Fore.GREEN
        YELLOW = Fore.YELLOW
        RED = Fore.RED
        BRIGHT = Style.BRIGHT
        DIM = Style.DIM
        BOLD_RED = Fore.RED + Style.BRIGHT
        RESET = Style.RESET_ALL
    except ImportError:
        GREY = ''
        BLUE = ''
        GREEN = ''
        YELLOW = ''
        RED = ''
        BRIGHT = ''
        DIM = ''
        BOLD_RED = ''
        RESET = ''

    def _colorize_field(self, fmt: str, field: str, color: str) -> str:
        return re.sub("(" + field + ")", color + r"\1" + self.RESET, fmt)

    def _patch_fmt(self, fmt: str, level_color: str) -> str:
        fmt = self._colorize_field(fmt, r"%\(asctime\)s", self.GREEN)
        fmt = self._colorize_field(fmt, r"%\(name\).*?s", self.BLUE)
        fmt = self._colorize_field(fmt, r"%\(message\).*?s", self.GREY)
        if level_color:
            fmt = self._colorize_field(fmt, r"%\(levelname\).*?s", level_color)
        return fmt

    def __init__(self, fmt, level_color=None, **kwargs):
        fmt = self._patch_fmt(fmt, level_color=level_color)
        super().__init__(fmt, **kwargs)

class ColoringFormatter(logging.Formatter):
    level_to_color = {
        logging.INFO: LevelAwareColoredLogFormatter.GREEN,
        logging.DEBUG: LevelAwareColoredLogFormatter.GREY + LevelAwareColoredLogFormatter.DIM,
        logging.WARN: LevelAwareColoredLogFormatter.YELLOW + LevelAwareColoredLogFormatter.BRIGHT,
        logging.ERROR: LevelAwareColoredLogFormatter.BOLD_RED,
        logging.CRITICAL: LevelAwareColoredLogFormatter.BOLD_RED,
        logging.FATAL: LevelAwareColoredLogFormatter.RED + LevelAwareColoredLogFormatter.DIM,
    }

    _formatters: Dict[int, LevelAwareColoredLogFormatter]

    def __init__(self, fmt: str, **kwargs):
        self._formatters = {}
        for level, style in self.level_to_color.items():
            self._formatters[level] = LevelAwareColoredLogFormatter(
                fmt, level_color=style, **kwargs)

    def format(self, record: logging.LogRecord) -> str:
        fmtr = self._formatters[record.levelno]
        return fmtr.format(record)

DATE_FMT = "%H:%M:%S"

def get_status_formatter():
    status_terminal_format_string = "%(asctime)s %(name)s:%(levelname).1s - %(message)s"

    if sys.stderr.isatty():
        terminal_formatter = ColoringFormatter(
            status_terminal_format_string, datefmt=DATE_FMT)
    else:
        terminal_formatter = logging.Formatter(
            status_terminal_format_string, datefmt=DATE_FMT)
    return terminal_formatter

def make_status_logger(name="glycresoft.status"):
    status_logger = logging.getLogger(name)
    status_logger.propagate = False

    terminal_formatter = get_status_formatter()
    handler = logging.StreamHandler(sys.stderr)
    handler.setFormatter(terminal_formatter)
    status_logger.addHandler(handler)
    return status_logger

def get_main_process_formatter():
    terminal_format_string = "%(asctime)s %(name)s:%(levelname).1s:%(filename)s:%(lineno)-4d %(maybeproc)s- %(message)s"
    if sys.stderr.isatty():
        fmt = ColoringFormatter(
            terminal_format_string, datefmt=DATE_FMT)
    else:
        fmt = ProcessAwareFormatter(
            terminal_format_string, datefmt=DATE_FMT)
    return fmt

def make_main_process_logger(name=None, level="INFO"):
    fmt = get_main_process_formatter()
    handler = logging.StreamHandler()
    handler.setFormatter(fmt)
    handler.setLevel(level)
    logging.getLogger(name=name).addHandler(handler)

def make_log_file_logger(log_file_name, log_file_mode, name=None, level="INFO"):
    file_fmter = ProcessAwareFormatter(
        "%(asctime)s %(name)s:%(filename)s:%(lineno)-4d - %(levelname)s%(maybeproc)s - %(message)s",
        DATE_FMT)
    flex_handler = FlexibleFileHandler(log_file_name, mode=log_file_mode)
    flex_handler.setFormatter(file_fmter)
    flex_handler.setLevel(level)
    logger = logging.getLogger(name=name)
    for handler in list(logger.handlers):
        if isinstance(handler, FlexibleFileHandler):
            logger.removeHandler(handler)
    logger.addHandler(flex_handler)

def configure_logging(level=None, log_file_name=None, log_file_mode=None):
    global LOGGING_CONFIGURED
    # If we've already called this, don't repeat it
    if LOGGING_CONFIGURED:
        return
    else:
        LOGGING_CONFIGURED = True
    if level is None:
        level = logging_levels.get(LOG_LEVEL, "INFO")
    if log_file_name is None:
        log_file_name = LOG_FILE_NAME
    if log_file_mode is None:
        log_file_mode = LOG_FILE_MODE

    if log_file_mode not in ("w", "a"):
        warnings.warn("File Logger configured with mode %r not applicable, using \"w\" instead" % (
            log_file_mode,))
        log_file_mode = "w"
    logging.getLogger().setLevel(level)

    logger_to_silence = logging.getLogger("deconvolution_scan_processor")
    logger_to_silence.propagate = False
    logging.captureWarnings(True)

    logger = logging.getLogger("glycresoft")
    # We probably only need to register the base class but let's play it safe
    task.LoggingMixin.log_with_logger(logger)
    task.TaskBase.log_with_logger(logger)

    make_status_logger()

    if current_process().name == "MainProcess":
        make_main_process_logger(level=level)

        if log_multiprocessing:
            fmt = get_main_process_formatter()
            multilogger = multiprocessing.get_logger()
            handler = logging.StreamHandler()
            handler.setFormatter(fmt)
            handler.setLevel(level)
            multilogger.addHandler(handler)

        if log_file_name:
            make_log_file_logger(log_file_name, log_file_mode, name='glycresoft', level=level)

    warner = logging.getLogger('py.warnings')
    warner.setLevel("CRITICAL")

permission_mask = S_IRUSR & S_IWUSR & S_IXUSR & S_IRGRP & S_IWGRP & S_IROTH & S_IWOTH

class FlexibleFileHandler(FileHandler):
    def _get_available_file(self):
        basename = current_name = self.baseFilename
        suffix = 0
        while suffix < 2 ** 16:
            if not os.path.exists(current_name):
                break
            elif os.access(current_name, os.W_OK):
                break
            else:
                suffix += 1
                current_name = "%s.%s" % (basename, suffix)
        if suffix < 2 ** 16:
            return current_name
        else:
            return "%s.%s" % (basename, uuid.uuid4().hex)

    def _open(self):
        """
        Open the current base file with the (original) mode and encoding.
        Return the resulting stream.
        """
        stream = LazyFile(self.baseFilename, self.mode, self.encoding)
        return stream

class LazyFile(object):
    def __init__(self, name, mode='r', encoding=None):
        self.name = name
        self.mode = mode
        self.encoding = encoding
        self._file = None

    def _open(self):
        file_name = self._get_available_file()
        if self.encoding is None:
            stream = open(file_name, self.mode)
        else:
            try:
                stream = codecs.open(file_name, self.mode, self.encoding)
            except LookupError:
                print(f"!! Failed to look up encoding {self.encoding}, falling back to UTF-8")
                stream = open(file_name, self.mode, encoding='utf8')
        self.name = file_name
        self._file = stream
        return self._file

    def read(self, n=None):
        if self._file is None:
            self._open()
        return self._file.read(n)

    def write(self, t):
        if self._file is None:
            self._open()
        return self._file.write(t)

    def close(self):
        if self._file is not None:
            self._file.close()
        return None

    def flush(self):
        if self._file is None:
            return
        return self._file.flush()

    def _get_available_file(self):
        basename = current_name = self.name
        suffix = 0
        while suffix < 2 ** 16:
            if not os.path.exists(current_name):
                break
            elif os.access(current_name, os.W_OK):
                break
            else:
                suffix += 1
                current_name = "%s.%s" % (basename, suffix)
        if suffix < 2 ** 16:
            return current_name
        else:
            return "%s.%s" % (basename, uuid.uuid4().hex)


#!/usr/bin/env python
# -*- coding: utf-8 -*-

from django.views import View
from django.shortcuts import render
from django.contrib import messages
from django.utils import timezone
from django.utils.translation import gettext as _

from samanta.conf import settings

class ViewMixin(View):
    TEMPLATE = 'samanta/missing_template.html'
    TITLE = "No Title"

    def beautify_form(self, form, _fields=(), ignore_fields=()):
        """
        Formats the given form to use the class 'form-control' in all
        fields with the exception of the ignored ones.
        """

        fields = form.fields if not _fields else _fields
        use_fields = [f for f in fields if f not in ignore_fields]

        for field in use_fields:
            print(field)
            form.fields[field].widget.attrs['class'] = 'form-control'

    def render(self, request, context=None):
        """

        :param request: HttpRequest: request to be rendered
        :param context: dict: dictionary passing all the required context

        :return: HttpResponse

        """
        if context is None:
            context = {}
        context_ = {
            'title': self.TITLE
        }
        context_.update(context)
        return render(request, self.TEMPLATE, context_)

class TokenBasedView(ViewMixin):
    """General definition for processing token views. It care about the main
    process of validating and closing tokens
    """

    def process_token(self, request, user, token, token_manager):

        Token = token_manager.objects.filter(user=user, status=1).last()

        if not Token:
            messages.warning(request, _('Invalid link.'))
            return None

        elif not Token.is_old():
            messages.warning(request,
                             _('Token too old. Please request a new one.'))
            return None

        elif not Token.is_valid(token):
            messages.warning(request, _('Invalid link.'))
            return None

        # Deactivate token
        Token.close()
        return Token


import time

import subprocess
import sys
import shlex
import pod_status
from random import randint

def makepodwithname(name,soft_name):
    soft = "bitnami/" + soft_name
    if soft_name == "mediawiki":
        cp = subprocess.run(
            [
                "helm",
                "install",
                "--set",
                "service.type=ClusterIP,persistence.storageClass=longhorn,resources.requests.cpu=null,persistence.size=2Gi,mariadb.primary.persistence.size=2Gi",
                "--namespace=planetes",
                name,
                "bitnami/" + soft_name,
                "-f",
                "values.yml"
            ],
            encoding="utf-8",
            stdout=subprocess.PIPE,
        )
    else:
        cp = subprocess.run(
            [
                "helm",
                "install",
                "--set",
                "service.type=ClusterIP,persistence.storageClass=longhorn,resources.requests.cpu=null,persistence.size=2Gi,mariadb.primary.persistence.size=2Gi",
                "--namespace=planetes",
                name,
                "bitnami/" + soft_name,
            ],
            encoding="utf-8",
            stdout=subprocess.PIPE,
        )
    if cp.returncode != 0:
        print("ls failed.", file=sys.stderr)
        sys.exit(1)
    return cp.stdout.split("\n")[0].replace("NAME: ", "")

def get_pod():
    cp = subprocess.run(
        ["helm", "list", "-n", "planetes", "--short"],
        encoding="utf-8",
        stdout=subprocess.PIPE,
    )
    return cp.stdout[:-1].split("\n")

def get_pass(name):
    cp = subprocess.run(
        "kubectl get secret -n planetes " + name + "-wordpress -o jsonpath=\"{.data.wordpress-password}\" | base64 --decode",
        encoding="utf-8",
        stdout=subprocess.PIPE,
        shell=True,
    )
    return cp.stdout

def delete_pod(name):
    try:
        cp = subprocess.run(
            ["helm", "delete", "--namespace", "planetes", name],
            encoding="utf-8",
            stdout=subprocess.PIPE,
        )
    except:
        pass
    try:
        pvdelete1 = subprocess.run(
            'kubectl get pvc -n planetes --no-headers -o custom-columns=":metadata.name"',
            capture_output=True,
            text=True,
            shell=True,
        )
        pvdelete2 = subprocess.run(
            ["grep", "data-" + name],
            capture_output=True,
            text=True,
            input=pvdelete1.stdout,
        )
        pvdelete3 = subprocess.run(
            ["tr", "-s", '"\n"', '" "'],
            capture_output=True,
            text=True,
            input=pvdelete2.stdout,
        )
        pvdelete4 = subprocess.run(
            ["kubectl", "delete", "pvc", "-n", "planetes", pvdelete3.stdout[:-1]]
        )
    except:
        pass
    # return cp.stdout

def get_used_port():
    cp = subprocess.run(
        [
            "kubectl",
            "get",
            "svc",
            "--all-namespaces",
            "-o",
            "go-template='{{range .items}}{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{\"\\n\"}}{{end}}{{end}}{{end}}'",
        ],
        encoding="utf-8",
        stdout=subprocess.PIPE,
    )
    ports = cp.stdout[1:-2].split("\n")
    print(f"return:{ports}")
    unusedport = []
    while len(unusedport) < 4:
        num = randint(30000, 32768)
        if num not in ports and num not in unusedport:
            unusedport.append(num)
    print(unusedport)
    return unusedport

def update_port(name: str, port: int):
    print(port)
    target1 = subprocess.run(
        'kubectl get service -n planetes --no-headers -o custom-columns=":metadata.name"',
        capture_output=True,
        text=True,
        shell=True,
    )
    target2 = subprocess.run(
        ["grep", name + "-"],
        capture_output=True,
        text=True,
        input=target1.stdout,
    )
    target3 = subprocess.run(
        ["grep", "-v", "mariadb"],
        capture_output=True,
        text=True,
        input=target2.stdout,
    )
    target_name = target3.stdout[:-1]

    if port == -1:
        print("reset_port")
        cp1 = subprocess.run(
            "kubectl patch service "
            + target_name
            + ' -n planetes -p \'{"spec":{"type": "ClusterIP"}}\'',
            shell=True,
            encoding="utf-8",
            stdout=subprocess.PIPE,
        )
    else:
        port_num = str(port)
        cp2 = subprocess.run(
            "kubectl patch service "
            + target_name
            + ' -n planetes --type=json -p=\'[{"op": "replace", "path": "/spec/type", "value": "NodePort"}]\'',
            shell=True,
            encoding="utf-8",
            stdout=subprocess.PIPE,
        )
        cp1 = subprocess.run(
            "kubectl patch service "
            + target_name
            + ' -n planetes --type=json -p=\'[{"op": "replace", "path": "/spec/ports/0/nodePort", "value":'
            + port_num
            + "}]'",
            shell=True,
            encoding="utf-8",
            stdout=subprocess.PIPE,
        )
    return cp1.stdout

def get_status(names: list):
    all_status = pod_status.pod_status()
    result = []
    for name in names:
        status = True
        flag = False
        for i in all_status.items():
            if i[0].startswith(name):
                flag = True
                if not all(i[1]):
                    status = False
        if flag == False:
            status = False
        result.append(status)
    return result


# -*- coding: utf-8 -*-
'''stuf utilities.'''

from uuid import uuid4
from threading import Lock
from pickletools import genops
from itertools import count, repeat
from functools import update_wrapper, partial

from .base import importer, first, norm
from .six import (
    PY3, items, isstring, func_code, b, next, intern, rcompile, pickle, u)

# first slug pattern
one = partial(rcompile(r'[^\w\s-]').sub, '')
# second slug pattern
two = partial(rcompile(r'[-\s]+').sub, '-')
# counter
count = partial(next, count())
# light weight  range
lrange = partial(repeat, None)
# unique identifier selection
unique_id = lambda: b(uuid4().hex.upper())
# return one or all values
oneorall = lambda value: value[0] if len(value) == 1 else value

def diff(current, past):
    '''Difference between `past` and `current` ``dicts``.'''
    intersect = set(current).intersection(set(past))
    changed = set(o for o in intersect if past[o] != current[o])
    return dict((k, v) for k, v in items(current) if k in changed)

def lazyimport(path, attribute=None, i=importer, s=isstring):
    '''
    Deferred module loader.

    :argument path: something to load
    :keyword str attribute: attribute on loaded module to return
    '''
    return importer(path, attribute) if s(path) else path

# import loader
lazyload = partial(
    lambda y, z, x: y(x) if z(x) and '.' in x else x,
    lazyimport,
    isstring,
)

def lru(maxsize=100):
    '''
    Least-recently-used cache decorator.

    If *maxsize* is set to None, the LRU features are disabled and the cache
    can grow without bound.

    Arguments to the cached function must be hashable.

    Access the underlying function with f.__wrapped__.

    See:  http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used

    By Raymond Hettinger
    '''
    def decorator(call):
        cache = dict()
        items_ = items
        repr_ = repr
        intern_ = intern
        # bound method to lookup key or return None
        cache_get = cache.get
        # localize the global len() function
        len_ = len
        # because linkedlist updates aren't threadsafe
        lock = Lock()
        # root of the circular doubly linked list
        root = []
        # make updateable non-locally
        nonlocal_root = [root]
        # initialize by pointing to self
        root[:] = [root, root, None, None]
        # names for the link fields
        PREV, NEXT, KEY, RESULT = 0, 1, 2, 3
        if maxsize is None:
            def wrapper(*args, **kw):
                # simple caching without ordering or size limit
                key = repr_(args, items_(kw)) if kw else repr_(args)
                # root used here as a unique not-found sentinel
                result = cache_get(key, root)
                if result is not root:
                    return result
                result = call(*args, **kw)
                cache[intern_(key)] = result
                return result
        else:
            def wrapper(*args, **kw):
                # size limited caching that tracks accesses by recency
                key = repr_(args, items_(kw)) if kw else repr_(args)
                with lock:
                    link = cache_get(key)
                    if link is not None:
                        # record recent use of the key by moving it to the
                        # front of the list
                        root, = nonlocal_root
                        link_prev, link_next, key, result = link
                        link_prev[NEXT] = link_next
                        link_next[PREV] = link_prev
                        last = root[PREV]
                        last[NEXT] = root[PREV] = link
                        link[PREV] = last
                        link[NEXT] = root
                        return result
                result = call(*args, **kw)
                with lock:
                    root = first(nonlocal_root)
                    if len_(cache) < maxsize:
                        # put result in a new link at the front of the list
                        last = root[PREV]
                        link = [last, root, key, result]
                        cache[intern_(key)] = last[NEXT] = root[PREV] = link
                    else:
                        # use root to store the new key and result
                        root[KEY] = key
                        root[RESULT] = result
                        cache[intern_(key)] = root
                        # empty the oldest link and make it the new root
                        root = nonlocal_root[0] = root[NEXT]
                        del cache[root[KEY]]
                        root[KEY] = None
                        root[RESULT] = None
                return result
        def clear():
            # clear the cache and cache statistics
            with lock:
                cache.clear()
                root = first(nonlocal_root)
                root[:] = [root, root, None, None]
        wrapper.__wrapped__ = call
        wrapper.clear = clear
        try:
            return update_wrapper(wrapper, call)
        except AttributeError:
            return wrapper
    return decorator

def memoize(f, i=intern, z=items, r=repr, uw=update_wrapper):
    '''Memoize function.'''
    f.cache = {}.setdefault
    if func_code(f).co_argcount == 1:
        memoize_ = lambda arg: f.cache(i(r(arg)), f(arg))
    else:
        def memoize_(*args, **kw):  # @IgnorePep8
            return f.setdefault(
                i(r(args, z(kw)) if kw else r(args)), f(*args, **kw)
            )
    return uw(f, memoize_)

def optimize(
    obj,
    S=StopIteration,
    b_=b,
    d=pickle.dumps,
    g=genops,
    n=next,
    p=pickle.HIGHEST_PROTOCOL,
    s=set,
):
    '''
    Optimize a pickle string by removing unused PUT opcodes.

    Raymond Hettinger Python cookbook recipe # 545418
    '''
    # set of args used by a GET opcode
    this = d(obj, p)
    gets = s()
    # (arg, startpos, stoppos) for the PUT opcodes set to pos if previous
    # opcode was a PUT
    def iterthing(gadd=gets.add, this=this, g=g, n=n):  # @IgnorePep8
        prevpos, prevarg = None, None
        try:
            nextr = g(this)
            while 1:
                opcode, arg, pos = n(nextr)
                if prevpos is not None:
                    yield prevarg, prevpos, pos
                    prevpos = None
                if 'PUT' in opcode.name:
                    prevarg, prevpos = arg, pos
                elif 'GET' in opcode.name:
                    gadd(arg)
        except S:
            pass
    # copy the pickle string except for PUTS without a corresponding GET
    def iterthingy(iterthing=iterthing(), this=this, n=n):  # @IgnorePep8
        i = 0
        try:
            while 1:
                arg, start, stop = n(iterthing)
                yield this[i:stop if (arg in gets) else start]
                i = stop
        except S:
            pass
        yield this[i:]
    return b_('').join(iterthingy())

moptimize = memoize(optimize)

if PY3:
    ld = loads = memoize(lambda x: pickle.loads(x, encoding='latin-1'))

    def sluggify(value, n=norm, o=one, t=two):
        '''
        Normalize `value`, convert to lowercase, remove non-alpha characters,
        and convert spaces to hyphens.
        '''
        return t(o(n(value)).strip().lower())
else:
    ld = loads = memoize(lambda x: pickle.loads(x))

    def sluggify(value, n=norm, o=one, t=two):
        '''
        Normalize `value`, convert to lowercase, remove non-alpha characters,
        and convert spaces to hyphens.
        '''
        return t(u(o(n(u(value)).encode('ascii', 'ignore')).strip().lower()))


import torch
import torch.nn as nn
import math

"""
原理：
    1.对输入进来的特征层进行全局平均池化
    2.进行两次全连接
    3.再取一次sigmoid将值固定到0-1之间
    4.最后将这个权值*原输入特征层
"""
class se_block(nn.Module):
    # channel表示输入进来的通道数；ratio表示缩放的比例，用于第一次全连接
    def __init__(self,channel,ratio=16):
        super(se_block, self).__init__()  # 初始化
        self.avg_pool = nn.AdaptiveAvgPool2d(1) # 自适应全局平均池化，输出高宽为1
        # 两次全连接fc
        self.fc = nn.Sequential(
            # 定义第一次全连接，神经元个数减少
            # 输入神经元个数channel个数，输出神经元个数channel//ratio,不使用偏执量
            nn.Linear(channel, channel // ratio, bias=False),
            nn.ReLU(inplace=True),
            # 定义第一次全连接，神经元个数变为原来个数
            # 输入神经元个数个数channel//ratio，输出神经元个数channel,不使用偏执量
            nn.Linear(channel // ratio, channel, bias=False),
            nn.Sigmoid()
        )

    def forward(self,x):
        # 计算输入进来的特征层的size,batch_size,通道数，高，宽，bath_size表示一次训练所抓取的数据样本数量
        b,c,h,w = x.size()
        # 全局平均池化，结果为y(b,c,1,1),即去掉后面的两个维度
        # view(b,c)：进行reshape，即只保留b,c
        y = self.avg_pool(x).view(b,c)
        # 进行两次全连接fc,b,c->b,c//ratio->b,c
        # reshape:b,c->b,c,1,1
        y = self.fc(y).view(b,c,1,1)
        # 把两次全连接的结果*特征层
        return x * y

if __name__ == '__main__':
    x = torch.rand(1,96,112,112)
    model = se_block(96)
    output = model(x)
    print(output)


class ListNode:
    def __init__(self, val, next_node=None):
        self.val = val
        self.next = next_node

    def __str__(self):
        out, cur = '', self
        while cur:
            out += str(cur.val) + "->"
            cur = cur.next
        return out[:-2]

class SinglyLinkedList:
    def __init__(self, from_list=[]):
        # Dummy node
        self.head = ListNode(-1)
        self.tail = self.head

        for elem in from_list:
            self.insert_tail(elem)

    def get(self, index: int) -> int:
        curr = self.head.next
        i = 0
        while curr:
            if i == index:
                return curr.val
            i += 1
            curr = curr.next
        return -1  # Index out of bounds

    def insert_head(self, val: int) -> None:
        new_node = ListNode(val)
        new_node.next = self.head.next
        self.head.next = new_node
        if not new_node.next:  # if list was empty before inserting
            self.tail = new_node

    def insert_tail(self, val: int) -> None:
        self.tail.next = ListNode(val)
        self.tail = self.tail.next

    def remove(self, index: int) -> bool:
        i = 0
        curr = self.head
        while i < index and curr:
            # move curr to node before target node
            i += 1
            curr = curr.next

        if index == 0:
            self.head.next = self.head.next.next
        elif index > 0 and curr and curr.next:
            if curr.next == self.tail:
                self.tail = curr
            curr.next = curr.next.next
            return True
        return False

    def __str__(self):
        return str(self.head.next)

sll = SinglyLinkedList([1,2,3,5,6,7])
# sll.insert_tail(1)
# sll.insert_tail(2)
# sll.insert_tail(3)
print(sll)


import jsonschema
import unittest
import json

class JsonManager:

    @staticmethod
    def validate(schema, data):
        '''
        Validate schema file or json against file or json

        '''
        if isinstance(schema, str):
            f = open(schema)
            schema = json.load(f)
            f.close()

        if isinstance(data, str):
            f = open(data)
            data = json.load(f)
            f.close()

        try:
            jsonschema.validate(data, schema=schema)
            return True
        except Exception as e:
            raise Exception(e.__str__)
            return False

class TestJsonManager(unittest.TestCase):
    def test_validate(self):
        schema = {
            "type": "object",
            "properties": {
                "price": {"type": "number"},
                "name": {"type": "string"},
            }
        }
        data = {
            "name": "ABC",
            "price": 1.0
        }
        try:
            self.assertTrue(JsonManager.validate(schema, data))
        except Exception as e:
            print(e.message)
            self.fail()
if __name__ == '__main__':
    unittest.main()


'''
time:
    init O(N)
    convertAbb O(1)
    isUnique O(1) or O(N)
space: O(N)
'''

class ValidWordAbbr:

    def __init__(self, dictionary: List[str]):
        self.reverseMap = collections.defaultdict(list)
        self.countMap = collections.defaultdict(int)

        for d in dictionary:
            abb = self.convertAbb(d)
            self.reverseMap[abb].append(d)
            self.countMap[abb] += 1

    def convertAbb(self, word):
        if len(word) > 2:
            return word[0] + str(len(word) - 2) + word[-1]
        else:
            return word

    def isUnique(self, word: str) -> bool:
        abb = self.convertAbb(word)
        if self.countMap[abb] == 0:
            return True
        elif all(a == word for a in self.reverseMap[abb]):
            return True
        else:
            return False

# Your ValidWordAbbr object will be instantiated and called as such:
# obj = ValidWordAbbr(dictionary)
# param_1 = obj.isUnique(word)


from django.contrib.auth.models import User
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from .models import Ngo
# Create your models here.

# @receiver(post_save, sender=Profile) # another way of producing signals like "post_save.connect()"
def profileCreated(sender, instance, created, **kwargs):
    print("Profile Signal triggered")
    if created:
        user = instance
        name=user.username
        email=user.email
        # form = Ngo(name=name,email=email)
        # form.save()
        profile = Ngo.objects.create(name = user, email=user.email)
        print("Profile Created")
    print("Instance", instance)
    print("Created", created)

# def profileDeleted(sender, instance, **kwargs):
#     user = instance.user
#     user.delete()
#     # print("Deleting User ....")

post_save.connect(profileCreated, sender=User)

# post_delete.connect(profileDeleted,sender=Ngo)


import re
from sys import exit

from words import Word

class Round:
    """
    Represents a round of guessing a word.
    """

    def __init__(self, word: str, chances: int):
        """Sets up data pertaining to the round."""

        self.__word = Word(word)
        self.__chances = chances

        self.__hints = self.__load_hints()

        self.__guessed_letters = self.__load_guessed_letters(
            self.__word.get_letters_sort_freq())

        # Holds incorrect guesses.
        self.__wrong_letters = list()

        self.__active = True

        # True iff the word was guessed.
        self.__success = False

    def run(self) -> bool:
        """
        Starts the round. Ends if the word is guessed or chances run out.

        Returns a bool indicating whether the word was guessed.
        """

        while self.__active:
            user_input = self.__get_valid_user_input()

            self.__process_input(user_input)
            self.__update_status()

            print(79 * '_')

        return self.__success

    def __get_valid_user_input(self) -> str:
        """Prompts the user for input until a valid input."""

        error = '\nInvalid input!'

        # Loops until valid input.
        while True:
            print(self.__get_prompt())

            try:
                # User may input uppercase letters and all words consist of
                # lowercase letters, so user's input must be made lowercase.
                user_input = input('\n>>> ').lower()
            except (EOFError, KeyboardInterrupt):
                exit()

            # Validates user input.
            if len(user_input) > 1 or len(user_input) <= 0:
                print(f'{error} Enter ONE character.')
                continue
            elif re.search("[^a-z1-2]", user_input):
                print(f'{error}')
                continue
            # Checks if user's input has already been used as either an
            # incorrect or correct guess.
            elif user_input in self.__wrong_letters \
                    or \
                    (user_input in self.__guessed_letters
                    and self.__guessed_letters[user_input]):

                print('\nLetter already used!')
                continue
            # If there are no hints available, '1' or '2' should not be
            # inputted.
            elif len(self.__hints) <= 0 and \
                    (user_input == '1' or user_input == '2'):

                print(f'{error} No hints available.')
                continue
            elif len(self.__hints) <= 1 and (user_input == '2'):
                print(f'{error} Hint #2 not available.')
                continue
            # User's input was valid.
            else:
                break

        return user_input

    def __get_prompt(self) -> str:
        """
        Returns the prompt for input.
        """

        num_hints = len(self.__hints)

        prompt = '\nEnter a letter[a-zA-Z]'

        if num_hints > 0:
            prompt += " or '1' for Hint #1"

        if num_hints > 1:
            prompt += " or '2' for Hint #2"

        prompt += '\n'

        for letter in self.__word.get_content():
            # If the 'letter' has been guessed.
            if self.__guessed_letters[letter]:
                prompt += letter + ' '
            else:
                prompt += '_ '

        prompt += f'\n\nIncorrect letters: {self.__wrong_letters}\n'

        prompt += f'{self.__chances} chances left'

        return prompt

    def __process_input(self, user_input: str):
        """Takes proper actions based on user's input."""

        if user_input == '1' or user_input == '2':
            hint_letter = self.__hints.pop(int(user_input) - 1)

            # Allows the hint letter to be visible in the next prompt.
            self.__guessed_letters[hint_letter] = True

            return

        for letter in self.__guessed_letters:
            # If user's input is in the word.
            if user_input == letter:
                self.__guessed_letters[letter] = True
                return

        # If user's input is not in the word.
        else:
            self.__wrong_letters.append(user_input)
            self.__chances -= 1

    def __update_status(self):
        """Determines whether the round is still active or not."""

        if self.__chances <= 0:
            self.__active = False
            return

        for letter in self.__guessed_letters:
            # If there are any letters which have not yet been guessed,
            # round should remain active.
            if not self.__guessed_letters[letter]:
                return
        else:
            self.__active = False

    def __load_guessed_letters(self, letter_set) -> dict:
        """
        Sets up a dictionary with letters and their guessed status
        as keys and values, respectively.
        """

        guessed_letters = dict()

        for key in letter_set:
            guessed_letters[key[0]] = False

        return guessed_letters

    def __load_hints(self) -> list:
        """
        Returns zero, one, or two hint(s) as a list depending on the number
        of unique characters in the word.

        The hints are a frequently occurring letter in the word.
        """

        word_uniq_count = self.__word.get_unique_count()
        hints = list()

        if word_uniq_count > 3:
            hints += self.__word.get_freq_letter(),

        if word_uniq_count > 6:
            hints += self.__word.get_freq_letter(1),

        return hints


import pyinputplus as pyip
import random, time

def mutiply():
    nqs = 10
    score = 0
    for questionNumber in range(nqs):
        num1 = random.randint(0, 9)
        num2 = random.randint(0, 9)
        prompt = '#%s: %s x %s = ' % (questionNumber, num1, num2)
        try:
            pyip.inputStr(prompt, allowRegexes=['^%s$' % (num1 * num2)],blockRegexes=[('.*', 'Incorrect!')],
            timeout=8, limit=3)
        except pyip.TimeoutException:
            print('Too late !')
        except pyip.RetryLimitException:
            print('You have reached your retry limit !')
        else:
            print('Congratulations it\'s correct!!')
            score += 1
            time.sleep(1)
            print('Score: %s / %s' % (score, nqs))


n, m = map(int,(input().split()))

num = list(map(int, input().split())) # 카드 숫자 리스트

result = 0
Max = 0

for i in range(n-2): # 3중 for문을 돌면서 겹치지 않게 범위를 지정
    for j in range(i+1,n-1):
        for k in range(j+1,n):
            if num[i]+num[j]+num[k] > m: # 3개의 값 더한것이 m보다 크다면 넘어감
                continue
            else:
                result = num[i]+num[j]+num[k]
                if Max <= result: # m과 가장 유사한 값은 가장 큰 값이기 때문에 비교해서 큰값을 저장
                    Max = result

print(Max)


from django.db import models

class User (models.Model):
    """This class represents the user model."""
    name = models.CharField(
        max_length=30
    )

    email = models.EmailField(
        max_length=30,
        unique=True
    )

    creation_time = models.DateTimeField(
        auto_now_add=True
    )

    def __str__(self):
        """Return a human readable representation of the model instance."""
        return "{}".format(self.name)


import json
import logging, logging.handlers, sys

from time import time

import shodan
from shodan import Shodan

from . import helper, misphandler

def shodan_cleanup_rules():
    # IOCs with these types of keys and values will be ignored from being created
    # e.g. IP 192.168.1.1 is extracted from autonomous_system_value key
    # ips['keys']['startswith']['autonomous_system'] will cause it to be scrubbed
    # ips['values']['endswith']['2.2.2', '168.1.1'] will cause it to be scrubbed
    cleanup_rules = {
        'ips': {
            'keys' : {
                'startswith': ['autonomous_system'],
                'endswith': ['source_ip'],
                'equals': [],
                'contains': []
            },
            'values': {
                'startswith': [],
                'endswith': [],
                'equals': [],
                'contains': []
            }

        },
        'emails':{
            'keys': {
                'startswith': [],
                'endswith': [],
                'equals': [],
                'contains': []
            },
            'values': {
                'startswith': [],
                'endswith': ['@openssh.com', '@libssh.org'],
                'equals': ['rijndael-cbc@lysator.liu.se', 'rijndael-cbc@lysator.liu'],
                'contains': []
            }
        },
        'domains':{
            'keys': {
                'startswith': [],
                'endswith': [],
                'equals': [],
                'contains': []
            },
            'values': {
                'startswith': [],
                'endswith': [
                    'w3.org',
                    'launchpad.net',
                    'debian.org',
                    '.lencr.org',
                    '.robotstxt.org'
                ],
                'equals': [],
                'contains': []
            }
        },
        'urls':{
            'keys': {
                'startswith': [],
                'endswith': [],
                'equals': [],
                'contains': []
            },
            'values': {
                'startswith': [
                    'http://www.w3.org/',
                    'http://manpages.debian.org/',
                    'https://bugs.launchpad.net/',
                    'http://r3.o.lencr.org',
                    'http://www.robotstxt.org/',
                    'http://crt.sectigo.com/',
                    'https://sectigo.com/'
                ],
                'endswith': [],
                'equals': [],
                'contains': [
                    '.godaddy.com/'
                ]
            }
        }
    }

    return cleanup_rules

def shodan_clean_json_keys():
    # This adds a set of keywords to remove for clean comparison of changes
    # across time. e.g. when taking the hash of two blobs of censys data, the
    # hash would change if they both had different time_scraped values. So we
    # want to remove those before the comparison.
    # Looks for keys that END WITH the follow values

    ignored_keys = {
        "startswith": [],
        "endswith": [
            "timestamp",
            "_shodan",
            "last_update",
            "_id",
            "_asn",
            "_isp"
        ],
        "equals": [],
        "contains": [
            "_shodan_",
            "_opts_",
            "_location_",
            "_references_"
        ]
    }

    return ignored_keys

def shodan_search(mh, search):
    mh.logger.debug(f"Running SHODAN search {search}")
    raw = {}
    ips = []
    shodan_api = Shodan(mh.shodan_key)

    if mh.do_it_live:
        mh.logger.debug(f"Using LIVE API query to search SHODAN...")
        # Get rate_limit for this service
        rate_limit = mh.shodan_rate
        try:

            # Sleep {rate_limit} seconds for each time the search is run
            helper.rate_respect(mh, mh.search_time, rate_limit)
            mh.search_time = time()
            raw = shodan_api.search(query=f"{search}")
            mh.shodan_api_counter+=1
            mh.logger.debug(f"\n\n#### TOTAL SHODAN API CALLS NOW {mh.shodan_api_counter}! \n\n")
            mh.logger.debug(f"SHODAN got a 200 OK for {search}!")

        except shodan.APIError:
            mh.logger.error(f"Error - API timed out. Trying again...")
            try:
                helper.rate_respect(mh, mh.search_time, rate_limit+1)
                mh.search_time = time()
                raw = shodan_api.search(query=f"{search}")
                mh.shodan_api_counter+=1
                mh.logger.debug(f"\n\n#### TOTAL SHODAN API CALLS NOW {mh.shodan_api_counter}! \n\n")
                mh.logger.debug(f"SHODAN got a 200 OK for {search}!")

            except Exception as e:
                mh.logger.error(f"Error searching SHODAN for query {search}: {e}")
                # raise Exception(e)
                return ips

        except Exception as e:
            mh.logger.error(f"Error searching SHODAN for query {search}: {e}")
            # raise Exception(e)
            return ips

    else:
        # DEBUGGER - DUMMY DATA
        mh.logger.debug(f"do_it_live==False - using dummy data")
        raw = {'matches': [{'ip': 123456789, 'product': 'nginx', 'total': 1}]}

    # for r in parse_res['results']:
    if 'matches' in raw:
        for match in raw['matches']:
            if 'ip_str' in match:
                if match['ip_str'] not in ips:
                    ips.append(match['ip_str'])

    return ips

def shodan_search_ip(mh, host_obj):
    ip = misphandler.get_attr_val_by_rel(host_obj, 'host-ip')
    service = "shodan"

    mh.logger.debug(f"Getting raw JSON data for {ip}")
    raw = {}
    shodan_api = Shodan(mh.shodan_key)

    if not mh.do_it_live:
        ### FOR DEBUGGING
        mh.logger.debug(f"do_it_live==False - using dummy data")
        raw = {'region_code': '16', 'tags': ['cloud'], 'ip': 1234567890, 'area_code': None, 'domains': ['linode.com'], 'postal_code': None, 'dma_code': None, 'org': 'Linode, LLC', 'ip_str': '192.168.1.100'}
        return raw

    # Get rate_limit for this service
    rate_limit = mh.shodan_rate
    fresh_json = misphandler.check_json_freshness(mh, host_obj, service)
    if fresh_json:
        return fresh_json

    mh.logger.debug(f"Discovered no fresh JSON blobs that are appropriate for reuse.")
    mh.logger.debug(f"Using LIVE API query to reach out to Shodan and get IP data...")

    try:
        # Sleep {rate_limit} seconds for each time the search is run
        helper.rate_respect(mh, mh.search_time, rate_limit)
        mh.search_time = time()
        raw = shodan_api.host(ip)
        mh.shodan_api_counter+=1
        mh.logger.debug(f"\n\n#### TOTAL SHODAN API CALLS NOW {mh.shodan_api_counter}! \n\n")
        # raw = json.loads(res)
        if mh.debugging:
            mh.logger.debug(f"Results for {ip}: \n\n{raw}")

    except shodan.APIError:
        mh.logger.error(f"Error - API timed out. Trying again...")
        try:
            helper.rate_respect(mh, mh.search_time, rate_limit+1)
            mh.search_time = time()
            raw = shodan_api.host(ip)
            mh.shodan_api_counter+=1
            mh.logger.debug(f"\n\n#### TOTAL SHODAN API CALLS NOW {mh.shodan_api_counter}! \n\n")
            # raw = json.loads(res)
            if mh.debugging:
                mh.logger.debug(f"Results for {ip}: \n\n{raw}")

        except Exception as e:
            mh.logger.error(f"Error getting IP {ip}: {e}")
            # raw = {"error": "IP Not Found"}
            return False

    '''
    except Exception as e:
        mh.logger.error(f"Error getting IP {ip}: {e}")
        # raw = {"error": "IP Not Found"}
        return False
    '''

    return raw

def shodan_search_cert_hosts(mh, cert):
    # hunt_type = 'censys-v2'
    mh.logger.debug(f"Getting raw JSON data from SHODAN for {cert}")
    raw = {}
    ips = []
    shodan_api = Shodan(mh.shodan_key)

    if mh.do_it_live:

        mh.logger.info(f"Using LIVE API query to reach out to SHODAN and find hosts associated with cert {cert}...")
        # Sleep {rate_limit} seconds for each time the search is run
        rate_limit = mh.shodan_rate
        try:
            # rate_limit = helper.get_rate_limit(mh, 'censys')
            helper.rate_respect(mh, mh.search_time, rate_limit)
            mh.search_time = time()
            # raw = shodan_api.search(query=f"ssl.cert.fingerprint:\"{cert}\"")
            # ^^ only works with SHA1 and I'm trying to keep it uniform.
            raw = shodan_api.search(query=f"ssl:\"{cert}\"")
            mh.shodan_api_counter+=1
            mh.logger.debug(f"\n\n#### TOTAL SHODAN API CALLS NOW {mh.shodan_api_counter}! \n\n")
            mh.logger.debug(f"SHODAN got a 200 OK for {cert}!")

        except shodan.APIError:
            mh.logger.error(f"Error - API timed out. Trying again...")
            try:
                helper.rate_respect(mh, mh.search_time, rate_limit+1)
                mh.search_time = time()
                raw = shodan_api.search(query=f"ssl:\"{cert}\"")
                mh.shodan_api_counter+=1
                mh.logger.debug(f"\n\n#### TOTAL SHODAN API CALLS NOW {mh.shodan_api_counter}! \n\n")
                mh.logger.debug(f"SHODAN got a 200 OK for {cert}!")

            except Exception as e:
                mh.logger.error(f"Error searching SHODAN for certificate {cert}: {e}")
                return ips

        except Exception as e:
            mh.logger.error(f"Error searching SHODAN for certificate {cert}: {e}")
            return ips

    #### FOR DEBUGGING
    else:
        mh.logger.debug(f"do_it_live==False - using dummy data")
        raw = {'matches': [{'ip': 123456789, 'product': 'nginx', 'total': 1}]}

    if 'matches' in raw:
        for match in raw['matches']:
            if 'ip_str' in match:
                ips.append(match['ip_str'])

    return ips

def shodan_extract_certs(mh, iocs, new_res):
    mh.logger.debug(f"Extracting certificate IOCs from Shodan data...")
    cert_fingerprint_pattern = r"(\d+_ssl_cert_fingerprint_sha256)"
    cert_name_pattern = r"\d+_ssl_cert_subject_CN"

    iocs = helper.parse_cert(mh, cert_fingerprint_pattern, cert_name_pattern, iocs, new_res)
    return iocs