import torch

from hooks.transformer.vit import ViTAttHookHolder
from model import model_library
from utils import exp_starter_pack
from datasets import weird_image_net

def main():
    exp_name, args, _ = exp_starter_pack()
    model, image_size, batch_size, name = model_library[34]()
    eval = weird_image_net.eval()

    hooks = ViTAttHookHolder(model, True, True, True, True, True, True)

    """ Result: 18 """
    # images, labels = [], []
    # for i in range(1000):
    #     x, y = eval[i]
    #     images.append(x)
    #     labels.append(y)
    #
    #     xs = torch.stack(images).cuda()
    #     with torch.no_grad():
    #         _ = hooks(xs)
    #         print(f'Can be done: {len(xs)} w/o grad')

    """ Result: 10 """
    images, labels = [], []
    for i in range(1000):
        x, y = eval[i]
        images.append(x)
        labels.append(y)

        xs = torch.stack(images).cuda()
        cl = xs.clone()
        cl.requires_grad_()
        _, out = hooks(cl)
        out.sum().backward()
        print(f'Can be done: {len(xs)} w/ grad')

if __name__ == '__main__':
    main()


import json
import time
import requests
import random
import easygui

def get_like(tlp: tuple):
    return tlp[2]

input = easygui.enterbox("请输入作品ID")

aid: int = input
i = 0
all_comments = []
like_sort_mode = True
print(f'aid: {aid}')

while 1:
    i += 1
    data = requests.get(f'http://api.bilibili.com/x/v2/reply?jsonp=jsonp&pn={i}&type=1&oid={aid}').json()
    print('len: ', len(data['data']['replies']))
    if len(data['data']['replies']) < 1:
        break
    else:
        all_comments.extend(data['data']['replies'])
    time.sleep(random.uniform(0.8, 1.2))

print('oh i finished step 1')
filter_data = []

for i in range(len(all_comments)):
    msg = all_comments[i]['content']['message']
    if len(msg) >= 20 or '建议' in msg or '觉得' in msg or '看法' in msg:
        filter_data.append((all_comments[i]['member']['uname'], all_comments[i]['content']['message'], all_comments[i]['like']))

if like_sort_mode:
    filter_data = sorted(filter_data, key=get_like, reverse=True)
print('step 2')

with open(f'49_comments_output_av{aid}.txt', 'w', encoding='u8') as f:
    for i in filter_data:
        # json.dumps(filter_data, ensure_ascii=False)
        f.write(f'{i[0]}:\n{i[1]}\n')
        f.write(f'[👍 点赞数] {i[2]}')
        f.write('\n==========================================\n')


from src.DoubleLinkedList import DoubleLinkedList

def test_initialization():
    dll: DoubleLinkedList = DoubleLinkedList()
    assert dll.head is None
    assert dll.tail is None

def test_empty_after_removing_elements():
    dll: DoubleLinkedList = DoubleLinkedList()
    dll.add_element("1", "bananas")
    dll.delete_oldest()
    assert dll.head is None
    assert dll.tail is None

def test_empty_then_add_element():
    dll: DoubleLinkedList = DoubleLinkedList()
    dll.add_element("1", "bananas")
    dll.delete_oldest()
    node = dll.add_element("2", "apples")
    assert dll.head == node
    assert dll.tail == node
    assert dll.get_length() == 1

def test_delete_oldest():
    dll: DoubleLinkedList = DoubleLinkedList()
    oldest_value: str = "bananas"
    dll.add_element("1", oldest_value)
    dll.add_element("2", "strawberries")
    dll.add_element("3", "mangos")
    oldest = dll.delete_oldest()
    assert oldest.value == oldest_value

def test_delete_head_node():
    dll: DoubleLinkedList = DoubleLinkedList()
    first_head_node = dll.add_element("1", "bananas")
    expected_head_node = dll.add_element("2", "strawberries")
    dll.add_element("3", "mangos")
    dll.delete_node(first_head_node)
    assert dll.head == expected_head_node
    assert dll.get_length() == 2

def test_delete_tail_node():
    dll: DoubleLinkedList = DoubleLinkedList()
    dll.add_element("1", "bananas")
    expected_tail_node = dll.add_element("2", "strawberries")
    last_tail_node = dll.add_element("3", "mangos")
    dll.delete_node(last_tail_node)
    assert dll.tail == expected_tail_node
    assert dll.get_length() == 2

def test_delete_node_in_the_middle():
    dll: DoubleLinkedList = DoubleLinkedList()
    expected_head_node = dll.add_element("1", "bananas")
    node_to_be_deleted = dll.add_element("2", "strawberries")
    expected_tail_node = dll.add_element("3", "mangos")
    dll.delete_node(node_to_be_deleted)
    assert dll.head == expected_head_node
    assert dll.tail == expected_tail_node
    assert dll.get_length() == 2


import os
import sys
import signal
import socket
import datetime

import ftrack_api

from openpype_modules.ftrack.ftrack_server.ftrack_server import FtrackServer
from openpype_modules.ftrack.ftrack_server.lib import (
    SocketSession,
    ProcessEventHub,
    TOPIC_STATUS_SERVER
)
from openpype.modules import ModulesManager

from openpype.lib import (
    Logger,
    get_openpype_version,
    get_build_version
)

subprocess_started = datetime.datetime.now()

class SessionFactory:
    session = None

def send_status(event):
    subprocess_id = event["data"].get("subprocess_id")
    if not subprocess_id:
        return

    if subprocess_id != os.environ["FTRACK_EVENT_SUB_ID"]:
        return

    session = SessionFactory.session
    if not session:
        return

    new_event_data = {
        "subprocess_id": subprocess_id,
        "source": "processor",
        "status_info": [
            ["created_at", subprocess_started.strftime("%Y.%m.%d %H:%M:%S")],
            ["OpenPype version", get_openpype_version() or "N/A"],
            ["OpenPype build version", get_build_version() or "N/A"]
        ]
    }

    new_event = ftrack_api.event.base.Event(
        topic="openpype.event.server.status.result",
        data=new_event_data
    )

    session.event_hub.publish(new_event)

def register(session):
    '''Registers the event, subscribing the discover and launch topics.'''
    session.event_hub.subscribe(
        "topic={}".format(TOPIC_STATUS_SERVER), send_status
    )

def main(args):
    log = Logger.get_logger("Event processor")

    port = int(args[-1])
    # Create a TCP/IP socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # Connect the socket to the port where the server is listening
    server_address = ("localhost", port)
    log.debug("Processor connected to {} port {}".format(*server_address))
    sock.connect(server_address)

    sock.sendall(b"CreatedProcess")

    returncode = 0
    try:
        session = SocketSession(
            auto_connect_event_hub=True, sock=sock, Eventhub=ProcessEventHub
        )
        register(session)
        SessionFactory.session = session

        manager = ModulesManager()
        ftrack_module = manager.modules_by_name["ftrack"]
        server = FtrackServer(
            ftrack_module.server_event_handlers_paths
        )
        log.debug("Launched Ftrack Event processor")
        server.run_server(session)

    except Exception:
        returncode = 1
        log.error("Event server crashed. See traceback below", exc_info=True)

    finally:
        log.debug("First closing socket")
        sock.close()
        return returncode

if __name__ == "__main__":
    # Register interupt signal
    def signal_handler(sig, frame):
        print("You pressed Ctrl+C. Process ended.")
        sys.exit(0)

    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    sys.exit(main(sys.argv))


# ADMIN
admin_panel_ru = (
    "Мы есть🫵"
)

admin_not_commands_ru = (
    "Пока рано для команд создатель!",
    "Давай сначала сделаем публикацию😎",
)

admin_post_ru = (
    "Внимаю создатель🤩",
    "Вы точно уверены, что настал тот час для речи👑❓",

)

admin_switch_post_ru = (
    "Какой пост хотите опубликовать для всех пользователей❓🆕",
    "Miss click, понимаю🤭",
)

admin_enter_post_ru = (
    "Опубликовал💌",
)

admin_statistics_ru = (
    "Общая статистика📋:\n\n",
    "♦ Пользователей 🙆 - ",
    "♦ Лент запущено👂 - ",
    "♦ Каналов 🌍 - ",
    "♦ Кол-во пожеланий💬 - ",
)

admin_reset_wish_ru = (
    'Отправляю все пожелания пользователей📩',
)

admin_add_spam_word_ru = (
    'Мы внимаем👀',
    'Жду новые спам слова для моего друга - рекламного фильтра📁'
)

admin_delete_spam_word_ru = (
    'Мы слушаем👂',
    'Какие спам слова хотите удалить❓',
    'Для быстрого удаления воспользуйся /spam_words😉'
)

admin_spam_words_ru = ((
                         "Спам слова📂:\n",
                     ),
                     (
                         "Спам слова📂:\n\n"
                         "⚠Пусто"
                     ))

admin_enter_add_spam_word_ru = ((
                                  "Добавил✅",
                              ),
                              (
                                  "Такое слово уже есть",
                                  "Давай другое😁"

                              ))

admin_enter_delete_spam_word_ru = ((
                                  "Удалил✅",
                              ),
                              (
                                  "Такого спам слова нет в моих списках🤔",
                              ))

# USER
help_ru = (
    "Помощь, которую мы заслужили👇\n\n"
    "⌨ /menu - меню для быстрого вызова основных команд.\n\n"
    "🚀🛑 /on, /off - вкл/выкл ленту, состоящую из публикаций каналов, на которые ты подписался через меня.\n\n"
    "➕ /add - добавляет по очереди новые каналы в твои подписки.\n"
    "💭(Можно быстро скинуть мне ссылки на каналы с помощью пересылки в Telegram, не общаясь со мной лично.\n"
    "Главное - в конце не забудь отправить мне команду /end.)\n\n"
    "➖ /delete - удаляет по очереди каналы из твоих подписок.\n"
    "💭(После начала процесса можешь, для быстрого удаления, использовать команду /subscriptions, где уже будут временные"
    " команды на удаление каждой подписки.\n"
    "Главное - в конце не забудь отправить мне команду /end.)\n\n"
    "📋 /subscriptions - показывает твои подписки.\n\n"
    "💬 /wish - добавить пожелания для будущих обновлений."
)

menu_ru = (
    "Лови👾"
)

back_ru = (
    "Держи🥕"
)

end_ru = (
    "Принял🤝",
    "Воспользуйся /menu"
)

state_if_exist_ru = (
    "Все и сразу не бывает ♻",
    "Сначала закончи предыдущие действия!"
)

channel_not_exist_ru = (
    " больше не существует или стал приватным, "
    "поэтому он будет удален из ваших подписок⚠")

channel_on_protection = (
    " включил защиту на пересылку сообщений, "
    "поэтому он будет удален из ваших подписок⚠"
)

start_ru = ((
                "Тута👀",
                "❗ Для начала пришли мне хотя бы одну публичную ссылку на канал.",
                "💭(Ссылку на канал можешь найти на главной странице канала,"
                " если ее нет, то он приватный, c такими мы не дружим⚠)",
                "После того, как мы познакомимся, ты сможешь быстро прислать мне все остальные каналы😜",
                "💭(Напомню, после добавления каналов в твои подписки, можешь спокойно удалить эти каналы у себя в диалогах😎)",
            ),
            (
                "Мы уже начинали когда-то.",
                "Когда были моложе🤭"
            ))

enter_init_listen_ru = ((
                            "⚠Что-то, но не публичные ссылки каналов:\n",
                        ),
                        (
                            "👍Существующие каналы:\n",
                        ),
                        (
                            "Внеси исправления и снова скинь мне публичные cсылку на канал😈",
                        ),
                        (
                            "Все запомнил👌",
                            "Лента запущена🚀",
                            "Воспользуйся /help"
                        ))

start_tape_ru = ((
                     "Лента уже запущена😁",
                 ),
                 (
                     "Все хорошо, только добавь хотя бы один канал в свои подписки🤔",
                     "Воспользуйся /add"
                 ),
                 (
                     "Лента запущена🚀",
                 ))

stop_tape_ru = ((
                    "Лента остановлена🛑",
                ),
                (
                    "Как остановить то, что даже не было запущено😅",
                ))

add_listen_ru = (
    "Слушаю👂",
    "Скидывай по очереди публичные ссылки на каналы, которые хочешь добавить в свои подписки.",
    "💭(Ссылку на канал можешь найти на главной странице канала,"
    " если ее нет, то он приватный, c такими мы не дружим⚠)",
    f"Когда надоест, скажи просто \n /end"
)

enter_add_listen_ru = ((
                           "Что-то не похоже на публичную ссылку канала🤔",
                           "Исправь и снова скинь мне..."
                       ),
                       (
                           "Канал уже есть в твоих подписках...",
                           "Давай другой😁"
                       ),
                       (
                           "Добавил✅",
                       ))

delete_listen_ru = ((
                        "Внимаю:👏",
                        "Скидывай по очереди публичные ссылки на каналы,"
                        " которые хочешь удалить из своих подписок.",
                        "❗ Для быстрого удаления воспользуйся \n/subscriptions",
                        "Как закончишь, скажи просто \n/end"
                    ),
                    (
                        "Что мы решили удалить из подписок, если даже нет ни одной🤔",
                        "Воспользуйся /add"
                    ))

enter_delete_listen_ru = ((
                              "Пора закругляться, так как у тебя нет больше подписок🤔",
                              "Воспользуйся /add"
                          ),
                          (
                              "Удалил✅",
                          ),
                          (
                              "Такого канала нет в твоих подписках😅",
                          )
)

subscriptions_ru = ((
                        "Твои подписки📋:\n\n",
                    ),
                    (
                        "Твои подписки📋:\n\n"
                        "⚠Пусто"
                    ))

wish_ru = ((
               "Твое желание🔥🔥🔥\n\n",
           ),
           (
               "Хочешь исправить?",
           ),
           (
               "Что желаешь увидеть в будущих обновлениях?💬",
               "Учти, что я смогу учесть только одно сообщение, так что напиши развернуто👆",
               "💭(Если твое предыдущее пожелание бесследно исчезло,"
               " то значит я его переслал своему создателю на рассмотрение.)",
           ))

switch_wish_ru = ((
                      "Понял, внимаю😏",

                  ),
                  (
                      "Понял, побежали дальше по делам😎",
                  ),
                  (
                      "Ну ладно, cчитаю, что нет😈",
                  ))

enter_wish_ru = (
    "Принял👌",
    "В дальнейшем, если что, сможешь переправить😉"
)

echo_ru = (
    "Так, так, так, не флуди...👊",
    "Воспользуйся /help"
)

engineering_works_ru = (
    "Don't worry, проводятся технические работы👨💻",
    "А все, технические работы закончились🔥"
)

bot_messages_ru = {
    'help': help_ru,
    'end': end_ru,
    'state_if_exist': state_if_exist_ru,
    'channel_not_exist': channel_not_exist_ru,
    'channel_on_protection': channel_on_protection,
    'start': start_ru,
    'enter_init_listen': enter_init_listen_ru,
    'start_tape': start_tape_ru,
    'stop_tape': stop_tape_ru,
    'add_listen': add_listen_ru,
    'enter_add_listen': enter_add_listen_ru,
    'delete_listen': delete_listen_ru,
    'enter_delete_listen': enter_delete_listen_ru,
    'subscriptions': subscriptions_ru,
    'wish': wish_ru,
    'switch_wish': switch_wish_ru,
    'enter_wish': enter_wish_ru,
    'echo': echo_ru,
    'engineering_works': engineering_works_ru,
    'menu': menu_ru,
    'back': back_ru,
    'admin_panel': admin_panel_ru,
    'admin_not_commands': admin_not_commands_ru,
    'admin_post': admin_post_ru,
    'admin_switch_post': admin_switch_post_ru,
    'admin_enter_post': admin_enter_post_ru,
    'admin_statistics': admin_statistics_ru,
    'admin_reset_wish': admin_reset_wish_ru,
    'admin_add_spam_word': admin_add_spam_word_ru,
    'admin_delete_spam_word': admin_delete_spam_word_ru,
    'admin_spam_words': admin_spam_words_ru,
    'admin_enter_add_spam_word': admin_enter_add_spam_word_ru,
    'admin_enter_delete_spam_word': admin_enter_delete_spam_word_ru,
}


num=int(input("Enter A Number: "))
usernum=num
count=0
while(num>0):
    i=int(num%10)
    if(i>0):
        count+=1
    num=num/10
print("Number Of Digits In ",usernum," = ",count)


#!/usr/bin/env python3

"""
=======================================
=           Twitter cleaner           =
=   https://twitter.com/telepathics   =
=======================================
"""

import json
import random
import time
from datetime import datetime

import gspread
import pytz
from dateutil.relativedelta import relativedelta
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import client, file, tools
from oauth2client.service_account import ServiceAccountCredentials
from twitter import OAuth, Twitter

from g import GSPREAD_SCOPES, ROW_OFFSET, SCOPES, SHEET_NAME, SPREADSHEET_ID
from picker import Picker
from t import (ACCESS_TOKEN_KEY, ACCESS_TOKEN_SECRET, AUTH_SCREEN_NAME,
               CONSUMER_KEY, CONSUMER_SECRET, DM_MSG, MIN_FAVS)

STARTC = '\033[90m'
ENDC = '\033[0m'
TimeZoneInfo = pytz.UTC
SHEET_LINK = f'https://docs.google.com/spreadsheets/d/{SPREADSHEET_ID}/edit#gid=0'

CANCEL_OPTIONS = ('no', 'n', 'exit', 'e', 'quit', 'q')
TIME_FORMATTING = "%a %b %d %H:%M:%S %z %Y"

"""
=============================================
=          Public Helper Functions          =
=============================================
"""

def sleep_overlay(prev_text='', sleepy=random.randrange(1, 8)):
    """-----------  Sleeps for a random amount of time between 1 and 8 seconds.  -----------"""
    _x = sleepy
    for _ in range(sleepy+1):
        print('\r0{0} {1}'.format(_x, prev_text).ljust(
            30)+'\r', end='', flush=True)
        _x -= 1
        time.sleep(1)

    return True

def display_error(e, location):
    """-----------  Displays a pretty error message.  -----------"""
    print("\n-----------\n")
    print(f"ERROR in {location}:")
    print(STARTC)
    print(e)
    print("\n" + SHEET_LINK + ENDC)
    print("\n-----------\n")

def max_request_limit_warning(sleepy):
    """-----------  Displays a warning message if the rate limit is reached.  -----------"""
    return sleep_overlay(f'{STARTC}MAX_REQUEST Limit reached.  Please wait...{ENDC}', sleepy)

def g_auth():
    """-----------  Basic Google Authentication  -----------"""
    store = file.Storage('token.json')
    creds = store.get()
    if not creds or creds.invalid:
        flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
        creds = tools.run_flow(flow, store)
    service = build('sheets', 'v4', http=creds.authorize(Http()))

    gcreds = ServiceAccountCredentials.from_json_keyfile_name(
        'service_credentials.json', GSPREAD_SCOPES)
    gclient = gspread.authorize(gcreds)
    sheet = gclient.open(SHEET_NAME)

    return service, sheet

def get_old_tweets(years_ago):
    """-----------  Get old tweets from tweet.json  -----------"""
    past_time = datetime.now() - relativedelta(years=years_ago)
    old_tweets = []

    with open('tweet.json', 'r') as tweets:
        tweetlist = json.load(tweets)
        for tweet in tweetlist:
            tweet = tweet["tweet"]
            try:
                created_at = datetime.strptime(
                    tweet["created_at"], TIME_FORMATTING)
                old_enough = created_at.replace(
                    tzinfo=TimeZoneInfo) < past_time.replace(tzinfo=TimeZoneInfo)
                if old_enough:
                    old_tweets.append(tweet)
            except Exception as e:
                display_error(e, 'AccountHandler.get_old_tweets')
                continue
    return old_tweets, created_at

def check_recent_mentions(values):
    """double-check IFTTT applet is running (if there have been mentions in the last 7 days)"""
    cont = True
    recent_mentions = False
    last_week = (datetime.now() - relativedelta(days=6)
                 ).replace(tzinfo=TimeZoneInfo)
    for datecol in values:
        udatetime = datetime.strptime(
            datecol[0], "%m/%d/%Y").replace(tzinfo=TimeZoneInfo)
        if udatetime > last_week:
            recent_mentions = True
    if not recent_mentions:
        print('Please double-check that IFTTT is running the applet.')
        answ = input('Continue? (Y/N): ')
        if answ.lower() in CANCEL_OPTIONS:
            cont = False

    return cont

class AccountHandler:
    """
    =============================================
    =           Account Handler Class           =
    =============================================
    """

    def __init__(self):
        self.t = Twitter(auth=OAuth(ACCESS_TOKEN_KEY,
                         ACCESS_TOKEN_SECRET, CONSUMER_KEY, CONSUMER_SECRET))
        self.feed = []
        self.friends = []
        self.resources = self.t.application.rate_limit_status()['resources']

    def check_rate_limit(self):
        """-----------  Checks the rate limit for the current account.  -----------"""
        t = self.t
        resources = self.resources
        reset_time = self.resources['application']['/application/rate_limit_status']['reset']
        curr_epoch = int(time.time())
        if reset_time < curr_epoch:
            resources = t.application.rate_limit_status()['resources']
            self.resources = resources

        return resources

    def update_t_rate_limit(self, resource, path):
        """-----------  Updates the rate limit for the current account.  -----------"""
        rate_limit = self.check_rate_limit()[resource][path]
        warning_complete = False
        while rate_limit['remaining'] <= 1 and not warning_complete:
            warning_complete = max_request_limit_warning(
                int(time.time()) - rate_limit['reset'])

        return warning_complete

    def get_twitter_friends(self, cursor):
        """-----------  Gets the current account's Twitter followers.  -----------"""
        t = self.t

        friends = t.friends.list(
            count=200, skip_status=True, include_user_entities=False, cursor=cursor)
        self.update_t_rate_limit('friends', '/friends/list')
        self.friends = friends

        return friends

    def get_twitter_lists(self):
        """-----------  Gets the current account's Twitter lists.  -----------"""
        t = self.t

        owned_lists = t.lists.ownerships(
            count=25, screen_name=AUTH_SCREEN_NAME)["lists"]
        self.update_t_rate_limit('lists', '/lists/ownerships')

        return owned_lists

    def get_twitter_list_members(self, list_id):
        """----------- Gets the current account's Twitter list members. -----------"""

        t = self.t

        screen_names = t.lists.members(
            list_id=list_id, count=5000, include_entities=False, skip_status=True)
        self.update_t_rate_limit('lists', '/lists/members')

        return screen_names

    def send_direct_message(self, uscreen_name):
        """-----------  Send DM  -----------"""
        t = self.t

        sent = t.direct_messages.events.new(
            _json={
                "event": {
                    "type": "message_create",
                    "message_create": {
                            "target": {
                                "recipient_id": t.users.show(screen_name=uscreen_name)["id"]},
                            "message_data": {
                                "text": DM_MSG}
                    }
                }
            }
        )
        self.update_t_rate_limit(
            'direct_messages', '/direct_messages/sent_and_received')

        return sent

    def delete_archived_tweets(self):
        """-----------  Delete tweets older than 2 years  -----------"""
        t = self.t
        old_tweets, created_at = get_old_tweets(2)

        for tweet in old_tweets:
            if int(tweet['favorite_count']) < MIN_FAVS:
                try:
                    tweet_id = tweet['id_str']
                    t.statuses.destroy(_id=tweet_id)
                    print(tweet['full_text'])
                    print(
                        f'DELETED {tweet_id} ({created_at.strftime(TIME_FORMATTING)})')

                    print('* ' + tweet['favorite_count'] + ' favorites\n')
                    # TODO figure out more accurate rate limit
                    sleep_overlay(
                        f'{STARTC}Looking for next archived tweet...{ENDC}')

                except Exception as e:
                    display_error(e, 'AccountHandler.delete_archived_tweets')
                    continue
        return True

    def delete_tweets_without_interactions(self):
        """-----------  Delete tweets without interactions  -----------"""
        t = self.t
        old_tweets, created_at = get_old_tweets(0)

        for tweet in old_tweets:
            try:
                # check if there are interactions
                interactions = int(tweet["favorite_count"]) + \
                    int(tweet["retweet_count"])
                if interactions == 0:
                    t.statuses.destroy(_id=tweet["id_str"])
                    print(tweet['full_text'] +
                          ' (' + str(interactions) + ' interactions) ')
                    print('DELETED ' + tweet['id_str'] + ' (' +
                          created_at.strftime(TIME_FORMATTING) + ')\n')
                    # TODO figure out more accurate rate limit
                    sleep_overlay(f'{STARTC}Looking for next tweet...{ENDC}')
            except Exception as e:
                display_error(
                    e, 'AccountHandler.delete_tweets_without_interactions')
                continue
        return True

    def unfollow_twitter_user(self, uscreen_name):
        """-----------  Unfollow users on Twitter  -----------"""
        t = self.t

        user = t.users.show(screen_name=uscreen_name)
        self.update_t_rate_limit('users', '/users/show/:id')

        if not user["protected"] and user["following"]:
            t.friendships.destroy(screen_name=uscreen_name)
            # TODO figure out more accurate rate limit
            sleep_overlay(f'{STARTC}unfollowing {uscreen_name}{ENDC}')
            try:
                lists = self.get_twitter_lists()
                for li in lists:
                    t.lists.members.destroy(
                        list_id=li["id"], screen_name=uscreen_name)
            except Exception as e:
                display_error(e, 'AccountHandler.unfollow_inactive_users')
            return True
        if user["following"]:
            no_unfollow_msg = ''
            no_unfollow_msg += 'Didn\'t unfollow https://twitter.com/' + uscreen_name
            no_unfollow_msg += f'{STARTC} [user is protected]{ENDC}'
            print(no_unfollow_msg)
        return False

    def add_users_to_list(self, screen_names, list_id, list_slug):
        """-----------  Add Users to Twitter List  -----------"""
        t = self.t

        # can only add ~100 users to a list at a time.
        chunks = [screen_names[x:x+100]
                  for x in range(0, len(screen_names), 100)]
        for chunk in chunks:
            t.lists.members.create_all(
                list_id=list_id,
                slug=list_slug,
                owner_screen_name=AUTH_SCREEN_NAME,
                screen_name=chunk
            )
            # TODO figure out more accurate rate limit
            sleep_overlay(f'{STARTC}Loading...{ENDC}')
            print("Added the following users to the list '" + list_slug + "'.")
            print(chunk)

        return True

class ExemptHandler:
    """
    # ============================================
    # =           Exempt Handler Class           =
    # ============================================
    """

    def __init__(self, reset):
        self.rate_limit = {
            # sheets api: 100 requests/100 seconds/1 user
            "limit": 100,
            "remaining": 100,
            "reset": reset
        }

        self.service, self.sheet = g_auth()
        self.allowlist = self.get_category_users('allowlist')
        self.categories = ['MENTIONS', 'LISTED']

    def reset_g_rate_limit(self):
        """-----------  Reset Rate Limit  -----------"""
        rate_limit = {
            "limit": 100,
            "remaining": 100,
            "reset": time.time()
        }
        self.rate_limit = rate_limit

        return rate_limit

    def update_g_rate_limit(self, minus_remaining=1):
        """-----------  Update Rate Limit  -----------"""
        rate_limit = self.rate_limit
        time_left = 100 + rate_limit['reset'] - time.time()
        if rate_limit['remaining'] <= 1 and time_left <= 0:
            max_request_limit_warning(100)
            self.reset_g_rate_limit()
        else:
            self.rate_limit['remaining'] -= minus_remaining

    def get_category_users(self, category, col='A'):
        """-----------  Get screen_names from specific category  -----------"""
        service = self.service
        range_name = f'{category.upper()}!{col}2:{col}'

        values = self.get_result_values(service, range_name)
        cat_users = [value[0] for value in values if value != []]

        return cat_users if values else False

    def get_cell_value(self, category, cell_range):
        """-----------  Get single cell value  -----------"""
        service = self.service
        range_name = f'{category.upper()}!{str(cell_range)}'

        values = self.get_result_values(service, range_name)
        return values[0][0] if values else False

    def get_next_cursor(self):
        """-----------  Get next Twitter API cursor ------------"""
        return self.get_cell_value('cursor', 'A2')

    def get_cleanup_cursor(self):
        """-----------  Get cleanup_cursor  -----------"""
        return self.get_cell_value('cursor', 'A3')

    def get_duplicate_cursor(self):
        """-----------  Get duplicate_cursor  -----------"""
        return self.get_cell_value('cursor', 'A4')

    def overwrite_cell(self, value, category, cell_range):
        """-----------  Overwrite cell in spreadsheet  -----------"""
        service = self.service
        resource = {"values": [[value]]}
        cat_range = f"{category.upper()}!{cell_range}"

        # delete old cursor
        service.spreadsheets().values().clear(
            spreadsheetId=SPREADSHEET_ID,
            range=cat_range,
        ).execute()
        self.update_g_rate_limit()

        # overwrite
        service.spreadsheets().values().append(
            spreadsheetId=SPREADSHEET_ID,
            range=cat_range,
            body=resource,
            valueInputOption="USER_ENTERED"
        ).execute()
        self.update_g_rate_limit()

    def overwrite_next_cursor(self, next_cursor):
        """-----------  Replace next twitter API cursor  -----------"""
        return self.overwrite_cell(next_cursor, 'cursor', 'A2')

    def overwrite_cleanup_cursor(self, uscreen_name):
        """-----------  Replace next allowlist cleanup cursor  -----------"""
        return self.overwrite_cell(uscreen_name, 'cursor', 'A3')

    def overwrite_duplicate_cursor(self, uscreen_name):
        """-----------  Replace next mention cursor  -----------"""
        return self.overwrite_cell(uscreen_name, 'cursor', 'A4')

    def add_users_to_category(self, category, screen_names):
        """-----------  Add User to Category Spreadsheet  -----------"""
        service = self.service
        resource = {"values": screen_names}
        cat_range = f"{category.upper()}!A:A"

        service.spreadsheets().values().append(
            spreadsheetId=SPREADSHEET_ID,
            range=cat_range,
            body=resource,
            valueInputOption="USER_ENTERED"
        ).execute()
        self.update_g_rate_limit()

    def remove_user_from_category(self, category, uscreen_name):
        """-----------  Remove User from Category Spreadsheet  -----------"""
        removed = False
        category_users = self.get_category_users(category)

        if category_users and uscreen_name in category_users:
            rows_to_remove = category_users.count(uscreen_name)
            for _ in range(rows_to_remove):
                category_users = self.get_category_users(category)
                row_index = category_users.index(uscreen_name)
                self.remove_row_from_category_spreadsheet(
                    category, row_index + ROW_OFFSET)
                removed = True

        if removed:
            print(f"{STARTC}Removed {uscreen_name} from {category}{ENDC}")

        return True

    def add_error_to_user_in_categories(self, uscreen_name):
        """-----------  Add ERROR to user in all categories  -----------"""
        for category in self.categories:
            cat_users = self.get_category_users(category)
            if uscreen_name in cat_users:
                self.overwrite_cell('error', category, ('D' if category.lower(
                ) == 'mentions' else 'B') + str(cat_users.index(uscreen_name) + ROW_OFFSET))

    def remove_row_from_category_spreadsheet(self, category, row_index):
        """-----------  Remove row from Category Spreadsheet  -----------"""
        deleted = False
        if self.get_cell_value('mentions', f'D{str(row_index)}') != 'error':
            spreadsheet = self.sheet.worksheet(category.upper())
            deleted = spreadsheet.delete_row(row_index)
            self.update_g_rate_limit()

        return deleted

    def handle_remove_or_dm(self, values):
        """-----------  Handle whether to unfollow or DM  -----------"""
        up_next_end = (datetime.now() - relativedelta(months=3) +
                       relativedelta(days=7)).replace(tzinfo=TimeZoneInfo)
        past_time = (datetime.now() - relativedelta(months=3)
                     ).replace(tzinfo=TimeZoneInfo)
        row_index = 0 + ROW_OFFSET

        print(f'Deleting mentions older than {str(past_time)}...')

        dm_screen_names = []
        removed_screen_names = []
        for datecol in values:
            uscreen_name = self.get_cell_value(
                'mentions', f'A{str(row_index)}').lower()
            udatetime = datetime.strptime(
                datecol[0], "%m/%d/%Y").replace(tzinfo=TimeZoneInfo)
            if udatetime < past_time:
                removed_screen_names.append(uscreen_name)
                self.remove_row_from_category_spreadsheet(
                    'mentions', row_index)
            else:
                row_index += 1
                # check if user submitted grace-period entry
                dm_list = self.get_category_users('DM', 'B')
                if udatetime < up_next_end and uscreen_name in dm_list:
                    dm_screen_names.append(uscreen_name)
                else:
                    break

        return [removed_screen_names, dm_screen_names]

    def remove_old_mentions(self):
        """-----------  Delete old dates from MENTIONS Spreadsheet  -----------"""
        service = self.service
        mentions_date_col = "MENTIONS!C2:C"

        values = self.get_result_values(service, mentions_date_col)
        if values:
            cont = check_recent_mentions(values)
            if cont:
                self.handle_remove_or_dm(values)

        return False

    def get_result_values(self, service, cell_range):
        """-----------  Get result values from Google Spreadsheet  -----------"""
        result = (service.spreadsheets().values().get(
            spreadsheetId=SPREADSHEET_ID, range=cell_range).execute())
        self.update_g_rate_limit()
        result = result.get('values', [])
        return result

    def remove_old_duplicate_category(self, category):
        """-----------  Delete old mentions from users who appear multiple times  -----------"""
        values = self.get_category_users(category.lower())
        listed = self.get_category_users('listed')

        if not values:
            return False

        print(f'Cleaning up duplicate {category}...')

        row_index = 0 + ROW_OFFSET
        duplicate_cursor = self.get_duplicate_cursor()
        if duplicate_cursor in values:
            row_index = values.index(duplicate_cursor) + ROW_OFFSET
            values = values[values.index(duplicate_cursor):]

        removed_screen_names = []
        for index, uscreen_name in enumerate(values):
            # remove user from mentions sheets if listed or repeated
            user_listed = category.lower() == 'mentions' and uscreen_name in listed
            if user_listed or (values[index+1:].count(uscreen_name) > 0):
                removed_screen_names.append(self.get_cell_value(
                    category.lower(), f'A{str(row_index)}'))

                self.remove_row_from_category_spreadsheet(
                    category.lower(), row_index)
            else:
                row_index += 1
                self.overwrite_duplicate_cursor(uscreen_name)

            sleep_overlay(STARTC + uscreen_name + ENDC)

        return removed_screen_names

class Tweeder:
    """
    =========================================
    =           Tweeder Functions           =
    =========================================
    """

    def __init__(self, tw, sheet):
        self.tw = tw
        self.sheet = sheet

    def reset_cursors(self):
        """-----------  reset cursors -----------"""
        sheet = self.sheet

        sheet.overwrite_next_cursor('-1')
        sheet.overwrite_cleanup_cursor('')
        sheet.overwrite_duplicate_cursor('')

    def add_sheet_category_users_to_tw_list(self, category, list_id, list_slug):
        """-----------  Add sheet category users to a twitter list  -----------"""
        tw = self.tw
        sheet = self.sheet

        screen_names = sheet.get_category_users(category)
        tw.add_users_to_list(screen_names, list_id,
                             list_slug, AUTH_SCREEN_NAME)

        return True

    def add_tw_user_to_sheet_category(self, uscreen_name):
        """-----------  Add user to category based off twitter information  -----------"""
        tw = self.tw
        sheet = self.sheet

        t = tw.t
        user = t.users.show(screen_name=uscreen_name)

        # check if user should be listed
        if user["verified"] or user["notifications"]:
            sheet.add_users_to_category('listed', [[uscreen_name]])
            return True

        return False

    def add_listed_users_to_allowlist(self):
        """-----------  Add listed users to allowlist  -----------"""
        tw = self.tw
        sheet = self.sheet
        lists = tw.get_twitter_lists()
        listed = sheet.get_category_users('listed')

        for li in lists:
            members = tw.get_twitter_list_members(li["id"])
            auto_add = li["name"].endswith('(y)')
            answ = 'n'
            if not auto_add and not li["name"].endswith('(n)'):
                # only ask if twitter list doesnt explicitly end in (y) or (n)
                answ = input("Add users from "+li["name"]+"? (Y/N): ")
            if (auto_add) or (answ.lower() not in CANCEL_OPTIONS):
                print(f'Adding listed users from {li["name"]}')
                for user in members["users"]:
                    uscreen_name = user['screen_name'].lower()
                    if uscreen_name not in listed and self.check_is_followed_by(uscreen_name):
                        sheet.add_users_to_category(
                            'listed', [[uscreen_name]])
                        sleep_overlay(uscreen_name)

    def user_is_allowlisted(self, uscreen_name):
        """-----------  Check if user is in allowlist  -----------"""
        sheet = self.sheet
        return uscreen_name in sheet.allowlist

    def unfollow_inactive_users(self):
        """-----------  Compare following list to allowlist  -----------"""
        tw = self.tw
        sheet = self.sheet

        friends = tw.friends
        next_cursor = sheet.get_next_cursor()
        if friends == []:
            friends = tw.get_twitter_friends(next_cursor)

        allowlisted = []
        unfollowed_users = []
        running = True
        # ! TODO broken code, doesn't stop looping
        while running:
            for friend in friends['users']:
                uscreen_name = friend['screen_name'].lower()
                if self.unfollow_after_allowlist_check(uscreen_name):
                    unfollowed_users.append(uscreen_name)
                else:
                    allowlisted.append(uscreen_name)

            if len(allowlisted) == len(friends['users']):
                next_cursor = friends['next_cursor']
                if friends['next_cursor'] == 0:
                    next_cursor = -1
                    running = False
                sheet.overwrite_next_cursor(next_cursor)
                print(f"NEXT_CURSOR overwritten: {str(next_cursor)}")
                allowlisted = []
                unfollowed_users = []
            # reset!
            friends = tw.get_twitter_friends(next_cursor)
        self.remove_unfollowers_from_categories()

    def check_is_followed_by(self, uscreen_name):
        """-----------  Check if user is following  -----------"""
        tw = self.tw
        sheet = self.sheet

        categories = sheet.categories
        blocked_list = sheet.get_category_users('blocked')
        manual_list = sheet.get_category_users('manual')
        followed_by = False

        if uscreen_name not in blocked_list:
            try:
                friendship = tw.t.friendships.show(
                    source_screen_name=AUTH_SCREEN_NAME, target_screen_name=uscreen_name)
                following_me = friendship["relationship"]["target"]["following"]

                if not following_me and uscreen_name not in manual_list:
                    print(STARTC + uscreen_name + " is not following." + ENDC)
                    for category in categories:
                        sheet.remove_user_from_category(category, uscreen_name)
                elif not friendship["relationship"]["target"]["followed_by"]:
                    print(STARTC + uscreen_name +
                          " is a new Reply Guy!" + ENDC)
                    tw.t.friendships.create(
                        screen_name=uscreen_name, follow=False)
                    tw.t.friendships.update(
                        screen_name=uscreen_name, retweets=False)
                    followed_by = True
                else:
                    tw.t.friendships.update(
                        screen_name=uscreen_name, retweets=False)
                    followed_by = True
            except Exception as e:
                sheet.add_error_to_user_in_categories(uscreen_name)
                display_error(e, 'AccountHandler.check_is_followed_by')

        return followed_by

    def unfollow_after_allowlist_check(self, uscreen_name):
        """-----------  Check if user is "newly allowlisted", determine unfollow  -----------"""
        tw = self.tw
        allowlisted = self.user_is_allowlisted(uscreen_name)
        newly_allowlisted = self.add_tw_user_to_sheet_category(uscreen_name)

        if allowlisted:
            print(STARTC + uscreen_name + ' is allowlisted.' + ENDC)
        elif newly_allowlisted:
            print(STARTC + uscreen_name + ' is newly allowlisted.' + ENDC)
        elif tw.unfollow_twitter_user(uscreen_name):
            print(f'Unfollowed {uscreen_name}')
            return True

        return False

    def remove_unfollowers_from_categories(self):
        """-----------  Remove users from categories if not following  -----------"""
        sheet = self.sheet
        allowlist = sheet.get_category_users('allowlist')
        cleanup_cursor = sheet.get_cleanup_cursor()

        if cleanup_cursor in allowlist:
            cleanup_cursor = cleanup_cursor.lower()
            allowlist = allowlist[allowlist.index(cleanup_cursor):]
        elif cleanup_cursor:
            start_at_letter = [
                i for i in allowlist if i.startswith(cleanup_cursor[0][0])][0]
            allowlist = allowlist[allowlist.index(start_at_letter):]

        for screen_name in allowlist:
            uscreen_name = screen_name.strip().lower()
            self.check_is_followed_by(uscreen_name)

            sheet.overwrite_cleanup_cursor(uscreen_name)
            sleep_overlay(uscreen_name)

    def remove_old_mentions(self):
        """-----------  Remove old mentions  -----------"""
        tw = self.tw
        sheet = self.sheet

        [removed_users, dm_screen_names] = sheet.remove_old_mentions()
        removed_users = list(set(removed_users))
        for screen_name in removed_users:
            uscreen_name = screen_name.lower()
            print(STARTC + uscreen_name +
                  ' has not tweeted at you in 6 months.' + ENDC)
            self.unfollow_after_allowlist_check(uscreen_name)
        for screen_name in dm_screen_names:
            uscreen_name = screen_name.lower()
            tw.send_direct_message(uscreen_name)

    def dailies(self):
        """-----------  Daily Tasks  -----------"""
        self.reset_cursors()
        self.add_listed_users_to_allowlist()
        self.remove_unfollowers_from_categories()
        self.remove_old_mentions()
        self.unfollow_inactive_users()

def menu(tweeder):
    """
    ======================================
    =   Menu for user to select options  =
    ======================================
    """
    user_options = [
        "0. Daily tasks",
        "1. Unfollow users",
        "2. Update listed users",
        "3. Remove old mentions",
        "4. Clean category users",
        "5. Reset CURSORs",
        "6. Delete tweets older than 2 years",
        "7. Delete tweets without interactions",
        "8. Sleep (in case of rate limit)",
        "9. Remove duplicates"
    ]

    opts = Picker(
        title='What would you like to do?',
        options=user_options
    ).getSelected()

    if not opts:
        return opts

    for opt in opts:
        print("\n----------- " + opt + " -----------")
        if opt == user_options[0]:
            tweeder.dailies()
        elif opt == user_options[1]:
            tweeder.unfollow_inactive_users()
        elif opt == user_options[2]:
            tweeder.add_listed_users_to_allowlist()
        elif opt == user_options[3]:
            tweeder.remove_old_mentions()
        elif opt == user_options[4]:
            tweeder.remove_unfollowers_from_categories()
        elif opt == user_options[5]:
            tweeder.reset_cursors()
        elif opt == user_options[6]:
            tweeder.tw.delete_archived_tweets()
        elif opt == user_options[7]:
            tweeder.tw.delete_tweets_without_interactions()
        elif opt == user_options[8]:
            answ = input('How many seconds should we sleep?: ') or 500
            sleep_overlay('zzz', int(answ))
        elif opt == user_options[9]:
            tweeder.sheet.remove_old_duplicate_category('mentions')
        else:
            return True

    answ = input("Would you like to do more? (Y/N) ")
    return answ.lower() not in CANCEL_OPTIONS

def main():
    """
    ======================================
    =    Main function for the program   =
    ======================================
    """
    running = True

    # ===== CONNECT TO RESOURCES AND CLASSES =====
    try:
        _tw = AccountHandler()
        _sheet = ExemptHandler(time.time())
        tweeder = Tweeder(_tw, _sheet)
        tweeder.sheet.overwrite_cell(str(datetime.now()), 'INFORMATION', 'B3')
        print("\nConnection complete!")
        sleep_overlay(f"{STARTC}Loading...{ENDC}", 3)
        print()
    except Exception as e:
        display_error(e, 'CONNECTION')
        sleep_overlay(
            f"{STARTC}Shutting down... Feel free to ctrl+c.{ENDC}", 100)
        running = False
    # ===== CONNECTION COMPLETE =====

    while running:
        running = menu(tweeder)

    print("\n\nThank you, come again!\n")

if __name__ == '__main__':
    main()


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

# # Importing Libraries

# These are just a few examples of popular Python libraries. You can import any other library using the same import statement followed by the library name or alias:

# NumPy: for numerical operations and array manipulation
#
# Pandas: for data manipulation and analysis
#
# Matplotlib: for creating visualizations
#
# Scikit-learn: for machine learning algorithms

# In[1]:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
get_ipython().run_line_magic('matplotlib', 'inline')

# # Reading Dataset

# In[2]:

from tensorflow.keras.datasets import cifar10

# # Splitting Dataset

# Dataset splitting is an important step in machine learning and data analysis. It involves dividing a dataset into two or more subsets to train and evaluate a model effectively. The most common type of dataset splitting is into training and testing subsets.

# Train-Test Split: This is the most basic type of split, where the dataset is divided into a training set and a testing set. The training set is used to train the machine learning model, while the testing set is used to evaluate its performance. The split is typically done using a fixed ratio, such as 80% for training and 20% for testing.

# In[3]:

(x_train, y_train), (x_test, y_test) = cifar10.load_data()

# In[5]:

x_train.shape, y_train.shape, x_test.shape, y_test.shape

# In[6]:

plt.imshow(x_train[20])

# In[7]:

x_train[20]

# In[8]:

x_train.min(), x_train.max()

# In[9]:

x_train = x_train / 255
x_test = x_test / 255

# In[10]:

x_train.shape, x_test.shape

# # Converting To Categorical

# Converting data to categorical format is often necessary for certain machine learning tasks, especially when dealing with categorical or nominal variables. This conversion is typically performed to represent the categorical variables as numeric values that can be processed by machine learning algorithms.

# In[11]:

from tensorflow.keras.utils import to_categorical

# In[12]:

y_train_categorical = to_categorical(y_train)
y_test_categorical = to_categorical(y_test)

# In[13]:

y_train_categorical

# In[14]:

y_test_categorical

# # Buliding Model

# Creating a deep learning model involves defining the architecture and structure of the neural network, specifying the layers, and configuring the parameters for training.

# In[15]:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten

# In[16]:

from tensorflow.keras.callbacks import EarlyStopping

# In[17]:

from sklearn.metrics import classification_report, confusion_matrix

# In[18]:

model = Sequential()
model.add(Conv2D(filters = 32, input_shape = (32, 32, 3), kernel_size = (4, 4), activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))

model.add(Conv2D(filters = 32, input_shape = (32, 32, 3), kernel_size = (4, 4), activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))

model.add(Flatten())

model.add(Dense(256, activation = 'relu'))

model.add(Dense(10, activation = 'softmax'))

# In[19]:

model.summary()

# # Compiling Model

# Compiling the model in deep learning involves configuring essential components that define how the model will be trained.

# In[20]:

model.compile(optimizer = 'rmsprop', loss = 'categorical_crossentropy', metrics = ['accuracy'])

# In[21]:

early_stopping = EarlyStopping(monitor = 'val_loss', patience = 3)

# # Training Model

# Training the model in deep learning involves the process of iteratively updating the model's parameters (weights and biases) based on the provided training data to minimize the loss function and improve the model's performance

# In[23]:

model.fit(x_train, y_train_categorical,
          validation_data = (x_test, y_test_categorical),
          epochs = 20,
          callbacks = [early_stopping])

# In[24]:

model.save('CNN_model_for_CIFAR10.h5')

# In[25]:

loss = pd.DataFrame(model.history.history)

# In[26]:

loss.head()

# In[27]:

loss.plot()

# In[28]:

loss[['loss', 'val_loss']].plot()

# In[29]:

loss[['accuracy', 'val_accuracy']].plot()

# In[34]:

prediction = model.predict(x_test)
prediction_classes = prediction.argmax(axis = 1)

# # Error Analysis

# Error analysis is an important step in evaluating and improving the performance of a machine learning model. It involves analyzing the errors made by the model during predictions to gain insights into the patterns, sources, and potential improvements.

# In[35]:

print(classification_report(y_test, prediction_classes))

# In[37]:

print(confusion_matrix(prediction_classes, y_test))

# In[41]:

plt.figure(figsize = (12, 6))
sns.heatmap(confusion_matrix(prediction_classes, y_test),
            annot = True,
            cmap = 'coolwarm')

# # Prediction

# In[57]:

prediction = x_train[5]

# In[58]:

plt.imshow(prediction)

# In[59]:

predictions = model.predict(prediction.reshape(1, 32, 32, 3))
predicted_class = np.argmax(predictions)

print("Predicted class:", predicted_class)

CNN on CIFAR10 Dataset/CNN on CIFAR10 Dataset.py


import sys
sys.setrecursionlimit(10000000)
input = sys.stdin.readline

def dfs(now, visited):
    global cnt
    visited[now] = cnt
    cnt += 1
    for new in adjL[now]:
        if visited[new]==0:
            dfs(new, visited)

    return visited

N, M, R = map(int, input().split())
adjL = [[] for _ in range(N+1)]
for _ in range(M):
    u, v = map(int, input().split())
    adjL[u].append(v)
    adjL[v].append(u)

for l in adjL:
    l.sort()

visited = [0 for _ in range(N+1)]

cnt = 1
ans = dfs(R, visited)

for idx in range(1, N+1):
    print(visited[idx])

백준/Silver/24479. 알고리즘 수업 － 깊이 우선 탐색 1/알고리즘 수업 － 깊이 우선 탐색 1.py

알고리즘 수업 － 깊이 우선 탐색 1.py


#!/usr/bin/env python

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

__author__ = "John Wieczorek"
__contributors__ = "Aaron Steele, John Wieczorek"
__copyright__ = "Copyright 2018 vertnet.org"
__version__ = "util.py 2018-04-07T20:26-03:00"

import json
import logging

UTIL_VERSION=__version__

ADD_TO_DOWNLOAD_RESULTS = ['url', 'citation', 'gbifdatasetid', 'gbifpublisherid', 'email',
    'contact', 'pubdate', 'lastindexed', 'migrator', 'hasmedia', 'hastissue',
    'wascaptive', 'isfossil', 'isarch', 'vntype', 'haslength']

OMIT_FROM_DOWNLOADS = ['location', 'record', 'verbatim_record', 'count', 'icode',
    'title', 'orgname', 'emlrights', 'networks', 'hashid', 'rank', 'haslicense',
    'mappable', 'source_url', 'hastypestatus', 'language', 'iptrecordid',
    'ownerinstitutioncode', 'organismquantity', 'organismquantitytype', 'parenteventid',
    'samplesizevalue', 'samplesizeunit', 'pointradiusspatialfit', 'footprintspatialfit',
    'taxonid', 'acceptednameusageid', 'parentnameusageid', 'originalnameusageid',
    'nameaccordingtoid', 'taxonconceptid', 'parentnameusage', 'nameaccordingto',
    'nomenclaturalstatus']

TRANSLATE_HEADER = {'pubdate':'dataset_pubdate', 'url':'dataset_url',
    'title':'dataset_title', 'contact':'dataset_contact', 'email':'dataset_contact_email',
    'citation':'dataset_citation', 'dctype':'type', 'migrator':'migrator_version'}

DWC_RECLEVEL = ['DCType', 'Modified', 'Language', 'License', 'RightsHolder',
    'AccessRights', 'BibliographicCitation', 'References', 'InstitutionID',
    'CollectionID', 'DatasetID', 'InstitutionCode', 'CollectionCode', 'DatasetName',
    'OwnerInstitutionCode', 'BasisOfRecord', 'InformationWithheld',
    'DataGeneralizations', 'DynamicProperties']

DWC_OCC = ['OccurrenceID', 'CatalogNumber', 'RecordNumber', 'RecordedBy',
    'IndividualCount', 'OrganismQuantity', 'OrganismQuantityType', 'Sex', 'LifeStage',
    'ReproductiveCondition', 'Behavior', 'EstablishmentMeans', 'OccurrenceStatus',
    'Preparations', 'Disposition', 'AssociatedMedia', 'AssociatedReferences',
    'AssociatedSequences', 'AssociatedTaxa', 'OtherCatalogNumbers', 'OccurrenceRemarks']

DWC_ORGANISM = ['OrganismID', 'OrganismName', 'OrganismScope', 'AssociatedOccurrences',
    'AssociatedOrganisms', 'PreviousIdentifications', 'OrganismRemarks']

DWC_SAMPLE = ['MaterialSampleID']

DWC_EVENT = ['EventID', 'parentEventID', 'FieldNumber', 'EventDate', 'EventTime',
    'StartDayOfYear', 'EndDayOfYear', 'Year', 'Month', 'Day', 'VerbatimEventDate',
    'Habitat', 'SamplingProtocol', 'SampleSizeValue', 'SampleSizeUnit', 'SamplingEffort',
    'FieldNotes', 'EventRemarks']

DWC_LOCATION = ['LocationID', 'HigherGeographyID', 'HigherGeography', 'Continent',
    'WaterBody', 'IslandGroup', 'Island', 'Country', 'CountryCode', 'StateProvince',
    'County', 'Municipality', 'Locality', 'VerbatimLocality', 'MinimumElevationInMeters',
    'MaximumElevationInMeters', 'VerbatimElevation', 'MinimumDepthInMeters',
    'MaximumDepthInMeters', 'VerbatimDepth', 'MinimumDistanceAboveSurfaceInMeters',
    'MaximumDistanceAboveSurfaceInMeters', 'LocationAccordingTo', 'LocationRemarks',
    'DecimalLatitude', 'DecimalLongitude', 'GeodeticDatum',
    'CoordinateUncertaintyInMeters', 'CoordinatePrecision', 'PointRadiusSpatialFit',
    'VerbatimCoordinates', 'VerbatimLatitude', 'VerbatimLongitude',
    'VerbatimCoordinateSystem', 'VerbatimSRS', 'FootprintWKT', 'FootprintSRS',
    'FootprintSpatialFit', 'GeoreferencedBy', 'GeoreferencedDate',
    'GeoreferenceProtocol', 'GeoreferenceSources', 'GeoreferenceVerificationStatus',
    'GeoreferenceRemarks']

DWC_GEO = ['GeologicalContextID', 'EarliestEonOrLowestEonothem',
    'LatestEonOrHighestEonothem', 'EarliestEraOrLowestErathem',
    'LatestEraOrHighestErathem', 'EarliestPeriodOrLowestSystem',
    'LatestPeriodOrHighestSystem', 'EarliestEpochOrLowestSeries',
    'LatestEpochOrHighestSeries', 'EarliestAgeOrLowestStage',
    'LatestAgeOrHighestStage', 'LowestBiostratigraphicZone',
    'HighestBiostratigraphicZone', 'LithostratigraphicTerms', 'Group', 'Formation',
    'Member', 'Bed']

DWC_ID = ['IdentificationID', 'IdentificationQualifier', 'TypeStatus', 'IdentifiedBy',
    'DateIdentified', 'IdentificationReferences', 'IdentificationVerificationStatus',
    'IdentificationRemarks']

DWC_TAXON = ['TaxonID', 'ScientificNameID', 'AcceptedNameUsageID', 'ParentNameUsageID',
    'OriginalNameUsageID', 'NameAccordingToID', 'NamePublishedInID', 'TaxonConceptID',
    'ScientificName', 'AcceptedNameUsage', 'ParentNameUsage', 'OriginalNameUsage',
    'NameAccordingTo', 'NamePublishedIn', 'NamePublishedInYear', 'HigherClassification',
    'Kingdom', 'Phylum', 'Class', 'Order', 'Family', 'Genus', 'Subgenus',
    'SpecificEpithet', 'InfraspecificEpithet', 'TaxonRank', 'VerbatimTaxonRank',
    'ScientificNameAuthorship', 'VernacularName', 'NomenclaturalCode', 'TaxonomicStatus',
    'NomenclaturalStatus', 'TaxonRemarks']

VN_TRAIT = ['LengthInMM', 'LengthType', 'LengthUnitsInferred', 'MassInG', 'MassUnitsInferred',
    'UnderivedLifeStage', 'UnderivedSex']

DWC_ALL = DWC_RECLEVEL + DWC_OCC + DWC_ORGANISM + DWC_SAMPLE + DWC_EVENT + DWC_LOCATION \
    + DWC_GEO + DWC_ID + DWC_TAXON + VN_TRAIT

DWC_ALL_LOWER = [x.lower() for x in DWC_ALL]
DWC_HEADER_LIST = DWC_ALL_LOWER + ADD_TO_DOWNLOAD_RESULTS
DWC_HEADER = '\t'.join(DWC_HEADER_LIST)

def format_json(json):
    return json.replace('""{','{').replace('}""','}').replace('""','"')

def download_field_list():
    """Create a list of the fields in a download. These are the original field names."""
    field_list = []
    for f in DWC_HEADER_LIST:
        field_list.append(f)
    for f in OMIT_FROM_DOWNLOADS:
        try:
            field_list.remove(f)
        except:
            pass
#    logging.debug('%s: FIELD_LIST: %s' % (__version__, field_list))
    return field_list

def download_header():
    """Create a list of the fields in a download. These are the original field names."""
    fieldlist=download_field_list()
    translated = []
    for f in fieldlist:
        if f in TRANSLATE_HEADER:
            translated.append(TRANSLATE_HEADER[f])
        else:
            translated.append(f)
    return '\t'.join(translated)

def classify(record):
    result = dict(meta=record, reclevel={}, occ={}, organism={}, sample={}, event={},
        loc={}, geo={}, id={}, taxon={})

    for term in DWC_RECLEVEL:
        if record.has_key(term.lower()):
            result['reclevel'][term] = record[term.lower()]

    for term in DWC_OCC:
        if record.has_key(term.lower()):
            result['occ'][term] = record[term.lower()]

    for term in DWC_ORGANISM:
        if record.has_key(term.lower()):
            result['organism'][term] = record[term.lower()]

    for term in DWC_SAMPLE:
        if record.has_key(term.lower()):
            result['sample'][term] = record[term.lower()]

    for term in DWC_EVENT:
        if record.has_key(term.lower()):
            result['event'][term] = record[term.lower()]

    for term in DWC_LOCATION:
        if record.has_key(term.lower()):
            result['loc'][term] = record[term.lower()]

    for term in DWC_GEO:
        if record.has_key(term.lower()):
            result['geo'][term] = record[term.lower()]

    for term in DWC_ID:
        if record.has_key(term.lower()):
            result['id'][term] = record[term.lower()]

    for term in DWC_TAXON:
        if record.has_key(term.lower()):
            result['taxon'][term] = record[term.lower()]

    return result

def search_resource_counts(recs, old_res_counts=None):
    # Build dictionary of resources with their record counts
    res_counts = {}
    gbifdatasetid = None
    for rec in recs:
        if 'gbifdatasetid' in rec:
            gbifdatasetid=rec['gbifdatasetid']
        else:
            gbifdatasetid=rec[TRANSLATE_HEADER['gbifdatasetid']]
        if gbifdatasetid not in res_counts:
            res_counts[gbifdatasetid] = 1
        else:
            res_counts[gbifdatasetid] += 1
    return res_counts


def fun(file1, file2):
    file1=open('file1.txt','w')
    file1.write(''' Hello world
    this is good
    how to save you
    ''')
    file1.close()
    try:
        file1=open('file1.txt' , 'r')
        file2=open('file2.txt','w')

    except IOError:
        print('File does not exist')

    content = file1.readlines()
    type(content)
    for i in range(0, len(content)):
        if i % 2 == 0:
            file2.write(content[i])
        else:
            pass
    file2.close()
fun('file1.txt', 'file2.txt')


"""Define models for pages."""
import os

from django.conf import settings
from django.db import models
from django.template.loaders.app_directories import get_app_template_dirs
from django.utils.translation import ugettext_lazy as _
from wagtail.admin.edit_handlers import FieldPanel
from wagtail.core.models import Page as WagtailPage

def get_templates_choices():
    """
    Return a list of templates as tuples usable as choices.

    Every file within a "pages" template directory that does not start
    with a dot (.) is included. Example, given the following files:
    - an_app/templates/pages/template.html
    - an_app/templates/pages/subdirectory/template.js
    - different_app/templates/pages/template.html

    The returned tuple would be:
    ```
    (
        ("pages/template.html", "pages/template.html"),
        ("pages/subdirectory/template.js", "pages/subdirectory/template.js"),
    )
    ```
    """
    template_dir_list = []
    for template_dir in get_app_template_dirs("templates"):
        if settings.BASE_DIR in template_dir:
            template_dir_list.append(template_dir)

    templates = set()
    for template_dir in template_dir_list + settings.TEMPLATES[0]["DIRS"]:
        full_path = os.path.join(template_dir, "pages")
        for base_dir, dirnames, filenames in os.walk(full_path):
            rel_dir = os.path.relpath(base_dir, template_dir)
            for filename in filenames:
                if not filename.startswith("."):
                    templates.add(os.path.join(rel_dir, filename))

    template_list = []
    for template in templates:
        template_list.append((template, template))

    return template_list

class Page(WagtailPage):
    """Define a page that uses a user selected template."""

    TEMPLATE_HELP_TEXT = _("Template to be used to render the page.")
    custom_template = models.CharField(
        max_length=255,
        blank=True,
        help_text=TEMPLATE_HELP_TEXT,
        verbose_name=_("Template"),
    )
    settings_panels = WagtailPage.settings_panels + [FieldPanel("custom_template")]

    def __init__(self, *args, **kwargs):
        """Set template based on custom_template property."""
        super().__init__(*args, **kwargs)

        self._meta.get_field("custom_template").choices = [
            ("", _("Default (%(template)s)") % {"template": self.template}),
            [_("Template override"), get_templates_choices()],
        ]

        if self.custom_template:
            self.template = self.custom_template


import sys
sys.stdin = open('input.txt')
input = sys.stdin.readline

def union_1(v, u):
    v_p = find_1(v)
    u_p = find_1(u)
    if rank[v_p] > rank[u_p]:
        parent[u_p] = v_p
    else:
        parent[v_p] = u_p
        if rank[u_p] == rank[v_p]:
            rank[u_p] += 1

def find_1(node):
    if parent[node] == node:
        return node
    parent[node] = find_1(parent[node])
    return parent[node]

n, m = map(int, input().split())
parent = [i for i in range(n)]
rank = [0] * n
for i in range(1, m+1):
    u, v = map(int, input().split())
    u_p = find_1(u)
    v_p = find_1(v)
    if v_p == u_p:
        print(i)
        break
    union_1(v, u)
else:
    print(0)


import csv
import os
import shutil

from model import *
from util import Logger

class CSVParser:
    """Class Responsável por manipular os arquivos de saída '.csv'"""

    # diretório dos arquivos de saída '.csv' (datasets)
    __output_dir = os.getcwd() + '/csv'
    __periodos_csv = f'{__output_dir}/periodos.csv'
    __turmas_csv = f'{__output_dir}/turmas.csv'
    __atividades_csv = f'{__output_dir}/atividades.csv'
    __estudantes_csv = f'{__output_dir}/estudantes.csv'
    __execucoes_csv = f'{__output_dir}/execucoes.csv'
    __solucoes_csv = f'{__output_dir}/solucoes.csv'
    __erros_csv = f'{__output_dir}/erros.csv'

    @staticmethod
    def __create_csv_file(filename: str, header: List[str]):
        with open(filename, 'w') as f:
            header = ','.join(header) + os.linesep
            f.write(header)

    @staticmethod
    def create_output_dir():
        """Cria a pasta e os arquivos de saídas '.csv' (datasets)."""
        try:
            # se o diretório de saída existir, apaga seu conteúdo
            if os.path.exists(CSVParser.__output_dir):
                shutil.rmtree(CSVParser.__output_dir)
            # cria o diretório de saída
            os.mkdir(CSVParser.__output_dir)
            # cria todos os arquivos de saída '.csv' (datasets)
            CSVParser.__create_csv_file(CSVParser.__periodos_csv, Periodo.get_csv_header())
            CSVParser.__create_csv_file(CSVParser.__turmas_csv, Turma.get_csv_header())
            CSVParser.__create_csv_file(CSVParser.__atividades_csv, Atividade.get_csv_header())
            CSVParser.__create_csv_file(CSVParser.__estudantes_csv, Estudante.get_csv_header())
            CSVParser.__create_csv_file(CSVParser.__execucoes_csv, Execucao.get_csv_header())
            CSVParser.__create_csv_file(CSVParser.__solucoes_csv, Solucao.get_csv_header())
            CSVParser.__create_csv_file(CSVParser.__erros_csv, Erro.get_csv_header())
        except OSError:
            Logger.error('Erro ao criar diretório de saída!')

    @staticmethod
    def __write_to_csv(entidades: List[CSVEntity], path: str, mode: str):
        """
        Salva uma lista de :class:`CsvEntity` num arquivo no formato CSV.

        :param entidades: Lista de Entidades a serem salvas.
        :type entidades: List[CSVEntity]
        :param path: Caminho absoluto do arquivo '.csv' onde as Entidades devam ser salvas.
        :type path: str
        :param mode: Modo de abertura do arquivo.
        :type mode: str
        """
        Logger.info(f'Salvando entidades no arquivo: {path}')
        rows = []
        for entidade in entidades:
            rows.append(entidade.as_row())

        with open(path, mode) as file:
            writter = csv.writer(file)
            writter.writerows(rows)

    @staticmethod
    def salvar_periodos(periodos: List[Periodo]):
        """
        Salva uma lista de :class:`Periodo` no arquivo '.csv' (dataset).

        :param periodos: Lista de Períodos a serem salvos.
        """
        CSVParser.__write_to_csv(periodos, CSVParser.__periodos_csv, 'a')

    @staticmethod
    def salvar_turmas(turmas: List[Turma]):
        """
        Salva uma lista de :class:`Turma` no arquivo '.csv' (dataset).

        :param turmas: Lista de Turmas a serem salvos.
        """
        CSVParser.__write_to_csv(turmas, CSVParser.__turmas_csv, 'a')

    @staticmethod
    def salvar_atividades(atividades: List[Atividade]):
        """
        Salva uma lista de :class:`Atividade` no arquivo '.csv' (dataset).

        :param atividades: Lista de Atividades a serem salvas.
        """
        CSVParser.__write_to_csv(atividades, CSVParser.__atividades_csv, 'a')

    @staticmethod
    def salvar_estudantes(estudantes: List[Estudante]):
        """
         Salva uma lista de :class:`Estudante` no arquivo '.csv' (dataset).

         :param estudantes: Lista de Estudantes a serem salvos.
         """
        CSVParser.__write_to_csv(estudantes, CSVParser.__estudantes_csv, 'a')

    @staticmethod
    def salvar_execucoes(execucoes: List[Execucao]):
        """
         Salva uma lista de :class:`Execucao` no arquivo '.csv' (dataset).

         :param execucoes: Lista de Execucões a serem salvas.
        """
        CSVParser.__write_to_csv(execucoes, CSVParser.__execucoes_csv, 'a')

    @staticmethod
    def salvar_solucoes(solucoes: List[Solucao]):
        """
         Salva uma lista de :class:`Solucao` no arquivo '.csv' (dataset).

         :param solucoes: Lista de Solucões a serem salvas.
        """
        CSVParser.__write_to_csv(solucoes, CSVParser.__solucoes_csv, 'a')

    @staticmethod
    def salvar_erros(erros: List[Erro]):
        """
         Salva uma lista de :class:`Erro` no arquivo '.csv' (dataset).

         :param erros: Lista de Erros a serem salvos.
        """
        CSVParser.__write_to_csv(erros, CSVParser.__erros_csv, 'a')