from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from .models import Faculty, Office, Applications, Projects, Progress_Reports
from django.views import generic
from django.utils.decorators import method_decorator
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from django.http import HttpResponseRedirect, HttpResponse, FileResponse
from .forms import ExtendApplication, CreateApplicationForm
from .filters import FacultyFilter, ApplicationsFilter
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from reportlab.lib import colors
from reportlab.pdfgen import canvas
from reportlab.lib.units import inch
from reportlab.platypus import Table, TableStyle, SimpleDocTemplate
from datetime import datetime
import io
# Create your views here.

@login_required
def index(request):
	"""view function for the homepage"""

	#filters applications based on user
	rlc_applications = Applications.objects.filter(applicant=request.user).order_by('-id')

	context = {
		'rlc_applications' : rlc_applications,
	}

	return render(request, 'index.html', context=context)

#list view for applications for regular users
@login_required
def ApplicationsListView(request):

	rlc_applications = Applications.objects.filter(applicant=request.user).order_by('-id')
	app_filter = ApplicationsFilter(request.GET, queryset=rlc_applications)

	#this it to check if user has unfinished rlc projects
	excludes = ['EXTENDED', 'COMPLETED']
	counter = rlc_applications.exclude(status__in=excludes).count()

	paginator = Paginator(app_filter.qs, 5) #Show 5 applications per page.
	page = request.GET.get('page')

	try:
		response = paginator.page(page)
	except PageNotAnInteger:
		response = paginator.page(1)
	except EmptyPage:
		response = paginator.page(paginator.num_pages)

	context = {
		'filter' : app_filter,
		'page' : response,
		'count' : counter
	}

	return render(request, 'rlcapp/rlc_list.html', context=context)

#detail view for applications for regular users
@login_required
def ApplicationsDetailView(request, pk):

	rlc_application = Applications.objects.get(id=pk)
	semester = Applications.get_current_semester()
	schoolyear = Applications.get_current_schoolyear()
	projects = Projects.objects.filter(application=rlc_application)

	if semester != rlc_application.semester_applicable:
		semester_different = True
	else:
		semester_different = False

	if schoolyear != rlc_application.schoolyear:
		schoolyear_different = True
	else:
		schoolyear_different = False

	can_extend = semester_different or schoolyear_different

	context = {
		'application' : rlc_application,
		'projects' : projects,
		'semester'  : semester,
		'schoolyear' : schoolyear,
		'extend'  : can_extend,
	}

	#these methods are for the submission of RLC Applications
	if request.method == "POST":
		if rlc_application.status == 'DRAFT' or rlc_application.status == 'FOR REVISION':
			if rlc_application.prev_status == 'PENDING COLLEGE APPROVAL':
				rlc_application.prev_status = rlc_application.status
				rlc_application.status = 'PENDING COLLEGE APPROVAL'
			else:
				rlc_application.prev_status = rlc_application.status
				rlc_application.status = 'PENDING DEPARTMENT APPROVAL'

		elif rlc_application.status =='PENDING DEPARTMENT APPROVAL':
			if rlc_application.prev_status == 'DRAFT':
				rlc_application.prev_status = rlc_application.status
				rlc_application.status = 'DRAFT'
			elif rlc_application.prev_status == 'FOR REVISION':
				rlc_application.prev_status = rlc_application.status
				rlc_application.status = 'FOR REVISION'

		elif rlc_application.status == 'PENDING COLLEGE APPROVAL':
			rlc_application.prev_status = rlc_application.status
			rlc_application.status = 'FOR REVISION'
		rlc_application.save()
		return render(request, 'rlcapp/applications_detail.html', context=context)

	return render(request, 'rlcapp/applications_detail.html', context=context)

#view for updating applications for regular users
@method_decorator(login_required, name='dispatch')
class ApplicationUpdateView(UpdateView):
	model = Applications
	fields = [
		'applicant',
		'units',
		'semester_applicable',
		'schoolyear',
		'status',
	]

#view for deleting applications
@method_decorator(login_required, name='dispatch')
class ApplicationDelete(DeleteView):
	model = Applications
	success_url = reverse_lazy('applications')

#view for Faculty Member page for regular users
@login_required
def FacultyDetailView(request):

	faculty = Faculty.objects.get(faculty_id=request.user.faculty_id)

	context = {
		'faculty' : faculty
	}

	return render(request, 'rlcapp/faculty_detail.html', context=context)

#view for updating faculty profile for regular users
@method_decorator(login_required, name='dispatch')
class FacultyUpdateSelf(UpdateView):
	model = Faculty
	fields = [
		'faculty_id',
		'first_name',
		'middle_name',
		'last_name',
		'password',
		'email',
		'department',
		'college',
		'designation',
		'rank',
		]
	success_url = reverse_lazy('faculty-detail')

#view for Faculty Member List for administrators
@login_required
def AdminFacultyView(request):

	faculty = Faculty.objects.all()
	faculty_filter = FacultyFilter(request.GET, queryset=faculty)

	paginator = Paginator(faculty_filter.qs, 5) #Show 5 faculty members per page.
	page = request.GET.get('page')

	try:
		response = paginator.page(page)
	except PageNotAnInteger:
		response = paginator.page(1)
	except EmptyPage:
		response = paginator.page(paginator.num_pages)

	context = {
		'filter' : faculty_filter,
		'page' : response
	}

	return render(request, 'rlcapp/admin_faculty.html', context=context)

#view for Faculty Member page for administrators
@login_required
def AdminFacultyDetailView(request, pk):

	faculty = Faculty.objects.get(id=pk)

	context = {
		'faculty' : faculty
	}

	return render(request, 'rlcapp/faculty_detail.html', context=context)

#view for creating faculty members for administrators
@method_decorator(login_required, name='dispatch')
class FacultyCreate(CreateView):
	model = Faculty
	fields = [
		'faculty_id',
		'first_name',
		'middle_name',
		'last_name',
		'password',
		'email',
		'department',
		'college',
		'designation',
		'rank',
		'access_level',
		'is_staff',
		'is_superuser',
		]

#view for updating faculty members for administrators
@method_decorator(login_required, name='dispatch')
class FacultyUpdate(UpdateView):
	template_name = 'rlcapp/admin_update_faculty_form.html'
	model = Faculty
	fields = [
		'faculty_id',
		'first_name',
		'middle_name',
		'last_name',
		'password',
		'email',
		'department',
		'college',
		'designation',
		'rank',
		'status',
		'remarks',
		'access_level',
		'is_staff',
		'is_superuser',
		]

#view for deleting faculty members for administrators
@method_decorator(login_required, name='dispatch')
class FacultyDelete(DeleteView):
	model = Faculty
	success_url = reverse_lazy('admin-faculty')

#view for creating projects
@method_decorator(login_required, name='dispatch')
class ProjectCreate(CreateView):
	model = Projects
	fields = [
		'application',
		'title',
		'original_name',
		'date_started',
		'date_completed',
		'percent_completed',
		'authors',
		'project_file',
	]

#view for updating projects
@method_decorator(login_required, name='dispatch')
class ProjectUpdateView(UpdateView):
	model = Projects
	fields = [
		'application',
		'title',
		'original_name',
		'date_started',
		'date_completed',
		'percent_completed',
		'authors',
		'project_file',
	]

#view to get a list of applications for administrators
@login_required
def AdminApplicationsListView(request):

	rlc_applications = Applications.objects.all().order_by('-id')
	app_filter = ApplicationsFilter(request.GET, queryset=rlc_applications)

	paginator = Paginator(app_filter.qs, 5) #Show 5 applications per page.
	page = request.GET.get('page')

	try:
		response = paginator.page(page)
	except PageNotAnInteger:
		response = paginator.page(1)
	except EmptyPage:
		response = paginator.page(paginator.num_pages)

	context = {
		'filter' : app_filter,
		'page' : response
	}

	#this block of code is for generating the statistics report
	if request.method == "POST":

		response = HttpResponse(content_type='application/pdf')
		response['Content-Disposition'] = 'attachment; filename=reports.pdf'

		buff = io.BytesIO()
		c = SimpleDocTemplate(buff, rightMargin=72, leftMargin=72, topMargin=72, bottomMargin=18)

		elements = []

		data = [["Applicant","Units","Semester","Schoolyear","Status","Department"]]

		for apps in app_filter.qs:
			lines = []
			lines.append(str(apps.applicant))
			lines.append(str(apps.units))
			lines.append(str(apps.semester_applicable))
			lines.append(str(apps.schoolyear))
			lines.append(str(apps.status))
			lines.append(str(apps.associated_department))
			data.append(lines)

		t = Table(data)
		t.setStyle(TableStyle([
			('BACKGROUND',(0,0),(5,0),colors.black),
			('TEXTCOLOR',(0,0),(5,0),colors.white),
			('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
			('BOX', (0,0), (-1,-1), 0.25, colors.black),
		]))

		elements.append(t)
		c.build(elements)
		response.write(buff.getvalue())
		buff.close

		return response

	return render(request, 'rlcapp/admin_rlc_list.html', context=context)

#view to create initial application
@method_decorator(login_required, name='dispatch')
class ApplicationsCreate(CreateView):

	model = Applications
	fields = [
		'applicant',
		'units',
		'semester_applicable',
		'schoolyear',
		'associated_department',
		'associated_college',
	]

	def get_initial(self):
		return {
			'applicant' : self.request.user,
			'associated_department' : self.request.user.department,
			'associated_college' : self.request.user.college,
		}

#view for viewing project details
@login_required
def ProjectDetailView(request, pk):

	projects = Projects.objects.get(id=pk)
	progress_reports = Progress_Reports.objects.filter(associated_project=pk).order_by('-id')

	context = {
		'projects' : projects,
		'progress_reports' : progress_reports,
	}

	return render(request, 'rlcapp/project_detail.html', context=context)

#view for getting a list of applications that are pending for approving bodies
@login_required
def PendingListView(request):

	if request.user.department == None:
		rlc_applications = Applications.objects.filter(status='PENDING COLLEGE APPROVAL')
	else:
		rlc_applications = Applications.objects.filter(status='PENDING DEPARTMENT APPROVAL').filter(associated_department=request.user.department)

	app_filter = ApplicationsFilter(request.GET, queryset=rlc_applications)

	paginator = Paginator(app_filter.qs, 5) #Show 5 applications per page.
	page = request.GET.get('page')

	try:
		response = paginator.page(page)
	except PageNotAnInteger:
		response = paginator.page(1)
	except EmptyPage:
		response = paginator.page(paginator.num_pages)

	context = {
		'filter' : app_filter,
		'page' : response
	}

	return render(request, 'rlcapp/pending_rlc_list.html', context=context)

#view for getting a list of approved applications for approving bodies
@login_required
def ApprovedListView(request):

	if request.user.department == None:
		rlc_applications = Applications.objects.filter(status='APPROVED' or 'COMPLETED')
	else:
		rlc_applications = Applications.objects.filter(status='APPROVED' or 'COMPLETED').filter(associated_department=request.user.department)

	app_filter = ApplicationsFilter(request.GET, queryset=rlc_applications)
	paginator = Paginator(app_filter.qs, 5) #Show 5 applications per page.
	page = request.GET.get('page')

	try:
		response = paginator.page(page)
	except PageNotAnInteger:
		response = paginator.page(1)
	except EmptyPage:
		response = paginator.page(paginator.num_pages)

	context = {
		'filter' : app_filter,
		'page' : response
	}

	return render(request, 'rlcapp/approved_rlc_list.html', context=context)

#view for evalutaing applications for approving bodies
@method_decorator(login_required, name='dispatch')
class Evaluate(UpdateView):
	model = Applications
	fields = ['remarks','status',]

#view for creating progress reports
@method_decorator(login_required, name='dispatch')
class ProgressCreate(CreateView):
	model = Progress_Reports
	fields = [
		'date_submitted',
		'associated_project',
		'progress_report_file',
	]
	success_url = reverse_lazy('project-detail')

#view for extending rlc applications
@login_required
def ApplicationsExtend(request, pk):

	rlc_application = Applications.objects.get(id=pk)
	semester = Applications.get_current_semester()
	schoolyear = Applications.get_current_schoolyear()
	projects = Projects.objects.filter(application=rlc_application)

	if request.method == "POST":
		newappform = ExtendApplication(request.POST)
		app = newappform.save(commit=False)
		app.applicant = rlc_application.applicant
		app.associated_department = rlc_application.applicant.department
		app.associated_college = rlc_application.applicant.college
		app.previous_application = rlc_application

		if rlc_application.semester_applicable == 'FIRST':
			app.semester_applicable = 'SECOND'
			app.schoolyear = schoolyear

		elif rlc_application.semester_applicable == 'SECOND':
			app.semester_applicable = "MIDYEAR"
			app.schoolyear = schoolyear

		elif rlc_application.semester_applicable == 'MIDYEAR':
			app.semester_applicable = "FIRST"
			sy = int(schoolyear) + 1
			app.schoolyear = sy

		app = newappform.save()

		rlc_application.prev_status = rlc_application.status
		rlc_application.status = 'EXTENDED'
		rlc_application.save()

		newapp = Applications.objects.get(id=app.id)
		newprojects = Projects.objects.filter(application=newapp)

		context = {
			'application' : newapp,
			'projects' : newprojects,
			'semester'  : semester,
			'schoolyear' : schoolyear,
		}

		return render(request, 'rlcapp/applications_detail.html', context=context)

	else:
		newappform = ExtendApplication()

	return render(request, 'rlcapp/extend_application_form.html', {'form' : newappform})

#view for adding remarks to progress reports for approving bodies
@method_decorator(login_required, name='dispatch')
class ProgressReportAddRemarks(UpdateView):
	model = Progress_Reports
	fields = ['remarks',]
	template_name_suffix = '_add_remarks'


from pathlib import Path

import pytest

from pygit2 import GIT_MERGE_ANALYSIS_UP_TO_DATE
from pygit2 import GIT_MERGE_ANALYSIS_FASTFORWARD
import pygit2

@pytest.mark.parametrize("id", [None, 42])
def test_merge_invalid_type(mergerepo, id):
    with pytest.raises(TypeError): mergerepo.merge(id)

def test_merge_analysis_uptodate(mergerepo):
    branch_head_hex = '5ebeeebb320790caf276b9fc8b24546d63316533'
    branch_id = mergerepo.get(branch_head_hex).id

    analysis, preference = mergerepo.merge_analysis(branch_id)
    assert analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE
    assert not analysis & GIT_MERGE_ANALYSIS_FASTFORWARD
    assert {} == mergerepo.status()

    analysis, preference = mergerepo.merge_analysis(branch_id, 'refs/heads/ff-branch')
    assert analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE
    assert not analysis & GIT_MERGE_ANALYSIS_FASTFORWARD
    assert {} == mergerepo.status()

def test_merge_analysis_fastforward(mergerepo):
    branch_head_hex = 'e97b4cfd5db0fb4ebabf4f203979ca4e5d1c7c87'
    branch_id = mergerepo.get(branch_head_hex).id

    analysis, preference = mergerepo.merge_analysis(branch_id)
    assert not analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE
    assert analysis & GIT_MERGE_ANALYSIS_FASTFORWARD
    assert {} == mergerepo.status()

    analysis, preference = mergerepo.merge_analysis(branch_id, 'refs/heads/master')
    assert not analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE
    assert analysis & GIT_MERGE_ANALYSIS_FASTFORWARD
    assert {} == mergerepo.status()

def test_merge_no_fastforward_no_conflicts(mergerepo):
    branch_head_hex = '03490f16b15a09913edb3a067a3dc67fbb8d41f1'
    branch_id = mergerepo.get(branch_head_hex).id
    analysis, preference = mergerepo.merge_analysis(branch_id)
    assert not analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE
    assert not analysis & GIT_MERGE_ANALYSIS_FASTFORWARD
    # Asking twice to assure the reference counting is correct
    assert {} == mergerepo.status()
    assert {} == mergerepo.status()

def test_merge_invalid_hex(mergerepo):
    branch_head_hex = '12345678'
    with pytest.raises(KeyError): mergerepo.merge(branch_head_hex)

def test_merge_already_something_in_index(mergerepo):
    branch_head_hex = '03490f16b15a09913edb3a067a3dc67fbb8d41f1'
    branch_oid = mergerepo.get(branch_head_hex).id
    with (Path(mergerepo.workdir) / 'inindex.txt').open('w') as f:
        f.write('new content')
    mergerepo.index.add('inindex.txt')
    with pytest.raises(pygit2.GitError): mergerepo.merge(branch_oid)

def test_merge_no_fastforward_conflicts(mergerepo):
    branch_head_hex = '1b2bae55ac95a4be3f8983b86cd579226d0eb247'
    branch_id = mergerepo.get(branch_head_hex).id

    analysis, preference = mergerepo.merge_analysis(branch_id)
    assert not analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE
    assert not analysis & GIT_MERGE_ANALYSIS_FASTFORWARD

    mergerepo.merge(branch_id)
    assert mergerepo.index.conflicts is not None
    with pytest.raises(KeyError):
        mergerepo.index.conflicts.__getitem__('some-file')
    assert 'some-file' not in mergerepo.index.conflicts
    assert '.gitignore' in mergerepo.index.conflicts

    status = pygit2.GIT_STATUS_CONFLICTED
    # Asking twice to assure the reference counting is correct
    assert {'.gitignore': status} == mergerepo.status()
    assert {'.gitignore': status} == mergerepo.status()

    ancestor, ours, theirs = mergerepo.index.conflicts['.gitignore']
    assert ancestor is None
    assert ours is not None
    assert theirs is not None
    assert '.gitignore' == ours.path
    assert '.gitignore' == theirs.path
    assert 1 == len(list(mergerepo.index.conflicts))

    # Checking the index works as expected
    mergerepo.index.add('.gitignore')
    mergerepo.index.write()
    assert mergerepo.index.conflicts is None
    assert {'.gitignore': pygit2.GIT_STATUS_INDEX_MODIFIED} == mergerepo.status()

def test_merge_remove_conflicts(mergerepo):
    other_branch_tip = '1b2bae55ac95a4be3f8983b86cd579226d0eb247'
    mergerepo.merge(other_branch_tip)
    idx = mergerepo.index
    conflicts = idx.conflicts
    assert conflicts is not None
    assert '.gitignore' in conflicts
    try:
        conflicts['.gitignore']
    except KeyError:
        mergerepo.fail("conflicts['.gitignore'] raised KeyError unexpectedly")
    del idx.conflicts['.gitignore']
    with pytest.raises(KeyError): conflicts.__getitem__('.gitignore')
    assert '.gitignore' not in conflicts
    assert idx.conflicts is None

@pytest.mark.parametrize("favor", [
    'ours',
    'theirs',
    'union',
])
def test_merge_favor(mergerepo, favor):
    branch_head_hex = '1b2bae55ac95a4be3f8983b86cd579226d0eb247'
    mergerepo.merge(branch_head_hex, favor=favor)

    assert mergerepo.index.conflicts is None

def test_merge_fail_on_conflict(mergerepo):
    branch_head_hex = '1b2bae55ac95a4be3f8983b86cd579226d0eb247'
    with pytest.raises(pygit2.GitError):
        mergerepo.merge(branch_head_hex, flags={'fail_on_conflict': True})

def test_merge_commits(mergerepo):
    branch_head_hex = '03490f16b15a09913edb3a067a3dc67fbb8d41f1'
    branch_id = mergerepo.get(branch_head_hex).id

    merge_index = mergerepo.merge_commits(mergerepo.head.target, branch_head_hex)
    assert merge_index.conflicts is None
    merge_commits_tree = merge_index.write_tree(mergerepo)

    mergerepo.merge(branch_id)
    index = mergerepo.index
    assert index.conflicts is None
    merge_tree = index.write_tree()

    assert merge_tree == merge_commits_tree

def test_merge_commits_favor(mergerepo):
    branch_head_hex = '1b2bae55ac95a4be3f8983b86cd579226d0eb247'
    merge_index = mergerepo.merge_commits(mergerepo.head.target, branch_head_hex, favor='ours')
    assert merge_index.conflicts is None

    with pytest.raises(ValueError):
        mergerepo.merge_commits(mergerepo.head.target, branch_head_hex, favor='foo')

def test_merge_trees(mergerepo):
    branch_head_hex = '03490f16b15a09913edb3a067a3dc67fbb8d41f1'
    branch_id = mergerepo.get(branch_head_hex).id
    ancestor_id = mergerepo.merge_base(mergerepo.head.target, branch_id)

    merge_index = mergerepo.merge_trees(ancestor_id, mergerepo.head.target, branch_head_hex)
    assert merge_index.conflicts is None
    merge_commits_tree = merge_index.write_tree(mergerepo)

    mergerepo.merge(branch_id)
    index = mergerepo.index
    assert index.conflicts is None
    merge_tree = index.write_tree()

    assert merge_tree == merge_commits_tree

def test_merge_trees_favor(mergerepo):
    branch_head_hex = '1b2bae55ac95a4be3f8983b86cd579226d0eb247'
    ancestor_id = mergerepo.merge_base(mergerepo.head.target, branch_head_hex)
    merge_index = mergerepo.merge_trees(ancestor_id, mergerepo.head.target, branch_head_hex, favor='ours')
    assert merge_index.conflicts is None

    with pytest.raises(ValueError):
        mergerepo.merge_trees(ancestor_id, mergerepo.head.target, branch_head_hex, favor='foo')

def test_merge_options():
    from pygit2.ffi import C

    # Default
    o = pygit2.Repository._merge_options()
    assert o.file_favor == C.GIT_MERGE_FILE_FAVOR_NORMAL
    assert o.flags == C.GIT_MERGE_FIND_RENAMES
    assert o.file_flags == 0

    o = pygit2.Repository._merge_options(
        favor='ours', flags={'fail_on_conflict': True}, file_flags={'ignore_whitespace': True}
    )
    assert o.file_favor == C.GIT_MERGE_FILE_FAVOR_OURS
    assert o.flags == C.GIT_MERGE_FIND_RENAMES | C.GIT_MERGE_FAIL_ON_CONFLICT
    assert o.file_flags == C.GIT_MERGE_FILE_IGNORE_WHITESPACE

    o = pygit2.Repository._merge_options(
        favor='theirs', flags={'find_renames': False}, file_flags={'ignore_whitespace': False}
    )
    assert o.file_favor == C.GIT_MERGE_FILE_FAVOR_THEIRS
    assert o.flags == 0
    assert o.file_flags == 0

    o = pygit2.Repository._merge_options(
        favor='union',
        flags={'find_renames': True, 'no_recursive': True},
        file_flags={'diff3_style': True, 'ignore_whitespace': True, 'patience': True}
    )
    assert o.file_favor == C.GIT_MERGE_FILE_FAVOR_UNION
    assert o.flags == C.GIT_MERGE_FIND_RENAMES | C.GIT_MERGE_NO_RECURSIVE
    assert o.file_flags == (
        C.GIT_MERGE_FILE_STYLE_DIFF3
        | C.GIT_MERGE_FILE_IGNORE_WHITESPACE
        | C.GIT_MERGE_FILE_DIFF_PATIENCE
    )

def test_merge_many(mergerepo):
    branch_head_hex = '03490f16b15a09913edb3a067a3dc67fbb8d41f1'
    branch_id = mergerepo.get(branch_head_hex).id
    ancestor_id = mergerepo.merge_base_many([mergerepo.head.target, branch_id])

    merge_index = mergerepo.merge_trees(ancestor_id, mergerepo.head.target, branch_head_hex)
    assert merge_index.conflicts is None
    merge_commits_tree = merge_index.write_tree(mergerepo)

    mergerepo.merge(branch_id)
    index = mergerepo.index
    assert index.conflicts is None
    merge_tree = index.write_tree()

    assert merge_tree == merge_commits_tree

def test_merge_octopus(mergerepo):
    branch_head_hex = '03490f16b15a09913edb3a067a3dc67fbb8d41f1'
    branch_id = mergerepo.get(branch_head_hex).id
    ancestor_id = mergerepo.merge_base_octopus([mergerepo.head.target, branch_id])

    merge_index = mergerepo.merge_trees(ancestor_id, mergerepo.head.target, branch_head_hex)
    assert merge_index.conflicts is None
    merge_commits_tree = merge_index.write_tree(mergerepo)

    mergerepo.merge(branch_id)
    index = mergerepo.index
    assert index.conflicts is None
    merge_tree = index.write_tree()

    assert merge_tree == merge_commits_tree


# Generator function that provides infinte fibonacci numbers
def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

# We need to impose a stop condition externally to use it
max_n = 7
fib_numbers = []
for i, fib in enumerate(fibonacci()):
    if i >= max_n:
        break
    else:
        fib_numbers.append(fib)
print(fib_numbers)

# Another way of doing that is using 'islice' from itertools
import itertools
# Generator expression
fib_gen = (fib for fib in itertools.islice(fibonacci(), max_n))
print(list(fib_gen))


import pygame
pygame.init()
screen = pygame.display.set_mode((800, 800))
pygame.display.set_caption("Test")
screen.fill((255, 211, 0))
pygame.display.flip()

class Hero(pygame.sprite.Sprite):
    def __init__(self, x, filename):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('').convert_alpha()
        self.rect = self.image.get_rect(center=(x, 0))

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
pygame.quit()


import sys
import os
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

#check if the input file name is provided
if len(sys.argv) < 2:
    print("[!]Usage: python dataEnc.py <input file name>")
    sys.exit(0)

#get the input file name from the command line
inputFile = sys.argv[1]

#locate the file in the computer
if not os.path.isfile(inputFile):
    print("[-]File not found")
    sys.exit(0)
else:
    print("[+]File found")
    filepath = os.path.abspath(inputFile)

#start timer
start = cv.getTickCount()

print("[!]Reading file")
file = open(filepath, "rb")

#read the file into a byte array
data = file.read()

#close file
file.close()

gray_values = np.frombuffer(data, dtype=np.uint8)

print("[!]Calculating size of the image")
#calculate the size of the equivalent 2d array
size = int(np.sqrt(len(gray_values)))

print("[!]Creating image header")
#create a header for the image with the original file type preceded and followed by $
header = "$" + inputFile[-3:] + "$"

#convert the header into a int array
header_values = np.frombuffer(header.encode(), dtype=np.uint8)

#add the header to the start of the array
gray_values = np.insert(gray_values, 0, header_values)

print("[!]Adjusting size of the image")
while size*size < len(gray_values):
    size += 1

print("[!]Adding zeros to fill the blank spaces")
#add zeros to the start of the array to make it a perfect square
zeros_to_add = size*size - len(gray_values)
zeros_added = 0
while len(gray_values) < size*size:
    print(f'\r[!]Zeros added: {zeros_added}/{zeros_to_add}', end='')
    gray_values = np.insert(gray_values, 0, 0)
    zeros_added += 1

print("\n[!]Reshaping the array into a 2d array")
#reshape the 1d array into a 2d array
gray_img = gray_values.reshape(size, size)

#stop timer
end = cv.getTickCount() - start

#check if the image is created
if gray_img is None:
    print(f'[-]Image not created! Time taken: {str(end/cv.getTickFrequency())}s')
    sys.exit(0)
else:
    print(f'[+]Image created successfully with size of {str(pow(size, 2))} bytes! Time taken: {str(end/cv.getTickFrequency())}s')
    #save the image as a tiff file with the file name from the command line and the adittion of "_enc.tif"
    cv.imwrite(inputFile[:-4] + "_enc.tif", gray_img)

#show the image in a window with matplotlib
plt.imshow(gray_img, cmap='gray', vmin=0, vmax=255)
plt.show()


"""
Authored by Bryce Burgess

6/4/2019

"""

import math
import skimage
import random
import numpy as np

class Image():
    def __init__(self, size):
        self.size = size
        self.__init_pixels()

    def __init_pixels(self):
        return None

class ImageMask():
    def __init__(self, height=1000, width = 1000):
        self.dims = (height, width)
        self.height = height
        self.width = width
        self.mask = np.zeros(self.dims)

    def ordered_lines(self, slope = 1/3, intercept_step = 50):

        for i in range(-self.height*slope, self.height, intercept_step):
            rr1, cc1 = skimage.draw.line(i, i, self.height*slope + i, self.width)
            rr2, cc2 = skimage.draw.line(i, self.width, self.height*slope + i, i)

        for i in range(intercept_step):
            rr3, cc3 = skimage.draw.line(0, i, self.height, i)

        self.mask[rr1, cc1] = 1
        self.mask[rr2, cc2] = 1
        self.mask[rr3, cc3] = 1

    def random_lines(self, n_lines):

        # choose random points on each edge
        grouped_intercepts   = {"left":  [[random.choice(range(self.height)), 0         ] for i in range(n_lines)],
                                "right": [[random.choice(range(self.height)), self.width] for i in range(n_lines)],
                                "top":   [[0,           random.choice(range(self.width))] for i in range(n_lines)],
                                "bottom":[[self.height, random.choice(range(self.width))] for i in range(n_lines)]
        }

        # get pairs of intercepts to create lines
        intercepts = [pt for key in grouped_intercepts.keys() for pt in grouped_intercepts[key]]
        for i in range(n_lines):
            pt1 = random.choice(intercepts)
            pt2 = random.choice(intercepts)

            # check that intercept pair are not on the same edge
            for key in grouped_intercepts:
                while pt1 in grouped_intercepts[key] and pt2 in grouped_intercepts[key]:
                    pt2 = random.choice(intercepts)

            # create line
            rr, cc = skimage.draw.line(pt1[0], pt1[1], pt2[0], pt2[1])
            self.mask[rr, cc] = 1

    def polygon_segments(self, _n_vertices):
        self.n_vertices = _n_vertices
        self.vertices = []
        for i in range(self.n_vertices):
            self.vertices.append([random.choice(range(self.height)), random.choice(range(self.width))])

        # how to create polygons?

    def find_region_indices(self):
        self.regions = {1:[]}
        for i,j in self.mask:
            for r in self.regions.keys():
                pix_in_regions = True

                # assign border pixels to region (bottom left for reference)
                if self.mask[i,j] == 1:
                    if any([self.mask[i+1,j] in self.regions[r], self.mask[i,j+1] in self.regions[r]]):
                        self.regions[r] += [[i,j]]

                # assign empty pixels to region based on neighbors
                if self.mask[i,j] == 0:
                    if any([self.mask[i+1,j] in self.regions[r], self.mask[i,j+1] in self.regions[r], self.mask[i-1,j] in self.regions[r], self.mask[i,j-1] in self.regions[r],]):
                        self.regions[r] += [[i,j]]
            else:
                pix_in_regions = False

            # if pixel not in existing regions, create a new one and add it
            if not pix_in_regions:
                self.regions[r+1] = [[i,j]]

        return self.regions

class PolygonPainting(Image):
    def __init__(self, size, n_colors, n_polygons):
        self.size = size
        self.__init_pixels()

        self.n_colors = n_colors

        self.n_polygons = n_polygons
        self.partition()

    def __init_pixels(self):
        pass

    def partition(self):
        # get random number
        polygon_max = 100
        polygon_min = 30

        poly_dist = lambda polygon_min, polygon_max: random.random()*(polygon_max-polygon_min) + polygon_min

        # use number to get points around border
        border_len = 2*self.size[0] + 2*self.size[1]
        intervals = []
        while max(intervals) < border_len:
            intervals.append(poly_dist(polygon_max, polygon_min))

        for i in range(len(intervals)):
            if i != 0:
                intervals[i] += intervals[i-1]

        # turn interval into coordinates by travelling along edge
        outer_vertices = []
        for i in intervals:
            if i < self.size[0]:
                x = i
                y = 0

            elif i < self.size[0] + self.size[1]:
                x = self.size[0]
                y = i-self.size[0]

            elif i < 2*self.size[0] + self.size[1]:
                x = -i+self.size[0]+self.size[1]
                y = self.size[1]

            elif i < 2*self.size[0] + 2*self.size[1]:
                x = 0
                y = i-2*self.size[0] - self.size[1]

            outer_vertices.append((x, y))

        # get set of points randomly within some distance of border
        # connect nearish points to make polygons

        used_vertices = []
        dist = lambda x,y: (x[0] - y[0])**2 + (x[1] - y[1])**2
        for i in outer_vertices:
            # make polygon from 2-3 border vertices + nearby internal vertex
            pass

def choose_color():
    pass


"""Objects to analyze the crawled data."""

from __future__ import annotations
from typing import Dict, List, Tuple, Any
from transformers import \
    AutoImageProcessor, \
    AutoModelForObjectDetection, \
    AutoTokenizer, \
    AutoConfig, \
    RobertaForSequenceClassification, \
    AutoModelForSequenceClassification, \
    AutoModelForVideoClassification, \
    AutoModelForSemanticSegmentation
import transformers
import numpy as np
import pandas as pd
from PIL import Image
import torch
from rich.progress import Progress, TaskID
from concurrent.futures import ThreadPoolExecutor, as_completed
from sklearn.cluster import DBSCAN
import face_recognition
from instacrawl.steps import InstaStepFour, PersonImage, FaceData
import time as sleep
from instacrawl.console import console
import os

np.random.seed(0)
transformers.logging.set_verbosity(transformers.logging.CRITICAL)

def sample_frame_indices(clip_len, frame_sample_rate, seg_len):
    converted_len = int(clip_len * frame_sample_rate)
    end_idx = np.random.randint(converted_len, seg_len)
    start_idx = end_idx - converted_len
    indices = np.linspace(start_idx, end_idx, num=clip_len)
    indices = np.clip(indices, start_idx, end_idx - 1).astype(np.int64)
    return indices

class Postalyzer:
    """Analyze the crawled data."""

    def __init__(
        self,
        data: InstaStepFour
    ):
        """Initialize the analysis."""
        self.data = data
        self.nlp = TextAnalysis(self.data)
        self.vid = VideoAnalysis(self.data)
        self.img = ImageAnalysis(self.data)

    def analyze(self) -> List[pd.DataFrame]:
        data: List[pd.DataFrame] = []
        with Progress(console=console) as progress:
            self.progress = progress
            task = self.progress.add_task(
                "Analyzing posts...",
                total=None
            )
            with ThreadPoolExecutor(max_workers=1) as executor:
                futures = []
                f = executor.submit(
                    self.vid.run,
                    self.progress
                )
                futures.append(f)
                f = executor.submit(
                    self.nlp.run,
                    self.progress
                )
                futures.append(f)
                f = executor.submit(
                    self.img.run,
                    self.progress
                )
                futures.append(f)
                for fut in as_completed(futures):
                    exce = fut.exception()
                    if exce is not None:
                        console.log(exce)
                    else:
                        data.append(fut.result())
            self.progress.update(task, completed=1)
        return data

class InstaAnalysis(object):
    def __init__(
        self,
        data: InstaStepFour,
        name: str
    ):
        self.data = data
        self.task: TaskID | None = None
        self.completed: int | None = None
        self.results: Dict[int, Dict[str, Dict[str, Any]]] = {}
        self.name = name

    def insert_result(
        self,
        post: int,
        cat: str,
        label: str,
        data: Any,
        append: bool = False
    ):
        if post not in self.results.keys():
            self.results[post] = {}
        if cat not in self.results[post].keys():
            self.results[post][cat] = {}
        if append:
            if label not in self.results[post][cat].keys():
                self.results[post][cat][label] = [data]
            else:
                self.results[post][cat][label].append(data)
        else:
            self.results[post][cat][label] = data

    def analyze(self):
        ...

    def run(
        self,
        progress: Progress | None = None,
    ) -> pd.DataFrame:
        self.progress = progress
        self.analyze()
        sleep.sleep(3)
        data = self.save()
        return data

    def track(self, name: str, len: int | None = None):
        if hasattr(self, "progress") and isinstance(
            self.progress,
            Progress
        ):
            if not name.endswith("..."):
                name = name + "..."
            self.task = self.progress.add_task(
                name,
                total=len,
            )
            self.completed = len if len is not None else 1

    def advance(self):
        if (hasattr(self, "progress") and
                hasattr(self, "task") and
                isinstance(
            self.progress,
            Progress
        ) and isinstance(
            self.task,
            int
        )):
            self.progress.update(self.task, advance=1)

    def complete(self):
        if (hasattr(self, "progress") and
                hasattr(self, "task") and
                hasattr(self, "completed") and
                isinstance(
            self.progress,
            Progress
        ) and isinstance(
            self.task,
            int
        ) and isinstance(
            self.completed,
            int,
        )):
            self.progress.update(self.task, completed=self.completed)
            self.task = None
            self.completed = None

    def save(self) -> pd.DataFrame:
        self.track(
            f"Saving the {self.name} results",
            ((len(self.results) * 2) + 2)
        )

        index: List[int] = []
        columns: List[Tuple[str, str]] = []
        for key in self.results.keys():
            if key not in index:
                index.append(key)
            for col1_key in self.results[key].keys():
                for col2_key in self.results[key][col1_key].keys():
                    if (col1_key, col2_key) not in columns:
                        columns.append((col1_key, col2_key))
            self.advance()

        lists: List[List[Any]] = []
        for key in index:
            row: List[Any] = []
            for (col1_key, col2_key) in columns:
                if col1_key not in self.results[key].keys():
                    row.append(None)
                elif col2_key not in self.results[key][col1_key].keys():
                    row.append(None)
                else:
                    row.append(self.results[key][col1_key][col2_key])
            lists.append(row)
            self.advance()

        data = pd.DataFrame(
            lists,
            columns=pd.MultiIndex.from_tuples(columns),
            index=index
        )
        self.advance()
        data.to_html(
            os.path.join(
                self.data.path,
                f"{self.name}_analysis.html"
            )
        )
        data.to_excel(
            os.path.join(
                self.data.path,
                f"{self.name}_analysis.xlsx"
            )
        )
        data.to_pickle(
            os.path.join(
                self.data.path,
                f"{self.name}_analysis.pkl"
            )
        )
        self.complete()
        return data

# Results structure:
#   self.results: Dict[int, Dict[str, Dict[str, Any]]] = {
#       PostIndex: {
#           measurementCategory: {
#               measurementName: measurementData
#           }
#       }
#   }

class VideoAnalysis(InstaAnalysis):
    """Analyze the crawled videos."""

    def __init__(
        self,
        data: InstaStepFour,
        model_name: str = "MCG-NJU/videomae-base-finetuned-kinetics",
    ):
        """Initialize the analysis."""
        super().__init__(data=data, name="video")
        self.model_name = model_name
        self.processor = AutoImageProcessor.from_pretrained(self.model_name)
        self.model = AutoModelForVideoClassification.from_pretrained(
            self.model_name
        )

    def analyze(self):
        """Analyze the videos."""
        self.track("Analyzing videos", len(self.data.videos))
        for video in self.data.videos:
            self.inputs = self.processor(
                list(video.video),
                return_tensors="pt",
            )
            with torch.no_grad():
                output = self.model(**self.inputs)
                logits = output.logits
            label = logits.argmax(-1).item()
            self.insert_result(
                video.post,
                "activity",
                self.model.config.id2label[label],
                logits[0][label].item()
            )
            self.advance()
        self.complete()

class ImageAnalysis(InstaAnalysis):
    """Analyze the crawled images."""

    def __init__(
        self,
        data: InstaStepFour,
        model_name: str = "facebook/detr-resnet-50",
        transformer_name: str = "mattmdjaga/segformer_b2_clothes"
    ):
        """Initialize the analysis."""
        super().__init__(
            data=data,
            name="image"
        )
        self.model_name = model_name
        self.transformer_name = transformer_name
        self.processor = AutoImageProcessor.from_pretrained(self.model_name)
        self.model = AutoModelForObjectDetection.from_pretrained(
            self.model_name
        )
        self.extractor = AutoImageProcessor.from_pretrained(
            self.transformer_name
        )
        self.transformer = \
            AutoModelForSemanticSegmentation.from_pretrained(
                self.transformer_name
            )
        self.annotations: Dict[int, str] = {
            1: "hat",
            2: "hair",
            3: "sunglasses",
            4: "upperclothes",
            5: "skirt",
            6: "pants",
            7: "dress",
            8: "belt",
            9: "leftShoe",
            10: "rightShoe",
            11: "face",
            12: "leftLeg",
            13: "rightLeg",
            14: "leftArm",
            15: "rightArm",
            16: "bag",
            17: "scarf"
        }

    def analyze(self):
        """Analyze the videos."""
        self.detector()
        self.segmenter()
        self.recognizer()
        self.classifier()
        sleep.sleep(3)

    def detector(self):
        self.track("Detecting objects", len(self.data.images))
        for image in self.data.images:
            inputs = self.processor(
                images=image.image,
                return_tensors="pt"
            )
            with torch.no_grad():
                outputs = self.model(**inputs)
                target_sizes = torch.tensor([image.image.size[::-1]])
                outs = self.processor.post_process_object_detection(
                    outputs,
                    target_sizes=target_sizes,
                    threshold=0.94
                )[0]
                boxes = outs['boxes'].detach().numpy()
                labels = outs['labels'].detach().numpy()
                scores = outs['scores'].detach().numpy()
            p = 0
            for score, label, box in zip(
                scores,
                labels,
                boxes
            ):
                label = self.model.config.id2label[label.item()]
                xmin = box[0]
                ymin = box[1]
                xmax = box[2]
                ymax = box[3]
                self.insert_result(image.post, label, "score", score.item())
                self.insert_result(image.post, label, "xmin", xmin)
                self.insert_result(image.post, label, "ymin", ymin)
                self.insert_result(image.post, label, "xmax", xmax)
                self.insert_result(image.post, label, "ymax", ymax)
                if label == "person":
                    self.insert_result(image.post, "people", "count", p)
                    x1 = 0 if int(xmin) < 0 else int(xmin)
                    x2 = int(xmax)
                    y1 = 0 if int(ymin) < 0 else int(ymin)
                    y2 = int(ymax)
                    self.data.people.append(
                        PersonImage(
                            post=image.post,
                            image=image.index,
                            index=p,
                            path=image.path,
                            person=Image.fromarray(
                                np.array(image.image)[y1:y2, x1:x2]
                            )
                        )
                    )
                    p += 1
            self.advance()
        self.complete()

    def segmenter(self):
        self.track(
            "Segmenting people",
            (
                len(self.data.people) *
                len(self.annotations)
            )
        )
        for person in self.data.people:
            if person.post not in self.results.keys():
                self.results[person.post] = {}
            if "visible" not in self.results[person.post].keys():
                self.results[person.post]["visible"] = {
                    "hat": 0,
                    "hair": 0,
                    "sunglasses": 0,
                    "upperclothes": 0,
                    "skirt": 0,
                    "pants": 0,
                    "dress": 0,
                    "belt": 0,
                    "leftShoe": 0,
                    "rightShoe": 0,
                    "face": 0,
                    "leftLeg": 0,
                    "rightLeg": 0,
                    "leftArm": 0,
                    "rightArm": 0,
                    "bag": 0,
                    "scarf": 0
                }
            inputs = self.extractor(images=person.person, return_tensors="pt")
            pixel_values = inputs["pixel_values"]
            with torch.no_grad():
                outputs = self.transformer(pixel_values=pixel_values)
            logits = outputs.logits
            upsampled_logits = torch.nn.functional.interpolate(
                logits,
                size=person.person.size[::-1],
                mode="bilinear",
                align_corners=False,
            )
            pred_seg = upsampled_logits.argmax(dim=1)[0]
            for num, label in self.annotations.items():
                segment = pred_seg.clone()
                self.advance()
                if num not in segment or 0 not in segment:
                    continue
                self.results[person.post]["visible"][label] += 1
        self.complete()

    def recognizer(self):
        self.track("Recognizing faces", len(self.data.images))
        for face in self.data.images:
            boxes = face_recognition.face_locations(
                face.array,
                model='cnn'
            )
            encodings = face_recognition.face_encodings(
                face.array,
                boxes
            )
            for box, encoding in zip(boxes, encodings):
                self.data.faces.append(
                    FaceData(
                        post=face.post,
                        image=face.index,
                        path=face.path,
                        encoding=encoding,
                        box=box,
                    )
                )
            self.insert_result(
                face.post,
                "faces",
                "quantity",
                len(boxes),
            )
            self.advance()
        self.complete()

    def classifier(self):
        self.track(
            "Identifying faces",
            3
        )
        encodings = [np.array(face.encoding) for face in self.data.faces]
        clt = DBSCAN(eps=0.5, metric="euclidean")
        self.advance()
        clt.fit(encodings)
        self.advance()
        for face, label in zip(self.data.faces, clt.labels_):
            self.insert_result(face.post, "faces", f"{label}", 1)
        self.complete()

class TextAnalysis(InstaAnalysis):
    def __init__(
        self,
        data: InstaStepFour,
        model_name: str = "SamLowe/roberta-base-go_emotions",
        classifier_name: str = "alimazhar-110/website_classification",
        ranking_name: str = "cardiffnlp/twitter-roberta-base-sentiment-latest"
    ):
        """Initialize the analysis."""
        super().__init__(
            data=data,
            name="text"
        )
        self.model_name = model_name
        self.classifier_name = classifier_name
        self.ranking_name = ranking_name
        self.rank_tokenizer = AutoTokenizer.from_pretrained(self.ranking_name)
        self.rank_config = AutoConfig.from_pretrained(self.ranking_name)
        self.rank_model = RobertaForSequenceClassification.from_pretrained(
            self.ranking_name,
        )
        self.tokenizer = AutoTokenizer.from_pretrained(self.model_name)
        self.token_config = AutoConfig.from_pretrained(self.model_name)
        self.model = RobertaForSequenceClassification.from_pretrained(
            self.model_name,
        )

        self.classifier = AutoTokenizer.from_pretrained(self.classifier_name)
        self.class_config = AutoConfig.from_pretrained(self.classifier_name)
        self.class_model = AutoModelForSequenceClassification.from_pretrained(
            self.classifier_name
        )

    def analyze(self):
        self.rank()
        self.token()
        self.classify()

    def rank(self):
        self.track("Ranking the affect", len(self.data))
        for tag, post in self.data.posts.items():
            encoded_input = self.rank_tokenizer(
                post.article,
                return_tensors="pt",
                truncation=True,
                max_length=512,
            )
            with torch.no_grad():
                output = self.rank_model(**encoded_input)
            scores = output[0][0].softmax(dim=0)
            scores = scores.detach().numpy()
            ranking = np.argsort(scores)
            ranking = ranking[::-1]
            self.advance()
            for i in range(scores.shape[0]):
                label = self.rank_config.id2label[ranking[i]]
                score = scores[ranking[i]]
                self.insert_result(tag, "positivity", label, score)
        self.complete()

    def classify(self):
        self.track("Classifying the text", len(self.data))
        for tag, post in self.data.posts.items():
            encoded_input = self.classifier(
                post.article,
                return_tensors="pt",
                truncation=True,
                max_length=512
            )
            with torch.no_grad():
                output = self.class_model(**encoded_input)
            scores = output[0][0].softmax(dim=0)
            scores = scores.detach().numpy()
            ranking = np.argsort(scores)
            ranking = ranking[::-1]
            self.advance()
            for i in range(scores.shape[0]):
                label = self.class_config.id2label[ranking[i]]
                score = scores[ranking[i]]
                self.insert_result(tag, "topics", label, score)
        self.complete()

    def token(self):
        self.track("Analyzing emotions", len(self.data))
        for tag, post in self.data.posts.items():
            encoded_input = self.tokenizer(
                post.article,
                return_tensors="pt",
                truncation=True,
                max_length=512,
            )
            with torch.no_grad():
                output = self.model(**encoded_input)
            scores = output[0][0].softmax(dim=0)
            scores = scores.detach().numpy()
            ranking = np.argsort(scores)
            ranking = ranking[::-1]
            self.advance()
            for i in range(scores.shape[0]):
                label = self.token_config.id2label[ranking[i]]
                score = scores[ranking[i]]
                self.insert_result(tag, "emotions", label, score)
        self.complete()


import math
import os
import argparse

# script to check the number of data records in an EDF file

def main(file):

	# number of bytes in whole file
	numBytes = os.path.getsize(file)

	with open(file, 'r+b') as thisFile:
		# number of bytes in header
		thisFile.read(184)
		headerBytes = int(thisFile.read(8).decode("utf-8").strip())
		thisFile.read(44)
		numRec = int(thisFile.read(8).decode("utf-8").strip())
		thisFile.read(8)
		# recDur = float(thisFile.read(8).decode("utf-8").strip())
		numSigs = int(thisFile.read(4).decode("utf-8").strip())

		thisFile.read(numSigs*(16+80+8+8+8+8+8+80))

		numSamps = []
		for i in range(numSigs):
			numSamps.append(int(thisFile.read(8).decode("utf-8").strip()))

	# required bytes for calculation
	remBytes = numBytes - headerBytes

	# If the number of data record is not known
	# if(numRec < 0):
	R = sum(numSamps) * 2 # length of record for all the samples
	numRecs = math.floor(remBytes/R) # number of records

	print("data records from the file: ", numRec)
	print("The number of data records is: ", numRecs)

if __name__ == '__main__':
	parser = argparse.ArgumentParser(description='get the number of data records for edf file', formatter_class=argparse.ArgumentDefaultsHelpFormatter)

	parser.add_argument('edfFileLocation', help='File name and location for final edf file , eg:(directory/filename.edf)')

	args = parser.parse_args()
	edf_file = args.edfFileLocation

	# checking if all the arguments are given
	if not edf_file:
		sys.exit('Must provide input edf file location.')
	else:
		main(edf_file)


import time
from Constants.GpioAddress import HORIZENTAL_CAMERA_SERVO, VERTICAL_CAMERA_SERVO
import RPi.GPIO as GPIO
import cv2
class cameraController:
    def __init__(self):

        self.verticalAngle = 90
        self.horizentalAngle = 90
        GPIO.setup(VERTICAL_CAMERA_SERVO, GPIO.OUT)
        GPIO.setup(HORIZENTAL_CAMERA_SERVO, GPIO.OUT)

    def getStatus(self):
        capture = cv2.VideoCapture(0)
        capture.set(3,600)  # Gets the video frame width
        capture.set(10, 55)  # Screen brightness
        flag = False
        if (capture.isOpened()):
            # Open the camera and read the image
            flag, image = capture.read()
            if(flag):
                cv2.imwrite("./Services/Camera/status.jpg", image)
        capture.release()
        return flag

    def playVideo(self):
        while self.capture.isOpened():
            flag, image = self.capture.read()
            if(flag):
                cv2.imshow("image", image)

        self.capture.release()
        # Close all Windows
        cv2.destroyAllWindows()

    def moveVertical(self):
        verticalToMove = ((45 + self.verticalAngle)%180)
        print(verticalToMove)
        pulsewidth = (verticalToMove*11) + 500  # The pulse width
        GPIO.output(VERTICAL_CAMERA_SERVO,GPIO.HIGH)
        time.sleep(pulsewidth/1000000.0)
        GPIO.output(VERTICAL_CAMERA_SERVO,GPIO.LOW)
        self.verticalAngle = verticalToMove

    def moveHorizontal(self):
        horizentalToMove = ((45 + self.horizentalAngle)%180)
        print(horizentalToMove)
        pulsewidth = (horizentalToMove*11) + 500  # The pulse width
        GPIO.output(HORIZENTAL_CAMERA_SERVO,GPIO.HIGH)
        time.sleep(pulsewidth/1000000.0)
        GPIO.output(HORIZENTAL_CAMERA_SERVO,GPIO.LOW)
        self.horizentalAngle = horizentalToMove


import pygame
from ship import Ship
import sprite_handler as sprite
from main import HEIGHT, WIDTH

PLAYER_VELOCITY = 5
PLAYER_LASER_VEL = 6

class Player(Ship):
    def __init__(self, x, y, health=100):
        super().__init__(x, y, PLAYER_VELOCITY, health)
        self.shipImg = sprite.YELLOW_SHIP
        self.laserImg = sprite.YELLOW_LASER
        self.mask = pygame.mask.from_surface(self.shipImg)
        self.maxHealth = health

    def moveShip(self, keyDictionary):
        if keyDictionary[pygame.K_a] and self.x - self.velocity > 0:  # Left
            self.x -= self.velocity
        if keyDictionary[pygame.K_d] and self.x + self.velocity + super().getWidth() < WIDTH:  # Right
            self.x += self.velocity
        if keyDictionary[pygame.K_w] and self.y - self.velocity > 0:  # Up
            self.y -= self.velocity
        if keyDictionary[pygame.K_s] and self.y + self.velocity + super().getHeight() + 15 < HEIGHT:  # Down
            self.y += self.velocity
        if keyDictionary[pygame.K_SPACE]:
            self.shoot()

    def moveLasers(self, vel, objs):
        enemiesShot = 0
        self.updateCooldown()
        for laser in self.lasers:
            laser.moveLaser(vel)
            if laser.isOffScreen():
                self.lasers.remove(laser)
            else:
                for obj in objs:
                    if laser.collision(obj):
                        enemiesShot += 1
                        objs.remove(obj)
                        self.lasers.remove(laser)
        return enemiesShot

    def drawHealth(self, window):
        pygame.draw.rect(window, (255, 0, 0), (self.x, self.y + self.shipImg.get_height() + 10,
                                               self.shipImg.get_width(), 10))
        pygame.draw.rect(window, (0, 255, 0), (self.x, self.y + self.shipImg.get_height() + 10,
                                               (self.health / 100) * self.shipImg.get_width(), 10))


from keras.layers import Dense,Flatten,Input,Layer
from keras.models import Model
from backends import inceptionv3,vgg16,mobilenetv2
import keras.backend as K

alpha=0.2

class TripletLossLayer(Layer):
	def __init__(self, alpha, **kwargs):
		self.alpha = alpha
		super(TripletLossLayer, self).__init__(**kwargs)

	def triplet_loss(self, inputs):
		a, p, n = inputs
		p_dist = K.sum(K.square(a - p), axis=-1)
		n_dist = K.sum(K.square(a - n), axis=-1)
		return K.sum(K.maximum(p_dist - n_dist + self.alpha, 0), axis=0)

	def call(self, inputs):
		loss = self.triplet_loss(inputs)
		self.add_loss(loss)
		return loss

def triplet_loss(y_true,y_pred):
	a,p,n=y_pred[0],y_pred[1],y_pred[2]

	p_dist=K.sum(K.square(a-p),axis=-1)
	n_dist=K.sum(K.square(a-n),axis=-1)

	base_dist=p_dist-n_dist+alpha

	loss=K.sum(K.maximum(base_dist,0))

	return loss

def base_model(BASE_MODEL):
	input_=Input(shape=(96,96,3))
	if BASE_MODEL=="INCEPTIONV3":
		backend=inceptionv3()
		print(30*"-"+"got inceptionv3 as the backend"+30*"-")
	elif BASE_MODEL=="VGG16":
		backend=vgg16()
		print(30*"-"+"got vgg16 as the backend"+30*"-")
	elif BASE_MODEL=="MOBILENET":
		backend=mobilenetv2()
		print(30*"-"+"got mobilenetv2 as the backend"+30*"-")

	features_temp=backend(input_)
	flatten=Flatten()(features_temp)
	dense=Dense(128)(flatten)

	model=Model(input_,dense)
	print(model.summary())
	return model

def model(BASE_MODEL):
	bs_model=base_model(BASE_MODEL)

	input_a=Input(shape=(96,96,3))
	input_p=Input(shape=(96,96,3))
	input_n=Input(shape=(96,96,3))

	embedding_a=bs_model(input_a)
	embedding_p=bs_model(input_p)
	embedding_n=bs_model(input_n)

	triplet_loss_layer = TripletLossLayer(alpha=0.2, name='triplet_loss_layer')([embedding_a, embedding_p, embedding_n])

	model=Model([input_a,input_p,input_n],triplet_loss_layer)

	model.compile(optimizer="adam",loss=None)

	return model

def triplet_loss_test():
    with tf.Session() as test:
        tf.set_random_seed(1)
        y_true = (None, None, None)
        y_pred = (tf.random_normal([3, 128], mean=6, stddev=0.1, seed=1),
                  tf.random_normal([3, 128], mean=1, stddev=1, seed=1),
                  tf.random_normal([3, 128], mean=3, stddev=4, seed=1))
        loss = triplet_loss(y_true, y_pred)

        print("loss = " + str(loss.eval()))

if __name__=="__main__":
	BASE_MODEL="MOBILENET"
	model=model(BASE_MODEL)
	model.summary()


from flask import Flask, render_template, Response, url_for, request
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
# from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import io
import base64
import numpy as np
import pandas as pd
import string
import random as rnd
from wtforms import Form, IntegerField, validators

app = Flask(__name__)

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

def define_df(dp = 10, nc=2):
    x = pd.DataFrame(np.random.randn(dp, nc))
    nrows = np.shape(x)[1]
    x.columns = list(string.ascii_lowercase[0:nrows])
    return x

class InputForm(Form):
    d = IntegerField(
        label = 'discrete series', default = 5, validators = [validators.InputRequired()]
    )
    c = IntegerField(
        label = 'Continous series', default = 5, validators = [validators.InputRequired()]
    )
    nr = IntegerField(
        label = 'No. of Rows', default = 10, validators = [validators.InputRequired()]
    )
    nc = IntegerField(
        label = 'No. of Columns', default = 5, validators = [validators.InputRequired()]
    )

@app.route('/simulations', methods = ['GET','POST'])
def simulations():
    form = InputForm(request.form)
    df = define_df(form.nr.data, form.nc.data)
    return render_template('simulations.html', table=df.to_html())

@app.route('/table', methods = ['POST','GET'])
def table():
    form = InputForm(request.form)
    if request.method == "GET" and form.validate():
        dat = define_df(form.d.data, form.nc.data)
        data = dat.to_html
        return render_template('table.html', name = "dataset", data = data)
        #return render_template('table.html', data=data)

# @app.route('/datasimform', methods = ['POST','GET'])
# def datasimform():
#     return render_template('simulations.html')
#
# # @app.route('/datasim', methods = ['GET'])
# @app.route('/table', methods = ['POST','GET'])
# def table():
#     # x = define_df()
#     # return render_template('table.html', name = 'dataset', data = x.to_html())
#
#     if request.method == 'GET':
#         d = request.args.get('discrete')
#         c = request.args.get('continous')
#         nr = request.args.get('m')
#         nc = request.args.get('n')
#         v = request.args.get('vector') == 'Vector'
#         m = request.args.get('matrix') == 'Matrix'
#
#         # return 'discrete'+'\t'+d + '\t' +c+'\t' +nr+'\t' +nc
#         # if (v):
#         # df = np.random.randn(1, int(d), int(nr))
#         # dat = pd.DataFrame({'x':df})
#             # return render_template('table.html', name = 'dataset', data = dat.to_html())
#         return
#     #
#     #     else:
#     #         df = np.random.randn(1, 5, 10)
#     #         dat = pd.DataFrame({'x':df})
#     #         return render_template('table.html', name = 'dataset', data = dat.to_html())

@app.route('/plots')
def build_plot():

    img = io.BytesIO()

    x = np.arange(0, 10)
    y = np.random.normal(0, 1, 10)

    plt.plot(x, y, '-o')

    plt.subplot(2, 1, 1)
    plt.plot(x, y, '-o')
    plt.subplot(2, 1, 2)
    y1 = np.random.normal(0, 1, 10)
    plt.plot(x, y1, '-o')

    plt.savefig(img, format = 'png')

    img.seek(0)

    plot_url = base64.b64encode(img.getvalue()).decode()
    return '<img src="data:image/png; base64, {}">'.format(plot_url)

@app.route('/test')
def chartTest():
  lnprice=np.log(np.arange(1, 10))
  plt.plot(lnprice)
  plt.savefig('static/images/plot1.png')
  return render_template('test.html', name = 'plot1', url = url_for('static', '/images/plot1.png'))

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


from tools.qt import QtWidgets, tr

from lib.bip import Kij, EoSBIP
from lib.sql import databank
from UI.widgets import Tabla

class Ui_BIP(QtWidgets.QDialog):
    """Dialog to view the BIP between selected component for EoS available

    Parameters
    ----------
    ids : list
        Index of component
    EoSIndex: integer
        Index of EoS with BIP to show
    """
    def __init__(self, ids, EoSIndex=0, parent=None):
        """Constructor"""
        super(Ui_BIP, self).__init__(parent)
        self.setWindowTitle(tr(
            "pychemqt", "BIP (Binary interaction parameters)"))

        lyt = QtWidgets.QGridLayout(self)
        lyt.addWidget(QtWidgets.QLabel("EoS"), 1, 1)
        self.eleccion = QtWidgets.QComboBox()
        lyt.addWidget(self.eleccion, 1, 2)
        lyt.addItem(QtWidgets.QSpacerItem(
            0, 0, QtWidgets.QSizePolicy.Policy.Expanding,
            QtWidgets.QSizePolicy.Policy.Fixed), 1, 3)
        self.stacked = QtWidgets.QStackedWidget()
        lyt.addWidget(self.stacked, 2, 1, 1, 3)

        # Get component names to show in table header
        names = []
        for cmp in ids:
            databank.execute(
                "SELECT id, name FROM compuestos WHERE id==%i" % cmp)
            names.append("%4i - %s" % databank.fetchone())

        args = (len(ids), len(ids))
        kw = {"stretch": False, "readOnly": True, "horizontalHeader": names,
              "verticalHeaderLabels": names}

        title = {"WILSON": "Aij", "UNIQUAC": "ΔUij", "NRTL": "Gij"}

        # Iterate over the EoS available
        for EoS in EoSBIP:
            self.eleccion.addItem(EoS)
            k = Kij(ids, EoS)

            widget = QtWidgets.QWidget()
            lyt2 = QtWidgets.QVBoxLayout(widget)
            lyt2.addWidget(QtWidgets.QLabel(title.get(EoS, "Kij")))
            table1 = Tabla(*args, **kw)
            lyt2.addWidget(table1)

            # Special case for NRTL with two interaction parameters matrix
            if EoS == "NRTL":
                lyt2.addWidget(QtWidgets.QLabel("α"))
                table2 = Tabla(*args, **kw)
                lyt2.addWidget(table2)
                kij, aij = k
                table1.setData(kij)
                table2.setData(aij)
                table1.resizeColumnsToContents()
                table2.resizeColumnsToContents()

            else:
                table1.setData(k)
                table1.resizeColumnsToContents()

            self.stacked.addWidget(widget)

        self.eleccion.currentIndexChanged.connect(self.stacked.setCurrentIndex)
        button = QtWidgets.QDialogButtonBox(
            QtWidgets.QDialogButtonBox.StandardButton.Cancel | QtWidgets.QDialogButtonBox.StandardButton.Ok)
        button.accepted.connect(self.accept)
        button.rejected.connect(self.reject)
        lyt.addWidget(button, 3, 1, 1, 3)

        self.eleccion.setCurrentIndex(EoSIndex)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = Ui_BIP([38, 44, 45], 4)
    Dialog.show()
    sys.exit(app.exec())


import pandas as pd
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn import preprocessing

sns.set()

raw_data = pd.read_csv('./Mall_Customers.csv')

print(raw_data.head())
print("----------------description---------------")
print(raw_data.describe())

data = raw_data.copy()

data['Gender'] = data['Gender'].map({'Male': 0, 'Female': 1})

print(data.isnull().sum())

features = data[['Gender', 'Age', 'Annual Income (k$)', 'Spending Score (1-100)']].values

featuresScaled = preprocessing.scale(features)

# Elbow Method
WCSS = []
for i in range(1, 10):
    kmeans = KMeans(n_clusters=i)
    kmeans.fit(featuresScaled)
    WCSS.append(kmeans.inertia_)

plt.plot(range(1, 10), WCSS, marker='o', linestyle='--')
plt.title('Elbow Method')
plt.xlabel('Number of Clusters')
plt.ylabel('WCSS')
plt.show()

numOfClusters = 5

kmeans = KMeans(numOfClusters)
clusters = kmeans.fit_predict(featuresScaled)

data['Cluster'] = clusters

clusterSummary = data.groupby('Cluster').mean()
print(clusterSummary)

plt.scatter(data['Annual Income (k$)'], data['Spending Score (1-100)'], c=data['Cluster'], cmap='rainbow')
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)')
plt.title('Customer Segmentation')
plt.show()


from typing import TYPE_CHECKING

from azure.mgmt.core import ARMPipelineClient
from msrest import Deserializer, Serializer

if TYPE_CHECKING:
    # pylint: disable=unused-import,ungrouped-imports
    from typing import Any, Optional

    from azure.core.credentials import TokenCredential
    from azure.core.pipeline.transport import HttpRequest, HttpResponse

from ._configuration import VMwareCloudSimpleConfiguration
from .operations import Operations
from .operations import DedicatedCloudNodesOperations
from .operations import DedicatedCloudServicesOperations
from .operations import SkusAvailabilityOperations
from .operations import PrivateCloudsOperations
from .operations import CustomizationPoliciesOperations
from .operations import ResourcePoolsOperations
from .operations import VirtualMachineTemplatesOperations
from .operations import VirtualNetworksOperations
from .operations import UsagesOperations
from .operations import VirtualMachinesOperations
from . import models

class VMwareCloudSimple(object):
    """Description of the new service.

    :ivar operations: Operations operations
    :vartype operations: azure.mgmt.vmwarecloudsimple.operations.Operations
    :ivar dedicated_cloud_nodes: DedicatedCloudNodesOperations operations
    :vartype dedicated_cloud_nodes: azure.mgmt.vmwarecloudsimple.operations.DedicatedCloudNodesOperations
    :ivar dedicated_cloud_services: DedicatedCloudServicesOperations operations
    :vartype dedicated_cloud_services: azure.mgmt.vmwarecloudsimple.operations.DedicatedCloudServicesOperations
    :ivar skus_availability: SkusAvailabilityOperations operations
    :vartype skus_availability: azure.mgmt.vmwarecloudsimple.operations.SkusAvailabilityOperations
    :ivar private_clouds: PrivateCloudsOperations operations
    :vartype private_clouds: azure.mgmt.vmwarecloudsimple.operations.PrivateCloudsOperations
    :ivar customization_policies: CustomizationPoliciesOperations operations
    :vartype customization_policies: azure.mgmt.vmwarecloudsimple.operations.CustomizationPoliciesOperations
    :ivar resource_pools: ResourcePoolsOperations operations
    :vartype resource_pools: azure.mgmt.vmwarecloudsimple.operations.ResourcePoolsOperations
    :ivar virtual_machine_templates: VirtualMachineTemplatesOperations operations
    :vartype virtual_machine_templates: azure.mgmt.vmwarecloudsimple.operations.VirtualMachineTemplatesOperations
    :ivar virtual_networks: VirtualNetworksOperations operations
    :vartype virtual_networks: azure.mgmt.vmwarecloudsimple.operations.VirtualNetworksOperations
    :ivar usages: UsagesOperations operations
    :vartype usages: azure.mgmt.vmwarecloudsimple.operations.UsagesOperations
    :ivar virtual_machines: VirtualMachinesOperations operations
    :vartype virtual_machines: azure.mgmt.vmwarecloudsimple.operations.VirtualMachinesOperations
    :param credential: Credential needed for the client to connect to Azure.
    :type credential: ~azure.core.credentials.TokenCredential
    :param subscription_id: The subscription ID.
    :type subscription_id: str
    :param referer: referer url.
    :type referer: str
    :param str base_url: Service URL
    :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present.
    """

    def __init__(
        self,
        credential,  # type: "TokenCredential"
        subscription_id,  # type: str
        referer,  # type: str
        base_url=None,  # type: Optional[str]
        **kwargs  # type: Any
    ):
        # type: (...) -> None
        if not base_url:
            base_url = 'https://management.azure.com'
        self._config = VMwareCloudSimpleConfiguration(credential, subscription_id, referer, **kwargs)
        self._client = ARMPipelineClient(base_url=base_url, config=self._config, **kwargs)

        client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)}
        self._serialize = Serializer(client_models)
        self._serialize.client_side_validation = False
        self._deserialize = Deserializer(client_models)

        self.operations = Operations(
            self._client, self._config, self._serialize, self._deserialize)
        self.dedicated_cloud_nodes = DedicatedCloudNodesOperations(
            self._client, self._config, self._serialize, self._deserialize)
        self.dedicated_cloud_services = DedicatedCloudServicesOperations(
            self._client, self._config, self._serialize, self._deserialize)
        self.skus_availability = SkusAvailabilityOperations(
            self._client, self._config, self._serialize, self._deserialize)
        self.private_clouds = PrivateCloudsOperations(
            self._client, self._config, self._serialize, self._deserialize)
        self.customization_policies = CustomizationPoliciesOperations(
            self._client, self._config, self._serialize, self._deserialize)
        self.resource_pools = ResourcePoolsOperations(
            self._client, self._config, self._serialize, self._deserialize)
        self.virtual_machine_templates = VirtualMachineTemplatesOperations(
            self._client, self._config, self._serialize, self._deserialize)
        self.virtual_networks = VirtualNetworksOperations(
            self._client, self._config, self._serialize, self._deserialize)
        self.usages = UsagesOperations(
            self._client, self._config, self._serialize, self._deserialize)
        self.virtual_machines = VirtualMachinesOperations(
            self._client, self._config, self._serialize, self._deserialize)

    def _send_request(self, http_request, **kwargs):
        # type: (HttpRequest, Any) -> HttpResponse
        """Runs the network request through the client's chained policies.

        :param http_request: The network request you want to make. Required.
        :type http_request: ~azure.core.pipeline.transport.HttpRequest
        :keyword bool stream: Whether the response payload will be streamed. Defaults to True.
        :return: The response of your network call. Does not do error handling on your response.
        :rtype: ~azure.core.pipeline.transport.HttpResponse
        """
        path_format_arguments = {
            'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str'),
        }
        http_request.url = self._client.format_url(http_request.url, **path_format_arguments)
        stream = kwargs.pop("stream", True)
        pipeline_response = self._client._pipeline.run(http_request, stream=stream, **kwargs)
        return pipeline_response.http_response

    def close(self):
        # type: () -> None
        self._client.close()

    def __enter__(self):
        # type: () -> VMwareCloudSimple
        self._client.__enter__()
        return self

    def __exit__(self, *exc_details):
        # type: (Any) -> None
        self._client.__exit__(*exc_details)


import torch
import torch.nn as nn
import os

from torch.utils import data
from torch.utils.data import DataLoader
from torchvision import transforms
from torch.optim.lr_scheduler import StepLR, CosineAnnealingLR
from tqdm import tqdm

from cars_attributes.data.dataload import download_dataset
from cars_attributes.data.dataset import Dataset
from cars_attributes.MobileNetV2 import mobilenet_v2
from yolov5.demo import Yolov5Detect
from cars_attributes.WarmUpLR import WarmUpLR
from endtoend import YOLOv5_MobileNetV2

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using {device} device")

train_list = "./car_recognition/cars_annos/xin_train.json"
val_list = "./car_recognition/cars_annos/xin_test.json"

# Hyperparameters
batch_size = 16
epochs = 10
learning_rate = 0.001
max_epoch = 30

# Save the model
def save_model(model, save_path, name, iter_cnt):
    if not os.path.exists(save_path):
        os.makedirs(save_path)
    save_name = os.path.join(save_path, name + '_' + str(iter_cnt) + '.pth')
    torch.save(model.state_dict(), save_name)
    return save_name

# Train and test the model
def train(epoch, net, trainloader, optimizer, criterion_detector, criterion_classifier, warmup_scheduler):
    print('\nEpoch: %d' % epoch)
    net.train()
    train_loss = 0
    correct_color = 0
    total_color = 0
    batch_id = 0
    for (inputs, targets_detector, targets_car, targets_type, targets_color) in tqdm(trainloader):
        if epoch < 2:
            warmup_scheduler.step()
            warm_lr = warmup_scheduler.get_lr()
            print("warm_lr:%s" % warm_lr)
        inputs, targets_detector, targets_car, targets_type, targets_color = inputs.to(device), targets_detector.to(device), targets_color.to(device), targets_car.to(device), targets_type.to(device)
        optimizer.zero_grad()
        outputs_detector, outputs_color, outputs_car, outputs_type = net(inputs)

        # Calculate detection loss
        loss_detector = criterion_detector(outputs_detector, targets_detector.long())

        # Calculate classification loss
        loss_color = criterion_classifier(outputs_color, targets_color.long())
        loss_car = criterion_classifier(outputs_car, targets_car.long())
        loss_type = criterion_classifier(outputs_type, targets_type.long())

        # Combine the detection loss and classification loss
        loss = loss_detector + loss_color + loss_car + loss_type
        loss.backward()
        optimizer.step()

        train_loss += loss.item()

        _, predicted_color = outputs_color.max(1)
        total_color += targets_color.size(0)
        correct_color += predicted_color.eq(targets_color.long()).sum().item()

        iters = epoch * len(trainloader) + batch_id
        if iters % 10 == 0:
            acc = predicted_color.eq(targets_color.long()).sum().item()*1.0/targets_color.shape[0]
            los = loss*1.0/targets_color.shape[0]
            #tensor_board.visual_loss("train_loss", los, iters)
            #tensor_board.visual_acc("train_acc", acc, iters)
        batch_id += 1

    # Test
def test(epoch, net, valloader, criterion_detector, criterion_classifier):
    net.eval()
    test_loss = 0
    correct_detector = 0
    correct_color = 0
    correct_car = 0
    correct_type = 0
    total_detector = 0
    total_color = 0
    total_car = 0
    total_type = 0
    with torch.no_grad():
         for batch_idx, (inputs, targets_detector, targets_car, targets_type, targets_color) in enumerate(valloader):
            inputs, targets_detector, targets_car, targets_type, targets_color = inputs.to(device), targets_detector.to(device), targets_color.to(device), targets_car.to(device), targets_type.to(device)
            outputs_detector, outputs_color, outputs_car, outputs_type = net(inputs)

            loss_detector = criterion_detector(outputs_detector, targets_detector.long())
            loss_color = criterion_classifier(outputs_color, targets_color.long())
            loss_car = criterion_classifier(outputs_car, targets_car.long())
            loss_type = criterion_classifier(outputs_type, targets_type.long())

            test_loss += loss_detector.item()
            test_loss += loss_color.item()
            test_loss += loss_car.item()
            test_loss += loss_type.item()

            _, predicted_detector = outputs_detector.max(1)
            _, predicted_color = outputs_color.max(1)
            _, predicted_car = outputs_car.max(1)
            _, predicted_type = outputs_type.max(1)

            total_detector += targets_detector.size(0)
            correct_detector += predicted_detector.eq(targets_detector.long()).sum().item()

            total_color += targets_color.size(0)
            correct_color += predicted_color.eq(targets_color.long()).sum().item()

            total_car += targets_car.size(0)
            correct_car += predicted_car.eq(targets_car.long()).sum().item()

            total_type += targets_type.size(0)
            correct_type += predicted_type.eq(targets_type.long()).sum().item()

    acc_detector = 1.*correct_detector/total_detector
    acc_color = 1.*correct_color/total_color
    acc_car = 1.*correct_car/total_car
    acc_type = 1.*correct_type/total_type

    print("Acc_detector in the val_dataset:%s" % acc_detector)
    print("Acc_color in the val_dataset:%s" % acc_color)
    print("Acc_car in the val_dataset:%s" % acc_car)
    print("Acc_type in the val_dataset:%s" % acc_type)

    if epoch % 10 == 0:
        save_model(net, "./checkpoint/", "EndToEnd", epoch)

if __name__ == "__main__":

    # Model and optimizer]
    net = YOLOv5_MobileNetV2().to(device)

    dataset_name = "custom-stanford-cars-dataset"
    save_path = "./car_recognition/dataset"

    #download_dataset(dataset_name, save_path)

    train_dataset = Dataset(train_list, phase='train')
    val_dataset = Dataset(val_list, phase='val')
    trainloader = data.DataLoader(train_dataset,
                                  batch_size=64,
                                  shuffle=True,
                                  num_workers=4)
    valloader = data.DataLoader(val_dataset,
                                  batch_size=8,
                                  shuffle=True,
                                  num_workers=4)
    # train_dataset = CarDataset("train.txt", transform)
    # train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)

    # test_dataset = CarDataset("test.txt", transform)
    # test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=True)
    # Loss function
    criterion_detector = nn.BCEWithLogitsLoss()
    criterion_classifier = nn.CrossEntropyLoss()
    optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate)
    warmup_epoch = 2
    scheduler = CosineAnnealingLR(optimizer, 30 - warmup_epoch)

    iter_per_epoch = len(train_dataset)
    warmup_scheduler = WarmUpLR(optimizer, iter_per_epoch * warmup_epoch)

    #tensor_board = TensorBoard(64, 3, 256, 256)
    #tensor_board.visual_model(net)
    for epoch in range(1, max_epoch+1):
        if epoch >= warmup_epoch:
            scheduler.step()
            learn_rate = scheduler.get_lr()[0]
            print("Learn_rate:%s" % learn_rate)
        test(epoch, net, valloader, criterion_detector, criterion_classifier)
        train(epoch, net, trainloader, optimizer, criterion_detector, criterion_classifier, warmup_scheduler)

# # Define object detection loss function
# class DetectionLoss(nn.Module):
#     def __init__(self, weight=1.0):
#         super(DetectionLoss, self).__init__()
#         self.weight = weight
#         self.bce_loss = nn.BCEWithLogitsLoss()
#         self.mse_loss = nn.MSELoss()

#     def forward(self, pred, target):
#         # Calculate objectness loss
#         objectness_loss = self.bce_loss(pred[..., 0], target[..., 0])

#         # Calculate localization loss
#         loc_loss = self.mse_loss(pred[..., 1:5], target[..., 1:5])

#         # Calculate classification loss
#         class_loss = self.bce_loss(pred[..., 5:], target[..., 5:])

#         # Combine the three losses
#         loss = objectness_loss + self.weight * loc_loss + class_loss
#         return loss

# criterion_detector = DetectionLoss()


import sys
import os, errno
from PIL import Image, ImageDraw, ImageOps
import random
from math import sin, cos, fabs, pi, ceil, floor
import numpy as np

def initParam():
	global thicknessCircle, diameter, x1Circle, y1Circle, sizePlus, x1Plus, y1Plus, y2Plus, x2Plus, thicknessPlus, rotationPlus, arcWidth, arcHeight, thicknessWaves, leftCorner, rotationWave, sizeX, sizeY, side, thicknessSquare, rotationSquare, x1Square, y1Square, linelength, newx, newy, linewidth, rotationStar

	'''
	#parameters for Circle
	'''
	thicknessCircle = 3										#Thickess of the circle
	diameter = 10											#Diameter fo the circle
	x1Circle=int(random.randint(0,25-diameter))				#Top left corner of the circle's X value
	y1Circle=int(random.randint(0,25-diameter))				#Top left corner of the circle's Y value
	'''
	'''

	'''
	#parameters for Plus Symbol
	'''
	sizePlus = 20											#width and height of Plus symbol
	x1Plus = random.randint(13, 38 - sizePlus)				#X coordinate of Top left corner of Plus symbol, before getting cropped
	y1Plus = random.randint(13, 38 - sizePlus)				#Y coordinate of Top left corner of Plus symbol, before getting cropped
	y2Plus = y1Plus + sizePlus								#Do not tweak
	x2Plus = x1Plus + sizePlus								#Do not tweak

	thicknessPlus = 3										#Thickness of Plus

	rotationPlus = 45										#Angle to rotate plus
	'''
	'''

	'''
	Parameters for wavy lines
	'''
	# Define the dimensions of the png image file before cropping it
	sizeX = 51  											#Size before cropping - Do not tweak
	sizeY = 51												#Size before cropping - Do not tweak

	#vary the size of the wavy lines (Total height of a curvy wave is arcHeight*3)
	arcWidth = 6    										#Width of arc
	arcHeight = 6   										#Height of Arc/3 (Value of 6 indicates height of 18)

	#vary the thickness of the symbol
	thicknessWaves = 1										#Thickness of Arc/3

	#vary the position of the symbol
	leftCorner = random.randint(13,sizeX-33)				#Left Corner X Coodinate

	#vary the rotation angle of the symbol
	rotationWave = random.randint(-90, 90)					#Degree of rotation for the wave
	'''
	'''

	'''
	Parameters for Square
	'''
	side = 10												#Side of Square
	thicknessSquare = 3										#Thickness of square_draw
	rotationSquare = random.randint(0, 360)					#Angle of rotation of square

	x1Square = int(random.randint(ceil(13), ceil(25-side**(1/2)))) 		#This value should be between 13 and 25-sqrt(side)
	y1Square = int(random.randint(ceil(13), ceil(25-side**(1/2)))) 		#This value should be between 13 and 25-sqrt(side)
	'''
	'''

	'''
	Parameters for Star
	'''
	linelength = random.randint(5, 25)						#provide the chord length of the star
	newx =	random.randint(ceil(linelength/2), ceil(25-linelength/2))	#Offset x position for drawing the star
	newy =  random.randint(0, 25-linelength)				#Offset y position for drawing the star
	linewidth = 3											#Thickness of the lines
	rotationStar = random.randint(-90, 90)
	'''
	'''

#Tweakable parameters
numberOfStrayMarks = 2
thicknessOfStrayMarks = 1

if(len(sys.argv)) != 3:
	print ("Please supply the correct arguments")
	raise SystemExit(1)

folder_name = sys.argv[1]
num_examples = sys.argv[2]

try:
    os.makedirs(folder_name)
except OSError as e:
    if e.errno != errno.EEXIST:
        raise

#draw Stray Marks
def drawStrayMarks(numberOfStrayMarks, thicknessOfStrayMarks, draw):
	for x in range(0, numberOfStrayMarks):
			startPositionX = random.randint(0, 25-thicknessOfStrayMarks)
			startPositionY = random.randint(0, 25-thicknessOfStrayMarks)
			draw.ellipse([(startPositionX, startPositionY), (startPositionX+thicknessOfStrayMarks, startPositionY+thicknessOfStrayMarks)], None, 'black')

#draw Circles
for count in range(0, int(num_examples)):

	# size of image
	canvas = (25, 25)

	# scale ration
	scale = 1
	thumb = canvas[0]/scale, canvas[1]/scale

	initParam()

	y2Circle=diameter+y1Circle
	x2Circle=diameter+x1Circle

	circle_img = Image.new('L', ( 25 , 25 ), "white")
	circle_draw = ImageDraw.Draw(circle_img)

	for thick in range(0,thicknessCircle):
		xy = [(x1Circle,y1Circle),(x2Circle,y2Circle)]
		circle_draw.ellipse(xy, None, "black")
		x1Circle = x1Circle+1
		y1Circle = y1Circle+1
		x2Circle = x2Circle-1
		y2Circle = y2Circle-1

	drawStrayMarks(numberOfStrayMarks, thicknessOfStrayMarks, circle_draw)		#draw stray marks

	# make thumbnail
	circle_img.thumbnail(thumb)

	# save image
	circle_img.save(folder_name+'/' + str(count+1) + '_O' + '.png')

#P - for Plus symbol
for count in range(0, int(num_examples)):

	# size of image
	canvas = (25, 25)

	# scale ration
	scale = 1
	thumb = canvas[0]/scale, canvas[1]/scale

	initParam()

	cross_img = Image.new('L', ( 51 , 51 ), "white")
	cross_draw = ImageDraw.Draw(cross_img)
	xy = [ x1Plus , y1Plus + sizePlus/2 , x2Plus, y1Plus +sizePlus/2]
	cross_draw.line( xy, 0 , thicknessPlus)

	xy = [ x1Plus+sizePlus/2 , y1Plus, x1Plus+sizePlus/2 , y2Plus 	]
	cross_draw.line( xy, 0 , thicknessPlus)

	image = cross_img.rotate(rotationPlus)
	image = ImageOps.crop(image, 13)

	cross_draw = ImageDraw.Draw(image)
	drawStrayMarks(numberOfStrayMarks, thicknessOfStrayMarks, cross_draw)		#draw stray marks
	# make thumbnail
	image.thumbnail(thumb)

	# save image
	image.save(folder_name+'/' + str(count+1) + '_P' + '.png')

#W - for Waves
for count in range(0, int(num_examples)):

	# size of image
	canvas = (25, 25)

	# scale ration
	scale = 1
	thumb = canvas[0]/scale, canvas[1]/scale

	initParam()

	#create a new blank image
	image = Image.new('L', (sizeX, sizeY), 'white')
	draw = ImageDraw.Draw(image)

	for x in range(0, thicknessWaves):
		draw.arc((leftCorner, leftCorner+arcHeight, leftCorner+arcWidth, leftCorner+arcHeight*2), 270, 90, 'black')  # draw an arc in black
		draw.arc((leftCorner, leftCorner, leftCorner+arcWidth, leftCorner+arcHeight), 90, 270, 'black')  # draw an arc in black
		draw.arc((leftCorner, leftCorner+arcHeight*2, leftCorner+arcWidth, leftCorner+arcHeight*3), 90, 270, 'black')  # draw an arc in black

		draw.arc((leftCorner+arcWidth, leftCorner+arcHeight, leftCorner+arcWidth*2, leftCorner+arcHeight*2), 270, 90, 'black')  # draw an arc in black
		draw.arc((leftCorner+arcWidth, leftCorner, leftCorner+arcWidth*2, leftCorner+arcHeight), 90, 270, 'black')  # draw an arc in black
		draw.arc((leftCorner+arcWidth, leftCorner+arcHeight*2, leftCorner+arcWidth*2, leftCorner+arcHeight*3), 90, 270, 'black')  # draw an arc in black

		draw.arc((leftCorner+arcWidth*2, leftCorner+arcHeight, leftCorner+arcWidth*3, leftCorner+arcHeight*2), 270, 90, 'black')  # draw an arc in black
		draw.arc((leftCorner+arcWidth*2, leftCorner, leftCorner+arcWidth*3, leftCorner+arcHeight), 90, 270, 'black')  # draw an arc in black
		draw.arc((leftCorner+arcWidth*2, leftCorner+arcHeight*2, leftCorner+arcWidth*3, leftCorner+arcHeight*3), 90, 270, 'black')  # draw an arc in black
		leftCorner+=1

	image = image.rotate(rotationWave)
	image = ImageOps.crop(image, 13)

	draw = ImageDraw.Draw(image)

	"Till here"
	drawStrayMarks(numberOfStrayMarks, thicknessOfStrayMarks, draw)		#draw stray marks

	# make thumbnail
	image.thumbnail(thumb)

	# save image
	image.save(folder_name+'/' + str(count+1) + '_W' + '.png')

#Q - for Squares
for count in range(0, int(num_examples)):

	# size of image
	canvas = (25, 25)

	# scale ration
	scale = 1
	thumb = canvas[0]/scale, canvas[1]/scale

	initParam()
	"Definition here"

	x2Square = side+x1Square
	y2Square = side+y1Square

	square_img = Image.new('L', (51, 51), "white")
	square_draw = ImageDraw.Draw(square_img)

	for thick in range(0, thicknessSquare):
		xy = [x1Square, y1Square, x2Square, y2Square]
		square_draw.rectangle(xy, "white", "black")
		x1Square = x1Square+1
		y1Square = y1Square+1
		x2Square = x2Square-1
		y2Square = y2Square-1

	square_img = square_img.rotate(rotationSquare)
	square_img = ImageOps.crop(square_img, 13)
	img = ImageDraw.Draw(square_img)

	"Till here"
	drawStrayMarks(numberOfStrayMarks, thicknessOfStrayMarks, img)		#draw stray marks
	# make thumbnail
	square_img.thumbnail(thumb)

	# save image
	square_img.save(folder_name+'/' + str(count+1) + '_Q' + '.png')

#S - for Stars`
for count in range(0, int(num_examples)):

	# size of image
	canvas = (25, 25)

	# scale ration
	scale = 1
	thumb = canvas[0]/scale, canvas[1]/scale

	"Definition here"
	im = Image.new('L', (51, 51), 'white')
	draw = ImageDraw.Draw(im)

	initParam()

	newx = newx+13
	newy = newy+13

	#Different parameters of the pentagram
	a = linelength/1.618
	b = linelength - a
	c = a - b

	#calculate points for the star and join them with each other
	pointA = [newx-b*(sin(18*pi/180)), newy+b*cos(18*pi/180)]
	draw.line((newx, newy, pointA[0], pointA[1]), fill=0, width = linewidth)

	pointB = [newx-a*cos(36*pi/180), newy+a*sin(36*pi/180)]
	draw.line((pointA[0], pointA[1], pointB[0], pointB[1]), fill=0, width = linewidth)

	pointC = [newx-a*sin(18*pi/180), newy+a*cos(18*pi/180)]
	draw.line((pointC[0], pointC[1], pointB[0], pointB[1]), fill=0, width = linewidth)

	pointD = [newx-linelength*sin(18*pi/180), newy+linelength*cos(18*pi/180)]
	draw.line((pointD[0], pointD[1], pointC[0], pointC[1]), fill=0, width = linewidth)

	pointE = [newx, newy+linelength-b*sin(36*pi/180)]
	draw.line((pointE[0], pointE[1], pointD[0], pointD[1]), fill=0, width = linewidth)

	pointF = [newx+b*cos(36*pi/180), newy+linelength*cos(18*pi/180)]
	draw.line((pointF[0], pointF[1], pointE[0], pointE[1]), fill=0, width = linewidth)

	pointG = [newx+a*sin(18*pi/180), newy+a*cos(18*pi/180)]
	draw.line((pointG[0], pointG[1], pointF[0], pointF[1]), fill=0, width = linewidth)

	pointH = [newx+a*cos(36*pi/180), newy+a*sin(36*pi/180)]
	draw.line((pointH[0], pointH[1], pointG[0], pointG[1]), fill=0, width = linewidth)

	pointI = [newx+b*(sin(18*pi/180)), newy+b*cos(18*pi/180)]
	draw.line((pointI[0], pointI[1], pointH[0], pointH[1]), fill=0, width = linewidth)

	draw.line((pointI[0], pointI[1], newx, newy), fill=0, width = linewidth)
	"Till here"
	im = im.rotate(rotationStar)
	im = ImageOps.crop(im, 13)

	draw = ImageDraw.Draw(im)
	drawStrayMarks(numberOfStrayMarks, thicknessOfStrayMarks, draw)		#draw stray marks

	# make thumbnail
	im.thumbnail(thumb)

	# save image
	im.save(folder_name+'/' + str(count+1) + '_S' + '.png')


import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
import pickle

# Load the dataset
data = pd.read_csv('/Users/prabhjeetbains/Desktop/BCIT/Data sets/SpotifyFeatures.csv')
pd.set_option('display.max_columns', None)
pd.set_option('display.width', 1000)

# Define the features and target variable
X = data[['danceability', 'energy', 'acousticness', 'instrumentalness', 'valence']]
y = data['popularity']

# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Create the logistic regression model
model = LogisticRegression()

# Train the model using the training data
model.fit(X_train, y_train)

# Save the model to a pickle file
with open('spotify_model.pkl', 'wb') as file:
    pickle.dump(model, file)

# Load the model from the pickle file and make predictions
with open('spotify_model.pkl', 'rb') as file:
    model = pickle.load(file)

user_input = {'genre': 'Rap', 'danceability': 4, 'energy': 4, 'acousticness': 2, 'instrumentalness': 2, 'valence': 3}

# Convert user input to a numpy array
user_input_array = pd.DataFrame(user_input, index=[0])[['danceability', 'energy', 'acousticness', 'instrumentalness', 'valence']].to_numpy()

# Reshape user input to match the expected shape of the model input
user_input_array = user_input_array.reshape(1, -1)

# Make predictions using the model
prediction = model.predict_proba(user_input_array)[0]

# Print the top 3 songs based on the predicted probability
top_songs_indices = prediction.argsort()[::-1][:10]

# Print the top 3 songs that match the user's preferred genre
preferred_genre = user_input['genre']
matches_genre = data[data['genre'] == preferred_genre].iloc[top_songs_indices][['track_name', 'artist_name', 'genre']]
print(f'Top songs that match the genre "{preferred_genre}":')
print(matches_genre)
print(type(matches_genre))


import psutil
import platform
import pyfiglet
from termcolor2 import colored
from datetime import datetime
#Sec-1
def get_size(bytes, suffix="B"):
    factor = 1024
    for unit in ["", "K", "M", "G", "T", "P"]:
        if bytes < factor:
            return f"{bytes:.2f}{unit}{suffix}"
        bytes /= factor
#Sec-2

message="pouria"
ascii_art=pyfiglet.figlet_format(message)
ascii_art=colored(ascii_art,color="green")
print(ascii_art)
result = pyfiglet.figlet_format("resource info", font = "digital" )
print(result)
print("="*80)

def cpu():
    print("CPU Usage Per Core:")
    for i, percentage in enumerate(psutil.cpu_percent(percpu=True, interval=1)):
        print(f"Core {i}: {percentage}%")
    print(f"Total CPU Usage: {psutil.cpu_percent()}%")
    input("Press Enter to continue...")

def memory():
    svmem = psutil.virtual_memory()
    print(f"Total: {get_size(svmem.total)}")
    print(f"Available: {get_size(svmem.available)}")
    print(f"Used: {get_size(svmem.used)}")
    input("Press Enter to continue...")

def disk():
    partitions = psutil.disk_partitions()
    for partition in partitions:
        print(f"=== Device: {partition.device} ===")
        print(f"  Mountpoint: {partition.mountpoint}")
        print(f"  File system type: {partition.fstype}")
        try:
            partition_usage = psutil.disk_usage(partition.mountpoint)
        except PermissionError:
            continue
        print(f"  Total Size: {get_size(partition_usage.total)}")
        print(f"  Used: {get_size(partition_usage.used)}")
        print(f"  Free: {get_size(partition_usage.free)}")
        print(f"  Percentage: {partition_usage.percent}%")
    input("Press Enter to continue...")
def menu():
    print("please Enter your number:")
    print("[1] CPU info")
    print("[2] MEMORY info")
    print("[3] DISK info")
    print("[4] ACCOUNT NAME")
    result2 = colored("Choose a menu option, or press 0 to Exit:",color = "blue" )
    print(result2)

while True:
    menu()
    number=int(input())

    if number== 1 :
        cpu()
        print("="*80)

    elif number== 2:
        memory()
        print("="*80)

    elif number== 3:
        disk()
        print("="*80)

    elif number== 4:
        uname = platform.uname()
        print(f"User Account: {uname.node}")
        input("Press Enter to continue...")
        print("="*80)

    elif number>4 or number<0:
        result3 = colored("You enter a wrong number, Choose a another number, or press 0 to Exit:",color = "red" )
        print(result3)
        print("="*80)

    elif number== 0:
        exit()


#!/usr/bin/env python3
'''
This script contains functions which access the MxToolBox API and get blacklist results for
IP addresses. to use against aws before attaching EIP's to instances
'''

import json
import requests
import argparse
from configparser import ConfigParser
from pprint import pprint

## API Configuration Data
## Parses .mxtbx file for API Key
parser = ConfigParser()
parser.read('.mxtbx')
API_KEY = parser.get('mxtbx', 'key')
API_URL = 'https://api.mxtoolbox.com/api/v1'

parser = argparse.ArgumentParser()
parser.add_argument('-l','--list', nargs='+', type=str, help='IP Address or Addressees space sparated', required=True)
args = parser.parse_args()
ips = args.list

def get_blacklist_results(ip):
    '''
    Utilizes the MXToolBox API to do a Blacklist lookup on the supplied ip
    address.

    Args:
        ip (str): IP address to perform blacklist check on.

    Returns:
        json: Returns a json dictonary
    '''
    http_payload = {'Authorization': API_KEY }
    result = requests.get('{}/Lookup/blacklist/{}'.format(API_URL, ip), params=http_payload)
    result.raise_for_status()
    jresult = json.loads(result.text)
    return jresult

def main():
    for ip in ips:
      blacklist_results = get_blacklist_results(ip)
      if blacklist_results['Failed']:
        #pprint(blacklist_results['Failed'])
        print("{}\t Failed due to results".format(ip))
      else:
        print("{}\t IP is clean".format(ip))
        return 0

main()