import torch
from torch import nn
import numpy as np
from datasets.CPSCDataset import CPSCDataset2D
from models.defaults import S_2RB2D2
from torch.utils.data import random_split
import torch.optim as optim
from tqdm import tqdm
import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel as DDP
import csv
import argparse
import torch.multiprocessing as mp
import os

LEARNING_RATE = 0.001

class Experiment:
    """ messy - use metaprogramming techniques torch clean up 'enum' when time allows """
    def __init__(self):
        self.vallosses = []
        self.valaccs = []
        self.trainlosses = []
        self.learning_rate = 0

    def log_metric(self, metric, value):
        if metric == 'val_loss':
            self.vallosses.append(value)

        elif metric == 'val_acc':
            self.valaccs.append(value)

        elif metric == 'train_loss':
            self.trainlosses.append(value)

    def log_parameter(self, param, value):
        if param == 'learning_rate':
            self.learning_rate = value

def scale_lr(batch_size, lr, min_batch_size):
    return lr * (batch_size / min_batch_size)

def setup(rank, world_size, backend):
    # initialize the process group
    dist.init_process_group(backend, rank=rank, world_size=world_size)

def cleanup():
    dist.destroy_process_group()

def output_size(input_size, filter_size=1, padding=0, stride=1):
    return 1 + np.floor((input_size - filter_size + 2 * padding) / stride)

def load_data(train_dir, train_ref, test_dir, test_ref):

    trainset = CPSCDataset2D(data_dir=train_dir,
                             reference_file_csv=train_ref,
                             wavelet='mexh',
                             leads=3,
                             test=False
                             )

    testset = CPSCDataset2D(data_dir=test_dir,
                            reference_file_csv=test_ref,
                            wavelet='mexh',
                            leads=3,
                            test=True
                            )

    return trainset, testset

def train(model, optimizer, criterion, trainloader, gpu_id):
    model.train()
    total_loss = 0
    epoch_steps = 0
    for batch_idx, (images, labels) in tqdm(enumerate(trainloader)):
        optimizer.zero_grad()
        images = images.cuda(gpu_id, non_blocking=True)
        labels = labels.cuda(gpu_id, non_blocking=True)

        pred = model(images)

        loss = criterion(pred, labels)
        loss.backward()

        total_loss += loss.item()
        epoch_steps += 1

        optimizer.step()

    return total_loss / epoch_steps

@torch.inference_mode()
def evaluate(model, criterion, valloader, local_rank):
    # Validation loss
    total_loss = 0.0
    epoch_steps = 0
    total = 0
    correct = 0

    model.eval()
    for i, data in enumerate(valloader, 0):
        inputs, labels = data
        inputs, labels = inputs.cuda(local_rank), labels.cuda(local_rank)
        outputs = model(inputs)

        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

        loss = criterion(outputs, labels)

        total_loss += loss.item()
        epoch_steps += 1

    val_acc = correct / total
    val_loss = total_loss / epoch_steps

    return val_loss, val_acc

@torch.inference_mode()
def test_accuracy(model, testset, answer_path, device="cpu"):

    testloader = torch.utils.data.DataLoader(
        testset, batch_size=4, shuffle=False, num_workers=2
    )

    with open(answer_path, 'w') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(['Recording', 'Result'])
        for data in testloader:
            images, names = data
            images = images.to(device)
            preds = model(images)
            result = torch.argmax(preds, dim=1) + 1

            for i in range(len(names)):
                answer = [names[i], result[i].item()]
                if answer[1] > 9 or answer[1] < 1 or np.isnan(answer[1]):
                    answer[1] = 1
                writer.writerow(answer)
        csvfile.close()

def run(local_rank, world_size, args):
    """
    This is a single process that is linked to a single GPU
    :param local_rank: The id of the GPU on the current node
    :param world_size: Total number of processes across nodes
    """
    experiment = Experiment()
    torch.cuda.set_device(local_rank)

    # The overall rank of this GPU process across multiple nodes
    global_process_rank = args.node_rank * args.gpus + local_rank

    learning_rate = scale_lr(args.replica_batch_size * world_size, LEARNING_RATE)
    experiment.log_parameter("learning_rate", learning_rate)
    print(f"Running DDP model on Global Process with Rank: {global_process_rank}.")

    setup(global_process_rank, world_size, args.backend)

    model = S_2RB2D2()
    model.cuda(local_rank)
    ddp_model = DDP(model, device_ids=[local_rank])

    criterion = nn.CrossEntropyLoss()
    optimizer = optim.SGD(ddp_model.parameters(), lr=learning_rate, momentum=0.9)

    # Load training data
    trainset, testset = load_data(train_dir="validation_set",
                                  train_ref="REF.csv",
                                  test_dir="last100",
                                  test_ref="last100.csv"
                                  )

    test_abs = int(len(trainset) * 0.8)
    train_subset, val_subset = random_split(
        trainset, [test_abs, len(trainset) - test_abs]
    )

    train_sampler = torch.utils.data.distributed.DistributedSampler(
        train_subset, num_replicas=world_size, rank=global_process_rank
    )

    trainloader = torch.utils.data.DataLoader(
        train_subset,
        batch_size=args.replica_batch_size,
        sampler=train_sampler,
        num_workers=8,
    )
    valloader = torch.utils.data.DataLoader(
        val_subset, batch_size=args.replica_batch_size, shuffle=True, num_workers=8
    )

    for epoch in range(args.epochs):
        train_loss = train(
            ddp_model, optimizer, criterion, trainloader, local_rank
        )
        experiment.log_metric("train_loss", train_loss)
        val_loss, val_acc = evaluate(ddp_model, criterion, valloader, local_rank)
        experiment.log_metric("val_loss", val_loss)
        experiment.log_metric("val_acc", val_acc)
    ######################################################################################
    # this should return the csv file with all F1 scores etc...
    test_accuracy(model, testset, answer_path='genetic_answers.csv', device=f'cuda:{local_rank}')
    score(answers_csv_path='genetic_answers.csv', reference_csv_path='top100.csv')

    cleanup()

def score(answers_csv_path, reference_csv_path):
    """ func from CPSC18 official code """
    answers = dict()
    reference = dict()
    A = np.zeros((9, 9), dtype=np.float)
    with open(answers_csv_path) as f:
        reader = csv.DictReader(f)
        for row in reader:
            answers.setdefault(row['Recording'], []).append(row['Result'])
        f.close()
    with open(reference_csv_path) as ref:
        reader = csv.DictReader(ref)
        for row in reader:
            reference.setdefault(row['Recording'], []).append([row['First_label'], row['Second_label'], row['Third_label']])
        ref.close()

    for key in answers.keys():
        value = []
        for item in answers[key]:
            predict = int(item)
        for item in reference[key][0]:
            if item == '':
                item = 0
            value.append(int(item))

        if predict in value:
            A[predict-1][predict-1] += 1
        else:
            A[value[0]-1][predict-1] += 1

    F11 = 2 * A[0][0] / (np.sum(A[0, :]) + np.sum(A[:, 0]))
    F12 = 2 * A[1][1] / (np.sum(A[1, :]) + np.sum(A[:, 1]))
    F13 = 2 * A[2][2] / (np.sum(A[2, :]) + np.sum(A[:, 2]))
    F14 = 2 * A[3][3] / (np.sum(A[3, :]) + np.sum(A[:, 3]))
    F15 = 2 * A[4][4] / (np.sum(A[4, :]) + np.sum(A[:, 4]))
    F16 = 2 * A[5][5] / (np.sum(A[5, :]) + np.sum(A[:, 5]))
    F17 = 2 * A[6][6] / (np.sum(A[6, :]) + np.sum(A[:, 6]))
    F18 = 2 * A[7][7] / (np.sum(A[7, :]) + np.sum(A[:, 7]))
    F19 = 2 * A[8][8] / (np.sum(A[8, :]) + np.sum(A[:, 8]))

    F1 = (F11+F12+F13+F14+F15+F16+F17+F18+F19) / 9

    ## following is calculating scores for 4 types: AF, Block, Premature contraction, ST-segment change.

    Faf = 2 * A[1][1] / (np.sum(A[1, :]) + np.sum(A[:, 1]))
    Fblock = 2 * (A[2][2] + A[3][3] + A[4][4]) / (np.sum(A[2:5, :]) + np.sum(A[:, 2:5]))
    Fpc = 2 * (A[5][5] + A[6][6]) / (np.sum(A[5:7, :]) + np.sum(A[:, 5:7]))
    Fst = 2 * (A[7][7] + A[8][8]) / (np.sum(A[7:9, :]) + np.sum(A[:, 7:9]))

    # print(A)
    print('Total File Number: ', np.sum(A))

    print("F11: ", F11)
    print("F12: ", F12)
    print("F13: ", F13)
    print("F14: ", F14)
    print("F15: ", F15)
    print("F16: ", F16)
    print("F17: ", F17)
    print("F18: ", F18)
    print("F19: ", F19)
    print("F1: ", F1)

    print("Faf: ", Faf)
    print("Fblock: ", Fblock)
    print("Fpc: ", Fpc)
    print("Fst: ", Fst)

    with open('score.txt', 'w') as score_file:
        # print (A, file=score_file)
        print ('Total File Number: %d\n' %(np.sum(A)), file=score_file)
        print ('F11: %0.3f' %F11, file=score_file)
        print ('F12: %0.3f' %F12, file=score_file)
        print ('F13: %0.3f' %F13, file=score_file)
        print ('F14: %0.3f' %F14, file=score_file)
        print ('F15: %0.3f' %F15, file=score_file)
        print ('F16: %0.3f' %F16, file=score_file)
        print ('F17: %0.3f' %F17, file=score_file)
        print ('F18: %0.3f' %F18, file=score_file)
        print ('F19: %0.3f\n' %F19, file=score_file)
        print ('F1: %0.3f\n' %F1, file=score_file)
        print ('Faf: %0.3f' %Faf, file=score_file)
        print ('Fblock: %0.3f' %Fblock, file=score_file)
        print ('Fpc: %0.3f' %Fpc, file=score_file)
        print ('Fst: %0.3f' %Fst, file=score_file)

        score_file.close()

def get_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--run_id", type=str)
    parser.add_argument("-b", "--backend", type=str, default="nccl")
    parser.add_argument("-n", "--nodes", default=1, type=int, metavar="N", help="total number of compute nodes",)
    parser.add_argument("-g", "--gpus", default=2, type=int, help="number of gpus per node")
    parser.add_argument("-nr", "--node_rank", default=0, type=int, help="ranking within the nodes, starts at 0",)
    parser.add_argument("--epochs", default=50, type=int, metavar="N", help="number of total epochs to configs",)
    parser.add_argument("--replica_batch_size", default=32, type=int, metavar="N",
                        help="number of total epochs to configs",)
    parser.add_argument("--master_addr", type=str, default="localhost",
                        help="""Address of master, will default to localhost if not provided. Master must be able to
                         accept network traffic on the address + port.""",)
    parser.add_argument("--master_port", type=str, default="8892", help="""Port that master is listening on, will
                        default to 29500 if not provided. Master must be able to accept network traffic on the host and port.""",)
    return parser.parse_args()

if __name__ == "__main__":
    args = get_args()
    world_size = args.gpus * args.nodes

    # Make sure all nodes can talk to each other on the unprivileged port range
    # (1024-65535) in addition to the master port
    os.environ["MASTER_ADDR"] = args.master_addr
    os.environ["MASTER_PORT"] = args.master_port

    mp.spawn(
        run, args=(world_size, args,), nprocs=args.gpus, join=True,
    )


# critter detector - polling solution

from gpiozero import DistanceSensor, Button, LED
from time import sleep

dsense = DistanceSensor(echo = 24, trigger = 18)
button = Button(16)
theLED = LED(12)

def IntruderAlert(device):
    if (device == "DistanceSensor"):
        theLED.blink(on_time = .25, off_time = .75, n = 10, background = True)
        print("Proximity: Intruder Alert!")
    else:
        print("Button: Intruder Alert!")
        theLED.blink(on_time = .75, off_time = .25, n = 10, background = True)

try:
    while True:
        sleep(3)
        intruderDistance = dsense.distance
        print(intruderDistance)
        if (intruderDistance < .3):
            IntruderAlert("DistanceSensor")
        if (button.is_pressed):
            IntruderAlert("Button")

except KeyboardInterrupt:
    print("cleanup")

Raspberry Pi Weekly/2020 - q1/05_08 polling interrupt/polling_solution.py


#! /usr/bin/python3
import os
import json
import praw
import time
import tweepy
import configparser

# Load custom settings from PRAW official file
if os.path.exists('./praw.ini'):
    praw_config = configparser.RawConfigParser()
    praw_config.read_file(open('./praw.ini'))

def save_tweets(posts):
    with open('posts.json', 'w') as outfile:
        print("\nPost saved")
        json.dump(posts, outfile, indent=4)

reddit = praw.Reddit(str(praw_config.get('user', 'nickname')))

print("Logged in as: " + str(reddit.user.me()))
print()

user = reddit.redditor(str(praw_config.get('user', 'nickname')))
posts = {}

# Load settings for tweepy
if os.path.exists('./tweepy.ini'):
    tweepy_config = configparser.RawConfigParser()
    tweepy_config.read_file(open('./tweepy.ini'))
else:
    print('tweepy.ini missing')

# Authenticate to Twitter
auth = tweepy.OAuthHandler(str(tweepy_config.get('tweepy', 'consumer_key')), str(tweepy_config.get('tweepy', 'consumer_secret')))
auth.set_access_token(str(tweepy_config.get('tweepy', 'access_token')), str(tweepy_config.get('tweepy', 'access_secret')))

# Create API object
api = tweepy.API(auth)

if os.path.exists('./posts.json'):
    print("File posts found")
    with open('./posts.json') as json_file:
        posts = json.load(json_file)
        print("Posts item: " + str(len(posts)))

excludes = str(praw_config.get('user', 'exclude'))
excludes = excludes.split(',')

for post in user.upvoted(limit=100):
    if post.id not in posts:
        tweet_it = True
        print("Missing " + post.id + " post")

        for exclude in excludes:
            if exclude.lower() == str(post.subreddit).lower():
                tweet_it = False
                break

        if 'crosspost_parent_list' in vars(post):
            if str(post.author.name).lower() == praw_config.get('user', 'nickname'):
                print("Crosspost of the user that is also the author, avoid publishing - ignored")
                continue

        if 'u_' + str(praw_config.get('user', 'nickname')) == str(post.subreddit).lower():
            continue

        if tweet_it:
            posts[post.id] = {'title': post.title, 'subreddit': str(post.subreddit).lower(), 'permalink': post.permalink}
            # Create a tweet
            print('Posting new tweet')
            save_tweets(posts)
            api.update_status(post.title + ' via /r/' + str(post.subreddit) + "\nhttps://www.reddit.com" + post.permalink)
            # Wait 10 minutes before tweet it
            time.sleep(600)


import argparse
import sys

from kedehub.services.identities_updater import identity_merge_users, identity_merge_users_with_human_help
from kedehub.services.project_service import load_all_project_names

def identity_merge_project(options):
    verbose = options.verbose

    projects_to_update = options.project
    if not projects_to_update:
        projects_to_update = load_all_project_names()

    number_or_projects_to_update = len(projects_to_update)

    print("First pass...")
    len_users, lean_authors, len_matched_users_by_email, len_matched_users_by_email_and_name, \
    authors_updated, users_inserted, users_merged_count, authors_merged_count = identity_merge_users(projects_to_update, verbose)
    print('Successfully merged {} into {} users with {} authors for {} projects. Created {} new users. '.format(len_users, len_matched_users_by_email_and_name, authors_updated, number_or_projects_to_update, users_inserted))

    print("Second pass...")
    len_users, lean_authors, len_matched_users_by_email, len_matched_users_by_email_and_name, \
    authors_updated, users_inserted, users_merged_count, authors_merged_count = identity_merge_users_with_human_help(projects_to_update, verbose)
    print(
        'Successfully merged {} into {} users with {} authors for {} projects. Created {} new users. '.format(len_users,
                                                                                len_matched_users_by_email_and_name,
                                                                                authors_updated,
                                                                                number_or_projects_to_update,
                                                                                users_inserted))

def parse_args(args):
    parser = argparse.ArgumentParser(prog='kedehub',
                                 description='Extract KEDE statistics from Git repositories')
    command_parsers = parser.add_subparsers(dest='subparser_name')

    create_identity_merge_parser(command_parsers)

    return parser.parse_args(args)

def create_identity_merge_parser(command_parsers):
    identity_merge_parser = command_parsers.add_parser('identity-merge', help='Merge identities of existing projects')
    identity_merge_parser.add_argument('-p', '--project', nargs='+',
                                       help='Name of the project which identities to merge')
    identity_merge_parser.add_argument('--verbose', dest='verbose', action='store_true')
    identity_merge_parser.add_argument('--no-verbose', dest='verbose', action='store_false')
    identity_merge_parser.set_defaults(verbose=False)
    identity_merge_parser.set_defaults(func=identity_merge_project)

def Main() -> None:
    # parse the args
    parsed_args = parse_args(sys.argv[1:])
    # call whatever function was selected
    parsed_args.func(parsed_args)

if __name__ == '__main__':
  Main()


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

from libs.data import (
    scan_result,
    scan,
    system_settings,
    target
)
from gosint.celery import app
from celery.result import AsyncResult
from apps.assets.models import SubDomain, IP, Port, IPC
from time import sleep
import IPy, re

def domaininfo_scan():
    """
    域名信息收集
    :return:
    """
    # DONE: 先处理target.domain中的domain信息
    if target.domain:
        temp_domain = []
        if system_settings.debug:
            print(len(target.domain))
        for _ in target.domain:
            _ = _.strip()
            try:
                if _ not in scan_result.domain:
                    temp_domain.append(SubDomain(subdomain=_, scan_task=scan.task, tools='手工导入'))
                    scan_result.domain.append(_)
            except Exception as e:
                print(e)
                print(_)
                continue
        SubDomain.objects.bulk_create(temp_domain, ignore_conflicts=True)

    scan_queue = []
    if system_settings.debug:
        print(len(scan_result.domain))
    print("[+] Running domaininfo_scan...")
    # 多domain同时发送客户端, 以10个列表的额度发送到客户端，客户端结果接收服务端增加多result处理 by _lin9e 2021.7.28
    for i in range(0, len(scan_result.domain), 50):
        domains = scan_result.domain[i:i+50]
        domaininfo_scan = app.send_task('domaininfo.run', args=(domains,), queue='domaininfo')
        scan_queue.append(AsyncResult(domaininfo_scan.id))
    while True:
        for task in scan_queue:
            if task.successful():
                if task.result['result']:
                    for domaininfo_result in task.result['result']:
                        try:
                            domain = domaininfo_result['domain']
                            domain_type = domaininfo_result['type']
                            domain_record = ','.join(domaininfo_result['record'])
                            domain_ips = domaininfo_result['ips']
                            sub = SubDomain.objects.get(subdomain=domain)
                            sub.domain_type = domain_type
                            sub.record = domain_record
                            sub.domain_ips = domain_ips
                            sub.save()
                            domain_ips_list = []
                            # 是不是CND，都添加到webport==80中，用于web发现、其他端口，则正常通过端口扫描到web发现的过程
                            scan_result.webport.append({'domain': domain, 'port': 80})
                            if len(domain_ips) < 2:  # 如果一个域名解析的ip地址大于1个，则判定为CDN地址
                                cdn = False
                            else:
                                cdn = True
                                # TODO: cdn结果的端口插入问题
                                # Port.objects.get_or_create(port='80', scan=scan.task, service='', ip=ip,
                                #                            ip_port=ip_port, tools=task.result['tool'])
                            for ip in domain_ips:
                                domain_ips_list.append(IP(ip=ip, scan=scan.task, subdomain=sub, is_cdn=cdn, tools='subdomain'))
                                # fix bug: 2021.1.14: 如果为CDN的话，则不去扫描端口，而直接将域名添加到webport，进行httpx扫描
                                # 内网IP则直接不扫端口，IPy.IP(ip).iptype() == 'PUBLIC' add by _lin9e 2021.8.5
                                # 内网ip扫描 - 2021.12.13
                                # if not cdn and IPy.IP(ip).iptype() == 'PUBLIC':
                                if not cdn:
                                    scan_result.ip.append(ip)
                            IP.objects.bulk_create(domain_ips_list)
                        except Exception as e:
                            print(domaininfo_result['domain'])
                            print(e)
                            continue
                scan_queue.remove(task)
            elif task.failed():
                scan_queue.remove(task)
        if not scan_queue:
            break
        sleep(0.5)    # fix bug: 2021.1.14: 修复单核cpu占用过高的问题

    # DONE: 处理target.ip中的ip信息，如果有网段，需要解析网段
    # TODO：需要先判断ip是否存活
    # DONE：判断内网ip，如果是内网ip，直接跳过端口扫描(解析到的IP)，直接添加的内网IP则可以扫描
    if target.ip:
        temp_ip = []
        print(target.ip)
        for _ in target.ip:
            try:
                results = IPy.IP(_)
                for ip in results:
                    temp_ip.append(IP(ip=str(ip), scan=scan.task))
                    scan_result.ip.append(str(ip))
                    scan_result.webport.append({'domain': ip, 'port': 80})
            except Exception as e:
                print(e)
                print(ip)
                continue
        IP.objects.bulk_create(temp_ip, ignore_conflicts=True)

    # 扫描IP去重 2021.7.27 by _lin9e
    try:
        scan_result.ip = list(set(scan_result.ip))
    except Exception as e:
        print(e)

    print("[+] Finish domaininfo_scan. Counts of no_cdn and no_priv ip is {}! Counts of all 80 web is {}".format(
        str(len(scan_result.ip)), str(len(scan_result.webport))))
    # if system_settings.debug:
    #     # debug模式下只存5个ip进行扫描
    #     scan_result.ip = scan_result.ip[:5]
    #     print(scan_result.ip)

    """
    IPC C段情报统计 add by _lin9e in 2021.9.9
    """
    print("[*] Running IP C line...")
    try:
        ipcs = []   # django添加数组
        ipc_list = []    # 整理C段
        for ip in scan_result.ip:
            ipc_list.append(re.findall(r'\d+?\.\d+?\.\d+?\.', ip)[0] + '0/24')
        count_ipc = dict()  # C段IP及对应主机数量字典
        for item in ipc_list:
            if item in count_ipc:
                count_ipc[item] += 1
            else:
                count_ipc[item] = 1
        for ip_c in count_ipc:
            try:
                ipcs.append(IPC(ipc=ip_c, ipc_count=count_ipc[ip_c], scan=scan.task))
                scan_result.ipc.append({'ipc': ip_c, 'count': count_ipc[ip_c]})
            except Exception as e:
                print(e)
        IPC.objects.bulk_create(ipcs)
        print("[+] Finish IP C line, count of C is {}".format(len(count_ipc)))
    except Exception as e:
        print(e)


# **
# ** SocialSimV5: Implementation of Graphs algorithm to create social simulation
# **
# ** Author: Roy Dabire
# ** Date:   October 2019

import random  # Used to calculate probabilities
from LinkedList import *  # Used throughout to store nodes referenced and implemented in practical 3
from Heaps import *  # Used in popularity method referenced and implemented in practical 7
import matplotlib.pyplot as plt  # Used for plotting features
import os  # Used in memory usage package
import psutil  # Package to calculate memory usage sourced from python org
import timeit  # Used to track the time a particular method/function took to execute sourced from python org

class SocialSim:

    def __init__(_self):
        _self.SocialSim = LinkedList() #LinkedList from Practical 3
        _self.numPeople = 0
        _self.postId = 1

        _self.totalposts = LinkedList() #LinkedList from Practical 3
        _self.total_posts = 0

        _self.total_likes_given = 0
        _self.likeswithoutclickbait = 0  #Results did not look correct so ommited from investigation
        _self.likeswithclickbait = 0     #Results did not look correct so ommited from investigation

        _self.total_followed = 0

        _self.likeprobability = 0
        _self.followprobability = 0
        _self.dislikeprobability = 0
        _self.clickbaitfactor = 1 #default value

    def addPerson(self, name):
        new_person = User(name)
        if not self._person_exist(name):
            self.SocialSim.insertFirst(new_person) #LinkedList from Practical 3
            print(new_person.name, " has been added")
            self.numPeople += 1
        else:
            print("Username has already been taken. ^Tip use: ", name, random.randint(0, 1000))
        print()

    def delete_user(self, person):
        v1 = self._getPerson(person)
        if not self._person_exist(person):
            print(person, "does not exist. ^Tip check spelling of name")

        else:
            for users in self.SocialSim:
                if users == v1:
                    self.SocialSim.removeMiddle(users) #LinkedList from Practical 3
                    self.numPeople -= 1
                    print(person, "has been removed from the social network")

    def find(self, user):
        v1 = self._getPerson(user)
        if not self._person_exist(user):
            print(user, "does not exist. ^Tip check spelling of name")
        else:
            for users in self.SocialSim:
                if users == v1:
                    print(user, "is in the network")

    def _person_exist(self, name):
        exist = False
        for item in self.SocialSim:
            if item.name == name:
                exist = True
        return exist

    def _getPerson(self, person):
        for item in self.SocialSim:
            if item.name == person:
                return item

    def Follow(self, person1, person2, show=True):
        if not self._person_exist(person1):
            print(person1, "does not exist to be able to action a follow. ^Tip check spelling of name")
        elif not self._person_exist(person2):
            print(person2, "does not exist to be able to action a follow. ^Tip check spelling of name")

        elif self._alreadyfollowing(person1, person2) is True:
            if show is True:
                print(person1, "already following", person2)

        else:
            v1 = self._getPerson(person1)
            v2 = self._getPerson(person2)
            v1._addFollow(v2)
            v2._addFollower(v1)
            self.total_followed += 1
            if show is True:
                print(person1, "is following", person2)
        print()

    def _alreadyfollowing(self, person1, person2):
        alreadyfollowing = False
        v1 = self._getPerson(person1)
        v2 = self._getPerson(person2)

        for i in v1._check_following():
            if i == v2:
                alreadyfollowing = True
        return alreadyfollowing

    def unFollow(self, person1, person2):
        v1 = self._getPerson(person1)
        v2 = self._getPerson(person2)
        if not self._person_exist(person1):
            print("Cannot unfollow as", person1, "does not exist ^Tip check spelling of name")
        elif not self._person_exist(person2):
            print("Cannot unfollow as", person2, "does not exist ^Tip check spelling of name")

        elif v1._emptyFollowing():
            print(person1, "is not following anyone")

        elif self._alreadyUnfollowed(person1, person2) is True:
            print("Unable to unfollow as", person1, "does not follow", person2, "^Tip check spelling of name")

        else:
            v1._removeFollow(v2)
            v2._removeFollowers(v1)
            print(person1, "unfollowed", person2)

    def _alreadyUnfollowed(self, person1, person2):
        alreadyUnfollowed = True
        v1 = self._getPerson(person1)
        v2 = self._getPerson(person2)

        for i in v1._check_following():
            if i == v2:
                alreadyUnfollowed = False
        return alreadyUnfollowed

    def List_of_followers(self, person):
        v1 = self._getPerson(person)
        if not self._person_exist(person):
            print(person, "does not exist. ^Tip check spelling of name")
        else:
            v1._list_followers()

    def List_of_following(self, person):
        v1 = self._getPerson(person)
        if not self._person_exist(person):
            print(person, "does not exist. ^Tip check spelling of name")
        else:
            for i in self.SocialSim:
                if v1 in i.follower_list:
                    print(person, "follows", i.name)
            print(person, "follows a total of:", v1.totalFollowing, "user")

    def set_probabilities(self, like, follow, dislike, clickbait):  # clickbait will be set to 1 as a default value
        self.likeprobability = float(like) / 100
        self.followprobability = float(follow) / 100
        self.dislikeprobability = float(dislike) / 100
        self.clickbaitfactor = int(clickbait)
        print("Probabilities of liking a post set to: ", self.likeprobability)
        print("Probability of following a user after liking a post set to: ", self.followprobability)
        print("Probabilities of disliking a post set to: ", self.dislikeprobability)
        print("Clickbait factor set to: ", self.clickbaitfactor)

    def Post(self, person, message, clickbait):
        if not self._person_exist(person):
            print(person, "does not exist to be able to action a post. ^Tip check spelling of name\n")

        else:
            v1 = self._getPerson(person)
            clickbaitFactor = float(clickbait)
            post = Post(v1, message, self.postId, clickbaitFactor)
            v1._add_post_ToUserList(post)
            self.totalposts.insertFirst(post)
            print(person, "has just posted....", "postId number is:", self.postId, "Clickbait factor is:",
                  post.clickbait)
            self.postId += 1
            self.total_posts += 1
            for people in v1._getFollowers():
                self._like_post(people.name, post.postId)
                if post.clickbait == 1:
                    self.likeswithoutclickbait += 1  # This was an attempt to track the likes coming from posts
                    # with/out clickbait factor.
                elif post.clickbait > 1:
                    self.likeswithclickbait += 1

    def remove_post(self, person, postId):
        v1 = self._getPerson(person)
        if not self._person_exist(person):
            print(person, "does not exist to be able to action a post. ^Tip check spelling of name\n")

        elif self._postExistence(person, postId) is False:
            print("Post with postId: ", postId, "does not exist. ^Tip check postId number\n")

        else:
            for i in v1._getPosts():
                if i.postId == int(postId):
                    v1._removing_post(i)
            print("PostId:", postId, "posted by", person, "has been removed")

    def _postExistence(self, person, postId):
        v1 = self._getPerson(person)
        exist = False
        for i in v1._getPosts():
            if i.postId == int(postId):
                exist = True
        return exist

    def See_Posts(self, person):
        v1 = self._getPerson(person)
        if not self._person_exist(person):
            print(person, "does not exist to be able to action a post. ^Tip check spelling of name\n")

        elif v1._emptyPosts() is True:
            print(person, "has not posted yet\n")
        else:
            posts = v1._getPosts()
            for i in posts:
                print(i.user.name, "postId number", i.postId, ":", i.message)

    def See_SpecificPost(self, person, postId):
        v1 = self._getPerson(person)
        if not self._person_exist(person):
            print(person, "does not exist. ^Tip check spelling of name\n")

        elif v1._emptyPosts() is True:
            print(person, "has not not posted yet")

        else:
            for i in v1._getPosts():
                if i.postId == int(postId):
                    print(person, "postId number", postId, ":", i.message)

    def _like_post(self, user, postId, show=True):  # Private and used when a post is created
        if not self._person_exist(user):
            print(user, "does not exist. ^Tip check spelling of name\n")

        elif self._alreadyLiked(user, postId) is True:
            print(user, "has already liked postId:", postId, "\n")

        else:

            v1 = self._getPerson(user)
            for posts in self.totalposts:
                if posts.postId == int(postId):
                    post = posts
                    if random.random() < self.likeprobability * post.clickbait:
                        post._Likes_received(user)
                        v1._has_liked_a_post()
                        v1._posts_user_likes(post)
                        self.total_likes_given += 1
                        if show is True:
                            print(user, "has liked", post.user.name, "post:", post.message)
                            print()
                        if random.random() < self.followprobability:
                            self.Follow(user, post.user.name, show=False)

    def like_post(self, person1, person2, postId):  # Public and used for manual likes
        v1 = self._getPerson(person1)
        v2 = self._getPerson(person2)

        if self._person_exist(person1) is False:
            print("Cannot like post as", person1, "does not exist\n")
        elif self._person_exist(person2) is False:
            print("Cannot like post as", person2, "does not exist\n")

        elif self._alreadyLiked(person1, postId) is True:
            print(person1, "has already liked post by", person2, "postId:", postId)
        else:
            for i in v2._getPosts():
                if i.postId == int(postId):
                    i._Likes_received(v1)
                    self.total_likes_given += 1
                    print(person1, "has liked", person2, "post:", i.message)

    def _alreadyLiked(self, user, postId):
        alreadyliked = False
        v1 = self._getPerson(user)

        for posts in self.totalposts:
            if posts.postId == int(postId):
                if v1 in posts._Post_likes():
                    alreadyliked = True
        return alreadyliked

    def likeTotal(self, person, postId):
        v1 = self._getPerson(person)
        if not self._person_exist(person):
            print(person, "does not exist. ^Tip check spelling of name\n")
        else:
            for i in v1._getPosts():
                if i.postId == int(postId):
                    print(person, "postId number", postId, ":", i.message)
                    print("Total likes =", i.likestotal)

    def unlike_post(self, person1, person2, postId):  # Public use for manual unlikes/dislikes
        v1 = self._getPerson(person1)
        v2 = self._getPerson(person2)

        if not self._person_exist(person1):
            print(person1, "does not exist. ^Tip check spelling of name\n")
        elif not self._person_exist(person2):
            print(person2, "does not exist. ^Tip check spelling of name\n")

        elif self._alreadyunliked(person2, postId) is True:
            print(person1, "does not like", person2, "postId:", postId)

        else:
            for post in v2._getPosts():
                if post.postId == int(postId):
                    if v1 in post._Post_likes():
                        post._Remove_likes(v1)
                        print(person1, "has unliked", person2, "post:", post.message)

    def _unlike_post(self, user, postId):  # Private use
        if not self._person_exist(user):
            print(user, "does not exist. ^Tip check spelling of name\n")

        elif self._alreadyunliked(user, postId) is True:
            print(user, "does not like postId:", postId)

        else:
            v1 = self._getPerson(user)
            for posts in self.totalposts:
                if posts.postId == int(postId):
                    post = posts
                    if v1 in post._Post_likes():
                        if random.random() < self.dislikeprobability:
                            post._Remove_likes(v1)
                            print(user, "has unliked post:", post.message)
                            self.total_likes_given -= 1

    def _alreadyunliked(self, user, postId):
        already_unliked = False
        v1 = self._getPerson(user)

        for posts in self.totalposts:
            if posts.postId == int(postId):
                if v1 not in posts._Post_likes():
                    already_unliked = True
        return already_unliked

    def displayNetwork(self):
        print("**** This social network contains", self.numPeople, "people ****\n")
        for person in self.SocialSim:
            print(person.name)
        print()
        print("\n**** Adjacency list of users and who they are following ***\n")
        for user in self.SocialSim:
            print(user.name, ":", user._list_following())
            print()

    def _get_users_followers(self, user):
        if not self._person_exist(user):
            print(user, "does not exist to be able to action a post. ^Tip check spelling of name\n")
        else:
            v1 = self._getPerson(user)
            followers = v1._getFollowers()
            return followers

    def run_timesteps(self, timesteps):  # Timestep defined within the background section of report
        for timestep in range(timesteps):
            process = psutil.Process(os.getpid())
            start_usage = int(process.memory_info().rss)
            startTime = timeit.default_timer()
            for posts in self.totalposts:
                likers = posts._get_likes_received()
                for peeps in likers:
                    followers = self._get_users_followers(peeps)
                    for peeps in followers:
                        self._like_post(peeps.name, posts.postId)
                        end_usage = int(process.memory_info().rss)
                        memory_used = end_usage - start_usage
                        print()
            endTime = timeit.default_timer()
            runningTotal = endTime - startTime
            print("Timestep run time =", str(runningTotal))
            print("\nTimestep memory usage: ", process.memory_info().rss, "byes of memory")

            print("************** Timstep", timestep, "*************\n")
            self.network_statistics()

            label = ["Number of People", "Posts Made", "Total Following Actioned",
                     "Total Likes Given"]
            yvalues = [self.numPeople, self.total_posts, self.total_followed,
                       self.total_likes_given]
            index = [1, 2, 3, 4]
            plt.bar(index, yvalues, color=["rosybrown", "indianred", "salmon", "maroon"])
            plt.xlabel("Statistics measured")
            plt.ylabel("Number (total)")  # Bar plot sourced from FOP unit practical 3 and lecture 3
            plt.title("Network Statistics")
            plt.xticks(index, label, fontsize=5)
            plt.savefig('Network Statistics_Timestep' + str(timestep) + '.png')
            # plt.show()     #User may chose to uncomment this if they would like to display to screen

    def network_statistics(self):
        print("**** Network Overall Statistics ****\n")
        print("Total people: ", self.numPeople)
        print("Total posts: ", self.total_posts)
        print("Total follow actioned: ", self.total_followed)
        print("Total likes given: ", self.total_likes_given)
        label = ["Number of People", "Posts Made", "Total Following Actioned", "Total likes"]
        yvalues = [self.numPeople, self.total_posts, self.total_followed,
                   self.total_likes_given]
        index = [1, 2, 3, 4]
        plt.bar(index, yvalues, color=["rosybrown", "indianred", "salmon", "maroon"])
        plt.xlabel("Statistics measured")
        plt.ylabel("Number (total)")   # Bar plot sourced from FOP unit practical 3 and lecture 3
        plt.title("Network Statistics")
        plt.xticks(index, label, fontsize=5)
        plt.savefig('Final Network Statistics' + '.png')
        # plt.show()    #User may chose to uncomment this if they would like to display to screen

    def UserStatistics(self, user):
        post_popularity = Heap(self.numPeople)
        v1 = self._getPerson(user)
        if self._person_exist(user) is False:
            print(user, "does not exist to be able to display statistics. ^Tip check spelling of name\n")

        # posts
        else:
            print("****", user, "Posts ****\n")
            self.See_Posts(user)
            print()

            # most liked post
            print("****", user, "Most Popular Post/s ****\n")
            like_array = [i.likestotal for i in v1._getPosts()]
            ordered_posts = post_popularity.heapSort(like_array)
            most_liked = ordered_posts[0].priority
            if v1._emptyPosts() is True:
                print("Unable to obtain most popular post as", user, "has not posted\n")

            else:
                for posts in v1._getPosts():
                    if most_liked == 0:
                        print(user, "has not received any likes on any posts")

                    if posts.likestotal == most_liked:
                        print(posts.message)
                        print("Total likes =", most_liked)
            # followers
            print()
            print("****", user, "Followers ****\n")
            v1._list_followers()
            print()
            # following
            print("****", user, "Following ****\n")
            v1 = self._getPerson(user)
            for users in self.SocialSim:
                if users.name == user:
                    print(user, "follows:", v1._list_following())
                    print()

    def Populararity(self):
        with open('Network Popularity Statistics Statistics.txt', 'a+') as f:
            post_popularity = Heap(self.total_posts)
            popular_people = Heap(self.numPeople)
            print("**** This social network had the following posts ****\n", file=f)
            for posts in self.totalposts:
                print(posts.message, file=f)
                print("Total likes =", posts.likestotal, "\n", file=f)
                print()

            print()
            print("**** Most Popular Post/s ****\n", file=f)  #Returns the most popular user by index
            startTime = timeit.default_timer()
            process = psutil.Process(os.getpid())
            start_usage = int(process.memory_info().rss)
            total_likes_posts = [i.likestotal for i in self.totalposts]
            if len(total_likes_posts) < 1:
                print("Unable to find the most popular post as no user has posted yet\n", file=f)
            else:
                ordered_posts_likes = post_popularity.heapSort(total_likes_posts)  #Returns the most popular user by index
                most_liked = ordered_posts_likes[0].priority
                for posts in self.totalposts:
                    if posts.likestotal == most_liked:
                        print(posts.message, "posted by", posts.user.name, file=f)
                        print("Total likes =", most_liked, "\n", file=f)
            endTime = timeit.default_timer()
            runningTotal = endTime - startTime
            print("Heapsort run time ordering popular posts=", str(runningTotal), file=f)

            print("**** Most Popular User/s ****\n", file=f)
            startTime = timeit.default_timer()
            popular_people_list = [people.totalfollowers for people in self.SocialSim]
            if len(popular_people_list) < 1:
                print("Unable to find most popular person as no has followed each other yet\n", file=f)
            else:
                ordered_people = popular_people.heapSort(popular_people_list)
                most_followed_user = ordered_people[0].priority
                for user in self.SocialSim:
                    if user.totalfollowers == most_followed_user:
                        print(user.name, file=f)
                        print("Total followers=", most_followed_user, "\n", file=f)
                        end_usage = int(process.memory_info().rss)
                        print()
            endTime = timeit.default_timer()
            runningTotal = endTime - startTime
            memory_used = end_usage - start_usage
            print("Heapsort run time for ordering popular user =", str(runningTotal), file=f)
            print()
            print("Heapsort memory usage in ordering popular posts and users =", str(memory_used), file=f)
            f.close()

# Class intended to be entirely private
#LinkedList from Practical 3 used throughout class
class User:

    def __init__(self, name):
        self.name = name

        self.following_list = LinkedList()
        self.totalFollowing = 0

        self.follower_list = LinkedList()
        self.totalfollowers = 0

        self.posts = LinkedList()
        self.post_total = 0

        self.posts_user_has_liked = LinkedList()
        self.totalLikesGiven = 0
        self.hasLiked_A_Post = False

    def _has_liked_a_post(self):
        self.hasLiked_A_Post = True

    def _posts_user_likes(self, post):
        self.posts_user_has_liked.insertFirst(post)
        self.totalLikesGiven += 1

    def _get_posts_user_likes(self):
        posts = self.posts_user_has_liked
        return posts

    def _emptyPosts(self):
        if self.posts._isEmpty():
            return True

    def _add_post_ToUserList(self, post):
        self.posts.insertFirst(post)
        self.post_total += 1
        return post

    def _getPosts(self):
        posts = self.posts
        return posts

    def _removing_post(self, postId):
        self.posts.removeMiddle(postId)
        self.post_total -= 1

    def _getFollowers(self):
        followers = self.follower_list
        return followers

    def _emptyFollowing(self):
        if self.following_list._isEmpty():
            return True

    def _check_following(self):
        following = self.following_list
        return following

    def _addFollow(self, person):
        self.following_list.insertFirst(person)
        self.totalFollowing += 1

    def _addFollower(self, person):
        self.follower_list.insertFirst(person)
        self.totalfollowers += 1

    def _list_followers(self):
        a = [i.name for i in self.follower_list]  # List comprehension approved by Valerie (displays the adjacency list)
        print("List of users following", self.name, ":", a)
        print(self.name, "has a total of", self.totalfollowers, "followers")

    def _list_following(self):
        a = [i.name for i in self.following_list]
        return a

    def _removeFollow(self, person):
        self.following_list.removeMiddle(person)
        self.totalFollowing -= 1

    def _removeFollowers(self, person):
        self.follower_list.removeMiddle(person)
        self.totalfollowers -= 1

# Class intended to be entirely private
#LinkedList from Practical 3 used throughout class
class Post:

    def __init__(self, user, message, postId, clickbait):
        self.user = user
        self.message = message
        self.postId = postId
        self.clickbait = clickbait

        self.likes = LinkedList()
        self.likestotal = 0

    def _Likes_received(self, user):
        self.likes.insertFirst(user)
        self.likestotal += 1

    def _get_likes_received(self):
        likes = self.likes
        return likes

    def _Post_likes(self):
        likes = self.likes
        return likes

    def _Remove_likes(self, user):
        self.likes.removeMiddle(user)
        self.likestotal -= 1


class Solution:
    def findAllConcatenatedWordsInADict(self, words: List[str]) -> List[str]:
        s = set(words)

        @cache
        def go(word):
            for i in range(1, len(word)):
                prefix = word[:i]
                suffix = word[i:]

                if prefix in s and (suffix in s or go(suffix)):
                    return True

            return False

        res = []
        for word in words:
            if go(word):
                res.append(word)

        return res


import math
import matplotlib.pyplot as plt
import os
import sys

kVals = [5, 10, 20, 50, 100]

def readQrel(qrelFile):
    relevant = {}
    print('reading qrel')

    with open(qrelFile, 'r') as qrel:
        line = qrel.readline()

        while line:
            split = line.strip().split()

            qID, docID, rel = split[0], split[2], split[3]

            if rel != '0':
                if qID in relevant:
                    relevant[qID].append(docID)
                else:
                    relevant[qID] = [docID]

            line = qrel.readline()

    qrel.close()

    return relevant

def readRes(resFile):
    results = {}
    print('reading res')

    with open(resFile, 'r') as res:
        line = res.readline()

        while line:
            split = line.strip().split()

            qID, docID = split[0], split[2]

            if qID in results:
                results[qID].append(docID)
            else:
                results[qID] = [docID]

            line = res.readline()

    res.close()

    return results

def calcNDCG(rel):
    i, dcg = 1, 0.0

    for score in rel:
        if i == 1:
            dcg += score
        else:
            dcg += score / math.log(i)

        i += 1

    return dcg

def calcCutoff(P, R, F1):
    tempP, tempR, tempF1 = {}, {}, {}

    for k in kVals:
        tempP[k] = math.fsum(P[k]) / len(P[k])
        tempR[k] = math.fsum(R[k]) / len(R[k])
        tempF1[k] = math.fsum(F1[k]) / len(F1[k])

    return tempP, tempR, tempF1

def printer(qID, ret, relDocs, relRet, avgPrec, rPrec, dcg, precCutoff, recCutoff, f1Cutoff):
    print('Query ID (num):', qID)
    print('\tRetrieved:', ret)
    print('\tRelevant:', relDocs)
    print('\tRelevant retrieved:', relRet)
    print('Avg prec (non-interpolated):', avgPrec)
    print('nDCG:', dcg)

    print('\n    k      Precision@k   Recall@k    F1-Measure@k')
    print('   ---     -----------   --------    ------------')
    for k in kVals:
        print('{0:4d} docs    {1:.4f}       {2:.4f}        {3:.4f}'.format(k, precCutoff[k], recCutoff[k], f1Cutoff[k]))
    print('R-Precision:', rPrec)

def graph(prec, rec, qID):
    print('graphing', qID)
    plt.plot(rec, prec)
    plt.title('Precision - Recall Curve for Query ' + qID)
    plt.xlabel('Precision')
    plt.ylabel('Recall')
    plt.savefig(os.getcwd() + '\\Graphs\\' + qID + '_all')
    plt.close()

def calc(option, relevant, results):
    totQuery, totRel, totRelRet, totRet = 0, 0, 0, 0
    avgPrec, rPrec, nDCG = [], [], []
    P, R, F1 = {}, {}, {}

    for qID in sorted(results.keys()):
        totQuery += 1
        relevanceScore = []
        totPrec, totRec = {}, {}
        sumPrec, ret, relRet, rp = 0, 0, 0, 0

        res = results[qID]

        if qID not in relevant:
            continue

        precCutQuery, recCutQuery, f1CutQuery = {}, {}, {}

        relResDocs = relevant[qID]
        numRel = len(relResDocs)
        totRel += numRel

        for doc in res:
            ret += 1
            isRelevant = False

            if doc in relResDocs:
                relRet += 1
                isRelevant = True

            precision = relRet / (ret)
            score = 0

            if isRelevant:
                sumPrec += precision
                score = 1

            relevanceScore.append(score)

            if numRel == 0:
                recall = 0
            else:
                recall = relRet / numRel

            if ret <= numRel:
                rp = relRet

            totPrec[ret] = precision
            totRec[ret] = recall

        count = ret
        finalRecall = relRet / numRel

        allPrec, allRec = [], []

        while count <= 1000:
            totPrec[count] = relRet / count
            totRec[count] = finalRecall
            allPrec.append(totPrec[count])
            allRec.append(totRec[count])
            count += 1

        precCutoff, recCutoff = [], []

        for k in kVals:
            tempP = totPrec[k]
            tempR = totRec[k]

            precCutoff.append(tempP)
            recCutoff.append(tempR)

            f1 = 0
            if tempP > 0 and tempR > 0:
                f1 = (2 * tempP * tempR) / (tempP + tempR)

            precCutQuery[k] = tempP
            recCutQuery[k] = tempR
            f1CutQuery[k] = f1

            if k in P:
                P[k].append(tempP)
            else:
                P[k] = [tempP]

            if k in R:
                R[k].append(tempR)
            else:
                R[k] = [tempR]

            if k in F1:
                F1[k].append(f1)
            else:
                F1[k] = [f1]

        avgP = 0.0

        if relRet != 0:
            avgP = sumPrec / numRel

        avgPrec.append(avgP)
        rPrec.append(rp / len(relResDocs))

        numDCG = calcNDCG(relevanceScore)
        relevanceScoreDesc = sorted(relevanceScore, reverse = True)
        dcgDesc = calcNDCG(relevanceScoreDesc)

        # graph(precCutoff, recCutoff, qID)

        tempNDCG = 0
        if dcgDesc != 0:
            tempNDCG = numDCG / dcgDesc

        nDCG.append(tempNDCG)
        totRelRet += relRet
        totRet += ret

        if option:
            printer(qID, ret, numRel, relRet, avgP, rp / len(relResDocs), tempNDCG, precCutQuery, recCutQuery, f1CutQuery)

    AvgPrec = math.fsum(avgPrec) / len(avgPrec)
    RPre = math.fsum(rPrec) / len(rPrec)
    NDCG = math.fsum(nDCG) / len(nDCG)

    finalP, finalR, finalF1 = calcCutoff(P, R, F1)

    printer(totQuery, totRet, totRel, totRelRet, AvgPrec, RPre, NDCG, finalP, finalR, finalF1)

def main():
    option = False
    qrelFile = None
    resFile = None

    if len(sys.argv) < 3 or len(sys.argv) > 4:
        print('Incorrect format')
        sys.exit(0)

    if len(sys.argv) == 3:
        qrelFile = sys.argv[1]
        resFile = sys.argv[2]
    else:
        option = True
        qrelFile = sys.argv[2]
        resFile = sys.argv[3]

    # print(option, qrelFile, resFile)

    relevant = readQrel(os.getcwd() + '\\Result Files\\' + qrelFile)
    results = readRes(os.getcwd() + '\\Result Files\\' + resFile)
    calc(option, relevant, results)

main()


import fantasy_game_inventory #i wrote this code alrdy

def addToInv(inventory, loot): #returns updated inv. dict.
    #code
    for i in range(0, len(loot)):
        if (loot[i] in inventory):
            inventory[loot[i]] += 1 #scrutinize?
        else:
            inventory[loot[i]] = 1
    return inventory

#main program
inv = {'gold coin': 42, 'rope': 1}
print('This is what you have so far in your inventory: ')
fantasy_game_inventory.displayInv(inv)

dragonLoot = ['gold coin', 'dagger', 'gold coin', \
              'gold coin', 'ruby']

print('This is the loot dropped by the dragon: ')
for i in range(0, len(dragonLoot)):
    print(dragonLoot[i])

print('Here is your updated inventory: ')
newInv = addToInv(inv, dragonLoot)
fantasy_game_inventory.displayInv(newInv)


def check(num):
    '''Dictionry to count occurrence of a digit in the number.
       Key -> (Digit) | Value -> count'''
    digit_count = {0:0, 1:0, 2:0, 3:0, 4:0,
                   5:0, 6:0, 7:0, 8:0, 9:0}

    num_str = str(num)
    for ch in num_str:
        digit_count[int(ch)] += 1

    if max(digit_count.values()) > 1:
        return False
    return True

#* Main
n1 = int(input("num 1= "))
n2 = int(input("num 2= "))
count = 0
unique_nums = []   #! Mitra! ye list banana sirf ans shwo krne ke liye hai.
for i in range(n1, n2+1):
    if check(i):
        count += 1
        unique_nums.append(i)

print("Ans: ", count)
print("No Repeat numbers: ", unique_nums)


import requests
from root.settings import APPID_KEY
from django import forms
from .models import City

class CityForm(forms.Form):
    name = forms.CharField(
        max_length=50,
        widget=forms.TextInput(
            attrs={
                "class": "form-control", "placeholder": "Введите город"
            }
        )
    )

    def save(self):
        City.objects.create(**self.cleaned_data)

    def clean(self):
        has_error = False
        city = self.cleaned_data["name"]
        all_city = City.objects.all()
        for c in all_city:
            if c.name == city:
                self.add_error("name", "Город уже присутствует")
                has_error = True
        req = requests.get(
            f"https://api.openweathermap.org/data/2.5/weather?q={city},&lang=ru&appid={APPID_KEY}&units=metric"
            ).json()
        if req["cod"] != 200:
            self.add_error("name", "Неверное название города")
            has_error = True
        if not has_error:
            self.save()
        else:
            raise forms.ValidationError("Неверные данные")


""""
Integration tests for various pieces involved in external provider support.
"""

from unittest import TestCase, main

try:
    from mock import MagicMock
except ImportError:
    from unittest.mock import MagicMock

from stormpath.resources.account import Account
from stormpath.resources.application import Application
from stormpath.resources.directory import Directory
from stormpath.resources.verification_email import VerificationEmailList

class TestVerificationEmail(TestCase):

    def test_resend(self):
        ds = MagicMock()
        ds.create_resource.return_value = {}
        client = MagicMock(data_store=ds, BASE_URL='http://example.com/')

        acc = Account(
            client=client,
            properties={'href': 'test/app','email': 'some@testmail.stormpath.com'})
        vel = VerificationEmailList(client=client, href='test/emails')
        app = Application(
            client=client,
            properties={'href': 'test/app','verification_emails': vel})
        dir = Directory(client=client, href='test/directory')

        app.verification_emails.resend(acc, dir)

        ds.create_resource.assert_called_once_with(
            'http://example.com/test/emails',
            {'login': 'some@testmail.stormpath.com', 'account_store': 'test/directory'})

if __name__ == '__main__':
    main()


from collections import deque

n = int(input())

cards = deque()

for i in range(1, n + 1):
    cards.append(i)

cards.reverse()

while len(cards) != 1:
    cards.pop()
    cards.rotate(1)

print(cards[0])


# write your solution here
def read_fruits():
    dict = {}
    with open("fruits.csv") as file:
        for line in file:
            line = line.replace("\n", "")
            list = line.split(";")
            dict[list[0]] = float(list[1])
    return dict


import pandas as pd
from scipy import optimize
import numpy_financial as npf
from datetime import date

def bondPrice(faceValue,coupon,daysUntilMaturity,daysBetweenCoupon,ytm):
    pv=(faceValue+coupon)/((1+ytm)**(daysUntilMaturity/365))
    daysUntilMaturity-=daysBetweenCoupon
    while daysUntilMaturity>0:
        pv+=coupon/((1+ytm)**(daysUntilMaturity/365))
        daysUntilMaturity-=daysBetweenCoupon
    return(pv)

file= pd.read_excel("Debt_TB2.xlsx", sheet_name=1)
todayDate=file.iloc[1,4]
debtPortfolio = file.iloc[4:,2:]
debtPortfolio.columns = ['S.No.','ISIN','SecurityName','InstrumentType','Maturity','Price','Yield','ModifiedDuration','Rating','RatingChange','ValuationTriggered','TriggerDate','FaceValue','MacaulayDuration','Period']
ytms=[]
for index, row in debtPortfolio.iterrows():
    price=row['Price']
    yld=row['Yield']
    period=row['Period']
    par=row['FaceValue']
    timeToMaturity=(row['Maturity']-todayDate).days
    print(timeToMaturity)
    get_yield= lambda int_rate: bondPrice(par,yld*par*period*30/365,timeToMaturity,period*30,int_rate) - price
    ytm=optimize.newton(get_yield, yld)
    ytms.append(ytm)
debtPortfolio['ytm']=ytms
print(debtPortfolio)
print(ytms)
debtPortfolio.to_csv("YTM.csv")


# import modules
from utils import decorator
from telegram.error import TelegramError
from errors.log import log
from config import log_channel
from telegram.constants import ParseMode

@decorator.general_admin
#@decorator.cancellacomandi
async def init(update, context):
    """
    This command is executed sending the command:
        /autoban reason

    where 'reason' is a message to explain to the user the reason of the ban

    The command must be used in reply to the user's message. The bot sends a message
    in the chat to the user providing the 'reason'. After 60 seconds the user is banned.
    """
    # decode command
    reason = update.message.text.replace('/autoban ', '').strip()
    # get username
    name = "@" + update.message.reply_to_message.from_user.username \
        if update.message.reply_to_message.from_user.username is not None \
        else update.message.reply_to_message.from_user.name

    # set and send message to the user
    msg = f"{name}, sarai bannato dal gruppo fra 60 secondi per questo motivo:\n\n{reason}"
    await update.message.reply_text(#chat_id=update.message.chat_id,
                             text=msg,)
                             #reply_to_message_id=update.message.reply_to_message.message_id)
    await context.bot.send_message(chat_id=log_channel ,
                                   text="ðŸ”´ Ban process #ban\n\nChat: {}\nChat_id: {}"
                                        "\nUser_id: {}"
                                        "\nName: {}"
                                        "\nUsername: @{}"
                                        "\n\nPerformed by admin: @{}"
                                        "\n\nBan reason: {}".format(update.message.chat.title,
                                                                           update.message.chat_id,
                                                                           update.message.reply_to_message.from_user.id,
                                                                           update.message.reply_to_message.from_user.first_name,
                                                                           update.message.reply_to_message.from_user.username,
                                                                           update.message.from_user.username,
                                                                           reason),
                                   parse_mode=ParseMode.HTML)
    await context.bot.delete_message(update.message.chat_id, update.message.message_id)

    # set delayed action
    async def delayed_ban(context, update=update):
        try:
            await context.bot.ban_chat_member(chat_id=update.message.chat.id,
                                        user_id=update.message.reply_to_message.from_user.id)

        except TelegramError:
            log("an error occurred [AUTOBAN] function")
            await update.message.reply_text(text="Error during autoban operation")

    # schedule action
    seconds = 60
    context.job_queue.run_once(delayed_ban, seconds)


from DbHelper import DbHelper
from pydantic import BaseModel
from ResponseModel import *

class ProductModel(BaseModel):
    productCode: str | None = None
    productName: str | None = None
    productLine: str | None = None
    productScale: str | None = None
    productVendor: str | None = None
    productDescription: str| None = None
    quantityInStock: int | None = None
    buyPrice: float | None = None
    MSRP: float| None = None

class DaoProducts:
    def __init__(self):
        self.db = DbHelper()

    def get_all_products(self):
        try:
            products = []
            query = "SELECT * FROM products;"
            rows = self.db.exe_query(query)
            for row in rows:
                products.append(ProductModel(productCode = row[0],
                                               productName=  row[1],
                                               productLine = row[2],
                                               productScale = row[3],
                                               productVendor = row[4],
                                               productDescription =  row[5],
                                               quantityInStock = row[6],
                                               buyPrice = row[7],
                                               MSRP = row[8]
                                               ))
            return response (
                message = 'OK',
                result = products
            )
        except Exception as error:
            return response (
                message = 'KO',
                result = error
            )

    def add_product(self, product):
        try:
            self.db.exe_query(f"INSERT INTO products (productCode, productName, productLine, productScale, productVendor, productDescription, quantityInStock , buyPrice, MSRP) VALUES ('{product.productCode}', '{product.productName}', '{product.productLine}', '{product.productScale}', '{product.productVendor}', '{product.productDescription}', '{product.quantityInStock }', '{product.buyPrice}', '{product.MSRP}');commit")
        except Exception as e:
            print('errore durante la connessione')
            print(e)


import tkinter as tk
from tkinter import ttk
from re import match
from os import listdir
from PIL import Image
from tkinter import messagebox as box
from back import *

# Функция создания иверсивной картинки
def inverse_pict():
    file = filename.get()
    if len(file) == 0:
        box.showinfo('Error', "No file chosen")
        return
    try:
        image = Image.open(file)
    except FileNotFoundError:
        box.showinfo('Error', "No such file")
        return

    size = list(image.size)
    pixels = list(image.getdata())

    pixels = inverse(size, pixels)
    wen_elif = file[:-4][::-1] + ".bmp"
    image.close()
    new_image = Image.new(image.mode, image.size)
    new_image.putdata(pixels)
    new_image.save(file[:-4][::-1] + ".bmp")
    entry_file["values"] = list(filter(lambda filee: match(r'.*\.bmp', filee), listdir()))
    box.showinfo('New file', f"New file: {wen_elif} was successfully created")

# Функция создания файла с отрисованными линиями
def draw_line(wr_col, wr_lin):
    if wr_col is None:
        box.showinfo('Error', "No choosing color")
        return
    if len(wr_lin) == 0:
        box.showinfo('Error', "No write lines")
        return
    file = filename.get()
    if len(file) == 0:
        box.showinfo('Error', "No file chosen")
        return
    try:
        image = Image.open(file)
    except FileNotFoundError:
        box.showinfo('Error', "No such file")
        return
    size = list(image.size)
    pixels = list(image.getdata())
    pix_mat = []
    for i in range(size[1]):
        pix_mat.append(pixels[size[0] * i: size[0] * (i + 1)])

    line_funcs = {'/': lambda: write_right_line(size, pix_mat, wr_col),
                  '|': lambda: write_up_line(size, pix_mat, wr_col),
                  '\\': lambda: write_left_line(size, pix_mat, wr_col),
                  '-': lambda: write_hor_line(size, pix_mat, wr_col)}

    for i in wr_lin:
        pix_mat = list(line_funcs[i]())
    pixels = []
    for i in range(len(pix_mat)):
        for j in pix_mat[i]:
            pixels.append(j)

    new_file = file[:-4]
    if '_net' in new_file:
        new_file += 't'
    else:
        new_file += '_net'
    image.close()
    new_image = Image.new(image.mode, image.size)
    new_image.putdata(pixels)
    new_image.save(new_file + '.bmp')
    entry_file["values"] = list(filter(lambda filee: match(r'.*\.bmp', filee), listdir()))
    box.showinfo('File', f"New file: {new_file}.bmp was successfully created")
    update()

# Функция обновляет данные после создания нового файла
def update():
    global choose_lin, choose_col, color, lines
    color = None
    lines = ''

    choose_lin.destroy()
    choose_col.destroy()

    choose_col = tk.Label(window, text="-", font=('Calibri', 12, 'bold'), fg='#ffffff', bg='#303030')
    choose_col.grid(row=3, column=3, columnspan=2, padx=5, pady=5)

    choose_lin = tk.Label(window, text="0", font=('Calibri', 12, 'bold'), fg='#ffffff', bg='#303030')
    choose_lin.grid(row=5, column=3, columnspan=2, padx=5, pady=5)

# Функция выбора цвета
def chose_color(num):
    colors = [tuple([255, 0, 0]), tuple([0, 255, 0]), tuple([0, 0, 255]), tuple([255, 255, 255]), tuple([0, 0, 0])]
    str_color = ['Red', 'Green', 'Blue', 'White', 'Black']
    fg_color = ['#ff0000', '#00ff00', '#5061fa', '#ffffff', '#000000']
    global color, choose_col
    color = colors[num]
    choose_col.destroy()
    choose_col = tk.Label(window, text=str_color[num], font=('Calibri', 12, 'bold'), fg=fg_color[num], bg='#303030')
    choose_col.grid(row=3, column=3, columnspan=2, padx=5, pady=5)

# Функция выбора построения линий
def chose_lines(num):
    _lines = ['|', '\\', '-', '/']
    global lines, choose_lin
    if num == 4:
        choose_lin.destroy()
        choose_lin = tk.Label(window, text="0", font=('Calibri', 12, 'bold'), fg='#ffffff', bg='#303030')
        choose_lin.grid(row=5, column=3, columnspan=2, padx=5, pady=5)
        lines = ''
    else:
        if _lines[num] not in lines:
            lines += _lines[num]
            choose_lin.destroy()
            choose_lin = tk.Label(window, text=lines, font=('Calibri', 12, 'bold'), fg='#ffffff', bg='#303030')
            choose_lin.grid(row=5, column=3, columnspan=2, padx=5, pady=5)

def press_key(event):
    if event.char == '\r':
        draw_line(color, lines)
    if event.char == '\x1b':
        window.destroy()

window = tk.Tk()
window.resizable()
window.title("Image")
window["bg"] = '#303030'
window.resizable(None, None)

window.bind('<Key>', press_key)  # Бинд ввода с клавиатуры

label_file = tk.Label(window, text="Base picture: ", font=('Calibri', 12, 'bold'), fg='#ffffff',
                      bg='#303030')
label_file.grid(row=0, column=0, columnspan=3, padx=5, pady=5)

file_list = list(filter(lambda file: match(r'.*\.bmp', file), listdir()))
filename = tk.StringVar()

entry_file = ttk.Combobox(textvariable=filename, values=file_list)
entry_file.grid(row=0, column=3, columnspan=2, padx=5, pady=5)

inv_button = tk.Button(window, text="inverse image", font=('Calibri', 12, 'bold'), fg='#303030', bg='#ffffff', bd=2,
                       command=inverse_pict)
inv_button.grid(row=1, column=0, columnspan=5, stick='wens')

# Кнопки цветов
# -------------------------------------------------------------------------------------------------------
color = None

red_button = tk.Button(window, text="Red", font=('Calibri', 12, 'bold'), fg='#000000', bg="#ff0000", bd=5,
                       command=lambda: chose_color(0))
red_button.grid(row=2, column=0)

green_button = tk.Button(window, text="Green", font=('Calibri', 12, 'bold'), fg='#000000', bg="#00ff00", bd=5,
                         command=lambda: chose_color(1))
green_button.grid(row=2, column=1)

blue_button = tk.Button(window, text="Blue", font=('Calibri', 12, 'bold'), fg='#000000', bg="#5061fa", bd=5,
                        command=lambda: chose_color(2))
blue_button.grid(row=2, column=2)

white_button = tk.Button(window, text="White", font=('Calibri', 12, 'bold'), fg='#000000', bg="#ffffff", bd=5,
                         command=lambda: chose_color(3))
white_button.grid(row=2, column=3, stick='wens')

red_button = tk.Button(window, text="Black", font=('Calibri', 12, 'bold'), fg='#ffffff', bg="#000000", bd=5,
                       command=lambda: chose_color(4))
red_button.grid(row=2, column=4, stick='wens')

# Выбранный цвет
# -------------------------------------------------------------------------------------------------------------
col = tk.Label(window, text="Color: ", font=('Calibri', 12, 'bold'), fg='#ffffff', bg='#303030')
col.grid(row=3, column=0, columnspan=3, padx=5, pady=5)

choose_col = tk.Label(window, text="-", font=('Calibri', 12, 'bold'), fg='#ffffff', bg='#303030')
choose_col.grid(row=3, column=3, columnspan=2, padx=5, pady=5)

# -------------------------------------------------------------------------------------------------------------

# Кнопки линий
# -------------------------------------------------------------------------------------------------------
lines = ''

up_button = tk.Button(window, text="||", font=('Calibri', 12, 'bold'), fg='#ffffff', bg="#303030", bd=2,
                      command=lambda: chose_lines(0))
up_button.grid(row=4, column=0, sticky='wsen')

left_button = tk.Button(window, text="\\\\", font=('Calibri', 12, 'bold'), fg='#ffffff', bg="#303030", bd=2,
                        command=lambda: chose_lines(1))
left_button.grid(row=4, column=1, sticky='wsen')

hor_button = tk.Button(window, text="--", font=('Calibri', 12, 'bold'), fg='#ffffff', bg="#303030", bd=2,
                       command=lambda: chose_lines(2))
hor_button.grid(row=4, column=2, sticky='wsen')

right_button = tk.Button(window, text="//", font=('Calibri', 12, 'bold'), fg='#ffffff', bg="#303030", bd=2,
                         command=lambda: chose_lines(3))
right_button.grid(row=4, column=3, sticky='wsen')

clr_button = tk.Button(window, text="Clear", font=('Calibri', 12, 'bold'), fg='#ffffff', bg="#303030", bd=2,
                       command=lambda: chose_lines(4))
clr_button.grid(row=4, column=4, sticky='wsen')

# Выбранные линии
# -------------------------------------------------------------------------------------------------------------
lin = tk.Label(window, text="Lines: ", font=('Calibri', 12, 'bold'), fg='#ffffff', bg='#303030')
lin.grid(row=5, column=0, columnspan=3, padx=5, pady=5)

choose_lin = tk.Label(window, text="0", font=('Calibri', 12, 'bold'), fg='#ffffff', bg='#303030')
choose_lin.grid(row=5, column=3, columnspan=2, padx=5, pady=5)

# -------------------------------------------------------------------------------------------------------------

draw_button = tk.Button(window, text="New picture", font=('Calibri', 12, 'bold'), fg='#ffffff', bg="#303030",
                        command=lambda: draw_line(color, lines))
draw_button.grid(row=6, column=0, columnspan=5, stick='wens')

window.mainloop()


class Solution:
    def minSwapsCouples(self, row: List[int]) -> int:
        count = 0
        dic = {min(i,j):max(i,j) for i,j in zip(row[0::2],row[1::2])}
        for i in range(0, len(row), 2):
            temp = dic[i]
            if abs(i-temp) > 1:
                count += 1
                d = dic.pop(i+1)
                dic[min(temp, d)], dic[i] = max(temp,d), i+1
        return count


import pulp
from pulp import *

# declare your variables
x1 = LpVariable("x1",lowBound=0,cat='Integer')
x2 = LpVariable("x2",lowBound=0,cat='Integer')
x3 = LpVariable("x3",lowBound=0,cat='Integer')

# defines the problem
prob = LpProblem("problem", LpMaximize)

# defines the constraints
prob += x1 + x2 <= 10   #no more than 10 classical and jazz
prob += x3 <= 8         #no more than 8 rock
prob += x3 - 2*x1 == 0

# defines the objective function to maximize
# attendance function
prob += 700*x1 + 800*x2 + 300*x3

# solve the problem
status = prob.solve(GLPK(msg=0))
LpStatus[status]

value(x1)
value(x2)
value(x3)

print(prob)
print(x1.varValue)
print(x2.varValue)
print(x3.varValue)

print('\n\nattendance is %f'%(700*x1.varValue + 800*x2.varValue + 300*x3.varValue))

400 - MathModellers/week 5/midterms/q8.py


import os
import json
from flask import Flask, render_template, jsonify, send_from_directory, request
from flask_swagger import swagger
from localstack.utils.aws.aws_stack import Environment
from localstack.utils import common
from localstack.dashboard import infra

root_path = os.path.dirname(os.path.realpath(__file__))
web_dir = root_path + '/web/'

app = Flask('app', template_folder=web_dir)
app.root_path = root_path

@app.route('/swagger.json')
def spec():
    swag = swagger(app)
    swag['info']['version'] = "0.1"
    swag['info']['title'] = "AWS Resources Dashboard"
    return jsonify(swag)

@app.route('/graph', methods=['POST'])
def get_graph():
    """ Get deployment graph
        ---
        operationId: 'getGraph'
        parameters:
            - name: request
              in: body
    """
    data = json.loads(request.data)
    env = Environment.from_string(data.get('awsEnvironment'))
    graph = infra.get_graph(name_filter=data['nameFilter'], env=env)
    return jsonify(graph)

@app.route('/kinesis/<streamName>/<shardId>/events/latest', methods=['POST'])
def get_kinesis_events(streamName, shardId):
    """ Get latest events from Kinesis.
        ---
        operationId: 'getKinesisEvents'
        parameters:
            - name: streamName
              in: path
            - name: shardId
              in: path
            - name: request
              in: body
    """
    data = json.loads(request.data)
    env = Environment.from_string(data.get('awsEnvironment'))
    result = infra.get_kinesis_events(stream_name=streamName, shard_id=shardId, env=env)
    return jsonify(result)

@app.route('/lambda/<functionName>/code', methods=['POST'])
def get_lambda_code(functionName):
    """ Get source code for Lambda function.
        ---
        operationId: 'getLambdaCode'
        parameters:
            - name: functionName
              in: path
            - name: request
              in: body
    """
    data = json.loads(request.data)
    env = Environment.from_string(data.get('awsEnvironment'))
    result = infra.get_lambda_code(func_name=functionName, env=env)
    return jsonify(result)

@app.route('/')
def hello():
    return render_template('index.html')

@app.route('/<path:path>')
def send_static(path):
    return send_from_directory(web_dir + '/', path)

def ensure_webapp_installed():
    web_dir = os.path.realpath(os.path.join(os.path.dirname(__file__), 'web'))
    node_modules_dir = os.path.join(web_dir, 'node_modules', 'jquery')
    if not os.path.exists(node_modules_dir):
        print('Initializing installation of Web application (this could take long time, please be patient)')
        common.run('cd "%s"; npm install' % web_dir)

def serve(port):
    ensure_webapp_installed()
    app.run(port=int(port), debug=True, threaded=True, host='0.0.0.0')


# Desafio 050: Desenvolva um programa que leia seis números inteiros
# e mostre a soma apenas daqueles que forem pares.
# Se o valor digitado for ímpar, desconsidere-o.
s  = 0
co = 0
for n in range(1,7):
    c = int(input('Digite um número inteiro:'))
    if c % 2 == 0:
        co += 1
        s += c
print('O somatório dos {} números pares digitados é igual a {}'.format(co,s))


from flask import Flask, render_template, request, json, redirect, session
from flask import Markup
import requests

app = Flask(__name__)
app.config["DEBUG"] = False

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

@app.route("/chart")
def chart():
    r = requests.get('https://api.airtable.com/v0/appAIHCBijmOXqMWG/membership_points?api_key=keyHwnj1ElCshCfmN&sortField=_createdTime&sortDirection=desc')
    dict1 = r.json()
    dict2 = {}
    dataset = []
    name_list = []
    point_list = []
    for i in dict1['records']:
         dict2 = i['fields']
         dataset.append(dict2)
    for item in dataset:
        name_list.append(item.get('name'))
        point_list.append(item.get('point'))
    return render_template('chart.html', entries = zip(name_list, point_list))

if __name__ == '__main__':
   app.run(debug = True)


from db.mongo import get_mongo_db
import os

async def find_user(chat_id: int):
    # Setup MongoDB to store chat history and user data
    database = get_mongo_db()
    # Get collection
    collection_name = os.environ.get('MONGO_DB_COLLECTION_NAME')
    collection = database[collection_name]
    # get document
    return collection.find_one({"chat_id": chat_id})


import tokens as tkn
import lexer as lxr

class LexerTests:

    def TestNextToken(self):
        print("Running TestNextToken")
        input = """
        let five = 5
        let ten = 10

        let add = fn(x, y){
            x + y
        }

        let result = add(five, ten)

        !-/*5
        5 < 10 > 5

        if (5 < 10) {
            return true
        }else{
            return false
        }

        10 == 10
        10 != 9
        """
        testTokens = [
            (tkn.LET, "let"),
            (tkn.IDENT, "five"),
            (tkn.ASSIGN, "="),
            (tkn.INT, "5"),
            (tkn.LET, "let"),
            (tkn.IDENT, "ten"),
            (tkn.ASSIGN, "="),
            (tkn.INT, "10"),
            (tkn.LET, "let"),
            (tkn.IDENT, "add"),
            (tkn.ASSIGN, "="),
            (tkn.FUNCTION, "fn"),
            (tkn.LPAREN, "("),
            (tkn.IDENT, "x"),
            (tkn.COMMA, ","),
            (tkn.IDENT, "y"),
            (tkn.RPAREN, ")"),
            (tkn.LBRACE, "{"),
            (tkn.IDENT, "x"),
            (tkn.PLUS, "+"),
            (tkn.IDENT, "y"),
            (tkn.RBRACE, "}"),
            (tkn.LET, "let"),
            (tkn.IDENT, "result"),
            (tkn.ASSIGN, "="),
            (tkn.IDENT, "add"),
            (tkn.LPAREN, "("),
            (tkn.IDENT, "five"),
            (tkn.COMMA, ","),
            (tkn.IDENT, "ten"),
            (tkn.RPAREN, ")"),
            (tkn.BANG, "!"),
            (tkn.MINUS, "-"),
            (tkn.SLASH, "/"),
            (tkn.ASTERISK, "*"),
            (tkn.INT, "5"),
            (tkn.INT, "5"),
            (tkn.LT, "<"),
            (tkn.INT, "10"),
            (tkn.GT, ">"),
            (tkn.INT, "5"),
            (tkn.IF, "if"),
            (tkn.LPAREN, "("),
            (tkn.INT, "5"),
            (tkn.LT, "<"),
            (tkn.INT, "10"),
            (tkn.RPAREN, ")"),
            (tkn.LBRACE, "{"),
            (tkn.RETURN, "return"),
            (tkn.TRUE, "true"),
            (tkn.RBRACE, "}"),
            (tkn.ELSE, "else"),
            (tkn.LBRACE, "{"),
            (tkn.RETURN, "return"),
            (tkn.FALSE, "false"),
            (tkn.RBRACE, "}"),
            (tkn.INT, "10"),
            (tkn.EQ, "=="),
            (tkn.INT, "10"),
            (tkn.INT, "10"),
            (tkn.NOT_EQ, "!="),
            (tkn.INT, "9"),
        ]

        resultTokens = []

        l = lxr.Lexer(input)

        ix = 0

        for index, tuple in enumerate(testTokens):
            key = tuple[0]
            value = tuple[1]
            tok = l.NextToken()
            resultTokens.append((tok.TokenType, tok.Literal))
            # print("key: %s, value: %s" %(key, value))
            # print("tok.TokenType: %s, tok.Literal: %s" %(tok.TokenType, tok.Literal))
            # value_hex = ":".join("{:02x}".format(ord(c)) for c in value)
            # literal_hex = ":".join("{:02x}".format(ord(c)) for c in tok.Literal)
            # print(f'value_hex: {value_hex}, literal_hex: {literal_hex}')

            if tok.TokenType != key:
                raise Exception(f'Test[{ix}] failed: TokenType wrong, expected: {key}, got: {tok.TokenType}')
            if tok.Literal != value:
                raise Exception(f'Test[{ix}] failed: Literal wrong, expected: {value}, got: {tok.Literal}')
            ix += 1

        print(resultTokens)


from django import forms

class UploadFileForm(forms.Form):
    title = forms.CharField(max_length=50)
    file  = forms.FileField()

SOURCE_CHOICES = (
    ("Facebook",u'Facebook'),
    ("Email",u'Email'),
    ("From a friend",u'From a friend'),
    ("Notification on my phone",u'Notification on my phone'),
    ("Saw in the app",u'Saw in the app'),
    ("Found out at the venue",u'Found out at the venue'),
    ("Other",u'Other'),
    ("...",u"...")
)

FREQUENCY_CHOICES = (
    ("Never",u'Never'),
    ("A couple times a year",u'A couple times a year'),
    ("Once a month",u'Once a month'),
    ("A couple times a month",u'A couple times a month'),
    ("Once a week",u'Once a week'),
    ("...",u"...")
)

class EventFeedback(forms.Form):
    general = forms.CharField(required=False,
                              widget=forms.Textarea(attrs={'class':'form-control','placeholder':'feedback','rows':3}))
    source = forms.CharField(required=False,
                              widget=forms.Select(choices=SOURCE_CHOICES, attrs={'class':'form-control'}))
    frequency = forms.CharField(required=False,
                                 widget=forms.Select(choices=FREQUENCY_CHOICES, attrs={'class':'form-control'}))
    improvements = forms.CharField(required=False,
                                    widget=forms.Textarea(attrs={'class':'form-control','placeholder':'feedback','rows':3}))


from playwright.async_api import Page

class VeloCubeLocators:
    status = ".product_stock-status"
    CHOOSE_SIZE = ".variant_name"

class VeloCubePage:
    URL = "https://velocube.ru/products/merida-silex-400-2021"

    def __init__(self, page: Page):
        self.page = page

    async def open_page(self, url):
        await self.page.goto(url)

    async def get_all_elements(self):
        elements = await self.page.query_selector_all(VeloCubeLocators.CHOOSE_SIZE)
        return elements

    async def get_status_text(self) -> str:
        result = await self.page.inner_text(selector=VeloCubeLocators.status, timeout=50000)
        return result

    async def check_status(self) -> bool:
        status = await self.get_status_text()
        if status != "Ожидается" or "Нет в наличии":
            return False
        return True

    async def check_status_for_all_element(self):
        status = {}
        elements = await self.get_all_elements()
        for element in elements:
            size = await element.text_content()
            if "XS" and "LIME" in size:
                await element.click()
                result = await self.check_status()
                status.update({"lime": result})
            elif "XS" and "BLUE" in size:
                await element.click()
                result = await self.check_status()
                status.update({"blue": result})
        return [status]


#coding:utf-8

from services import linux

class BaseTemplate(object):
    def __init__(self):
        self.name = 'your template name'
        self.hosts = []
        self.services = []

class LinuxGenericTemplate(BaseTemplate):
    def __init__(self):
        super(LinuxGenericTemplate,self).__init__()
        self.name = 'LinuxCommonServices'
        self.services = [
            linux.CPU(),
            linux.Memory(),
            #linux.Network()
        ]

class Linux2(BaseTemplate):
    def __init__(self):
        super(Linux2,self).__init__()
        self.name = 'Linux2'
        self.services = [
            linux.CPU(),
            #linux.Memory(),
            linux.Network()
        ]


from random import randint

class LevelGenerator:
    """
    this class produces a new map . i admit. it's logic is quite twisted but it's neccessary or the levels would be as simple as the logic you used.
    and we dont want the players to suffer death from boredom. doctors dont recommend it.
    """
    def __init__(self):
        self.tilemap ={}
        self.cubeTiles=[0,0,None,None]
        self.movementHistory=["0_0_None_None"]

    def generateLevel(self,effektiveMoves = 20):
        self.movementHistory=["0_0_None_None"]
        self.cubeTiles=[0,0,None,None]
        count = 0
        failcount = 0
        directions = ["up","down","left" , "right" ]
        while ( len( self.movementHistory ) < effektiveMoves ):
            print("step1:",self.movementHistory)
            self.fakeMove( directions[randint(0,3)] )
            print("step2:",self.movementHistory)
            indexnumber = self.movementHistory.index(self.movementHistory[-1])
            print("index:", indexnumber)
            while len(self.movementHistory) > indexnumber+1:
                print(self.movementHistory.pop())

        while (not "None" in self.movementHistory[-1]):
            self.movementHistory.pop()

        print(len(self.movementHistory),self.movementHistory[-1])
        return self.createLevelFromHistory(self.movementHistory)

    def createLevelFromHistory(self,history):
        tiles = []
        for number in range(0,len(history) ):
            tilestring =  history[number].split("_")
            strpos1 = "Pos="+tilestring[0]+"_"+tilestring[1]
            if strpos1 not in tiles:
                tiles.append(strpos1)
            if tilestring[2] != "None":
                strpos2 = "Pos="+tilestring[2]+"_"+tilestring[3]
                if strpos2 not in tiles:
                    tiles.append(strpos2)
        myMapString = "<Type=start,Pos=0_0>"
        for number in range(1,len(tiles)-1 ):
            myMapString +=  "<Type=tile,"+tiles[number]+">"
        myMapString += "<Type=goal,"+tiles[-1]+">"
        return myMapString

    def getCubeTiles(self):
        tiles = self.movementHistory[-1].split("_")
        if tiles[2] == "None":
            self.cubeTiles = [int(tiles[0]),int(tiles[1]),None,None]
        else:
            self.cubeTiles = [int(tiles[0]),int(tiles[1]),int(tiles[2]),int(tiles[3])]
        return self.cubeTiles

    def setCubeTiles(self,x1,y1,x2=None,y2=None):
        newPositionString = str(x1)+"_"+str(y1)+"_"+str(x2)+"_"+str(y2)  # looks like 12_5_None_None
        self.cubeTiles= [x1,y1,x2,y2]
        self.movementHistory.append(newPositionString)
        print("new move was successful", self.cubeTiles)

    def fakeMoveTest(self, x1,y1,x2=None,y2=None ):
        for i in ["up","down","left","right"]:
            if self.fakeMoveTestCases(i,x1,y1,x2,y2) == 1:
                return 1
        return 0

    def fakeMove(self,direction):
        """
        fakes the rotation of the cube.
        """
        x1,y1,x2,y2 = self.getCubeTiles()
        print("current position", x1,y1,x2,y2)
        if self.cubeTiles[2] == None :
            #case1 : cube is standing upright

            if direction == "right":
                self.setCubeTiles( x1, y1+1 ,x1 , y1+2 )
            if direction == "left":
                self.setCubeTiles( x1, y1-2 ,x1 , y1-1 )
            if direction == "up":
                self.setCubeTiles( x1-2, y1 ,x1-1 , y1 )
            if direction == "down":
                self.setCubeTiles( x1+1, y1 ,x1+2 , y1 )

        elif x1 == x2:  #if aligned to y-axis (heck i know but precision issues... you know?)
            if direction == "right":
                self.setCubeTiles( x1, y1+2  )
            if direction == "left":
                self.setCubeTiles( x1, y1-1)
            if direction == "up":
                self.setCubeTiles( x1-1, y1, x2-1, y2 )
            if direction == "down":
                self.setCubeTiles( x1+1, y1, x2+1, y2 )

        elif y1 == y2 : #if it is alligned to x-axis.. (math sux i know but we need tollerance)
            if direction == "right":
                self.setCubeTiles( x1, y1+1, x2, y2+1 )
            if direction == "left":
                self.setCubeTiles( x1, y1-1, x2, y2-1 )
            if direction == "up":
                self.setCubeTiles( x1-1, y1  )
            if direction == "down":
                self.setCubeTiles( x1+2, y1  )

        #this sorta.. doesnt belong here.. but i dunno where to put it yet.
        #x1,y1,x2,y2 = self.getCubeTiles()
        #checkresult = checkMove(self.level.levelNode,self.getCubeTiles(),self.sounds)


# declaration
rooms = {
     'Hall of education': {'South': 'Stairway to English 101', 'North': 'Main school entrance', 'East': 'Gym', 'West': 'Library', 'Item': 'skateboard'},
     'Stairway to English 101': {'North': 'Hall of education', 'East': 'English 101', 'Item': 'Bell'},
     'English 101': {'West': 'Stairway to English 101', 'Item': 'Books'},
     'Gym': {'East': 'Hall of education', 'Item': 'Alien'}, # The Games villian is located here
     'Main school entrance': {'East': 'Chemistry 101', 'South': 'Hall of education', 'Item': 'wooden sword'},
     'Chemisty 101': {'West': 'Main school entrance', 'Item': 'laser gun'},
     'Library': {'West': 'Hall of education', 'North': 'Math 101', 'Item': 'cell phone'},
     'Math 101': {'South': 'Library', 'Item': 'pencils'}

}
state = 'Hall of education'
# function
def get_new_state(state, direction):
    new_state = state  # declaraing
    for i in rooms:  # loop
        if i == state:  # if
            if direction in rooms[i]:  # if
                new_state=rooms[i][direction] #assigning new_state

    return new_state  # return
def get_item(state):
    return rooms[state]['Item'] #returning Item value
#function
def show_instructions():
    #print a main menu and the commands
    print("Alien invasion text game")
    print("Collect 6 items and meet up at the 'gym' to fight the alien and win the game")
    print("Move commands: go South, go North, go East, go West")
    print("Add to Inventory: get 'item name'")
show_instructions() #calling function
inventory=[]
while (1):  # gameplay loop
    print('You are in ', state)  # printing state
    print('Inventory:',inventory) #printing inventory
    item=get_item(state) #calling get_item function
    print('You see a',item) #print
    if item=='Alien': #if
        print('Your friends have died...GAME OVER!')
        exit(0)
    direction = input('Enter your move: ')  # asking user
    if (direction == 'go East' or direction == 'go West' or direction == 'go North' or direction == 'go South'):  # if
        direction=direction[3:]
        new_state = get_new_state(state, direction)  # calling function
        if new_state == state:  # if
            print('The room has wall in that direction enter other direction!')  # print
        else:
            state = new_state  # changing state value to new_state
    elif direction==str('get '+item): #if
        if item in inventory: #if item already present in inventory
            print('Item already taken go to another room!!')
        else:
            inventory.append(item) #appending
    else:
        print('Invalid direction!!')  # print
    if len(inventory)==6:
        print('Congratulations! You have collected all items and defeated the alien, your friends are saved thanks to your help!') #print
        exit(0)


from ..helper import newer
from ._base import MapperTask

class Copy(MapperTask):
    """Copy files to a destination directory, Exclude standard
hidden files.
constructor arguments:
Copy(*files, dest=<destdir>, exclude=<defaults>)"""

    # pylint: disable=unused-argument
    def dojob(self, sname, dname, context):
        self.logger.debug('sname = %s; dname = %s', sname, dname)
        srcfile = self.join(sname)
        dstfile = self.join(dname)
        if srcfile.isdir:
            # remove whatever is there
            if dstfile.exists and not dstfile.isdir:
                dstfile.remove()
            # create the directory
            if not dstfile.exists:
                dstfile.mkdir()
        elif srcfile.isfile and newer(srcfile, dstfile, logger=self.logger):
            self.logger.debug('uptodate: %s', dstfile)
        else:
            if not dstfile.dirname.isdir:
                dstfile.dirname.mkdir()
            self.logger.info('copy2(%s,%s)', sname, dname)
            srcfile.copy(dstfile)

Copy.register()