from datetime import datetime
import requests
from bs4 import BeautifulSoup
import itertools
import pymorphy2
import re

morph = pymorphy2.MorphAnalyzer()
state = []
nully = []
news = [[]]
d = {}

def get_html(url):
    response = requests.get(url)
    return response.text

def get_all_links(html): #, state, news):
    soup = BeautifulSoup(html, 'lxml')

    title = soup.find('h1')
    aftertitle = soup.find('div', class_ = 'preview-text')#.find_all('div', class_ = 'news-item')
    text = soup.find('div', class_ ='detail-text')

    apaftertitle = str(aftertitle)[35:-16]
    aptitle = str(title)[4:-6]

    before_aptext = str(str(title) + ' ' + str(aptitle) + ' ' + str(text))

    s = set()
    new = []

    str1 = before_aptext.split()
    for i in str1: #data[0]:
        p = morph.parse(i)[0]
        l = p.tag.POS
        p = p.normal_form
        result = re.sub(r',' , '', p)
        result = re.sub(r'»', '', result)
        result = re.sub(r'«', '', result)
        result = re.sub(r'
', '', result)
        result = re.sub(r'-', '', result)
        result = re.sub(r'–', '', result)
        result = re.sub(r'', '', result)
        result = re.sub(r'', '', result)
        result = re.sub(r'<div', '', result)
        result = re.sub(r'
', '', result)
        #result = re.sub(r'.', '', result)
        if (result.find('.') != -1):
            result = result[:-1]
        if (result.find(':') != -1):
            result = result[:-1]
        if (result.find('?') != -1):
            result = result[:-1]
        #print(result.find('.'))

        if ((l == 'NOUN') or (l == None)):
        #if ((l == 'VERB') or (l == None) or (l == 'INFN') or (l == 'PRTS') or (l == 'PRTF') or (l == 'GRND')):
        #if (l == 'ADJF' or l == 'ADJS' or l == 'ADVB' or l == None):
            if (result != '' and result != ' ' and result not in s):
                new.append(result)
                s.add(result)

    pairs = list(itertools.combinations(new, 2))
    for i in range(len(pairs)):
        if d.get(pairs[i]) == None:
            d[pairs[i]] = 1
        else:
            d[pairs[i]] += 1

def main():
    page = 'https://gazeta-n1.ru/news/' # 60143/ - 73269/

    for i in range(60143, 73269):#, 230):
        print(i - 60142, end='\n')
        url = page + str(i) + '/'
        all_links = get_all_links(get_html(url)) # state, news)
        print(i)

    my_file = open("gazeta_n1_pairs.txt", "a")
    for w in sorted(d, key=d.get, reverse=True):
        #print(w[0], ' ', d[w])
        if d[w] > 100:
            print("yahoo!")
            my_file.write(str(max(w[0], w[1])))
            my_file.write(' ')
            my_file.write(str(min(w[1], w[0])))
            my_file.write(' ')
            my_file.write(str(d[w]))
            my_file.write('\n')

    my_file.close()

if __name__ == '__main__':
    main()


from django.urls import path, include

from .apis import (
    UserSessionLoginApi,
    UserSessionLogoutApi,

    UserJwtLoginApi,
    UserJwtLogoutApi,

    UserMeApi,
)

urlpatterns = [
    path(
        'session/',
        include(([
            path(
                'login/',
                UserSessionLoginApi.as_view(),
                name='login'
            ),
            path(
                'logout/',
                UserSessionLogoutApi.as_view(),
                name='logout'
            )

        ], "session"))
    ),
    path(
        'jwt/',
        include(([
            path(
                "login/",
                UserJwtLoginApi.as_view(),
                name="login"
            ),
            path(
                "logout/",
                UserJwtLogoutApi.as_view(),
                name="logout"
            )
        ], "jwt"))
    ),
    path(
        'me/',
        UserMeApi.as_view(),
        name='me'
    )
]


#------------------------------------------------------------------------------
# Imports
#------------------------------------------------------------------------------
import os
os.chdir('C:/Users/GarlefHupfer/OneDrive - ipri-institute.com/H/02-Projekte/40180003_IoC/03_Projektergebnisse/AP 9.3 Gesamtwirtschaftlichkeitsanalyse/3 IoC-Ontologie/python/')

import dash
import dash_bootstrap_components as dbc
from dash import html, dcc
import dash_daq as daq
import plotly.express as px
import datetime
import pandas
import plotly.graph_objects as go
from pm4py.objects.petri_net.importer import importer as pnml_importer
import graphviz
import plotly.figure_factory as pff
from dash.dependencies import Input, Output

#------------------------------------------------------------------------------
# Main Project Variables
#------------------------------------------------------------------------------
project_name = 'Betonieren'
project_path = 'testing/project/'
cost_plan_path = 'testing/project2/predicted_costs.csv'
actual_costs_path = 'testing/project2/actual_costs.csv'

curr_date = datetime.datetime(2022, 2, 10, 9, 0) #datetime.datetime.now()

# for cost diplay: use costs.sum(axis=1)

#------------------------------------------------------------------------------
# Initiate Dash App
#------------------------------------------------------------------------------
external_stylesheets = [dbc.themes.BOOTSTRAP]
app = dash.Dash(external_stylesheets=external_stylesheets, title='Projektübersicht')

for f in [f for f in os.listdir(app.config.assets_folder)]:
    os.remove(os.path.join(app.config.assets_folder, f))

#------------------------------------------------------------------------------
# Content
#------------------------------------------------------------------------------
app.layout = html.Div([
     dbc.Row([
         html.H1('Projektübersicht - ' + project_name, style={
             "paddingBottom": "10px"
             })
         ]),
     dbc.Row([
         dbc.Col([
             html.H2(f'Stand {curr_date.strftime("%Y-%m-%d %H:%M:%S")}', style={
                 'color': 'gray',
                 "paddingBottom": "20px"
                 })
             ],
             width=6
             ),
         dbc.Col([
             html.H3(['Projektübersicht'], style={'float': 'right'})
             ], width=2),
         dbc.Col([
             daq.ToggleSwitch(id='main-switch', value=True)
             ], width=1),
         dbc.Col([
             html.H3(['Wirtschaftlichkeitsanalyse'])
             ], width=3)
         ]),

        html.Div(['content loading...'], id='main-content')
    ],
    style={
        "padding": "50px",
        "fontFamily": "Arial",
        "fontSize": "0.9em"
        }
    )

# Main Callback: Show Project view or economic analysis
#------------------------------------------------------------------------------
@app.callback(Output('main-content', 'children'),
              Input('main-switch', 'value'))
def render_main_content(value):
    if not value: # Projektübersicht
        return [
            dbc.Row([
                dbc.Col([
                    dcc.Tabs(id="tabs-progress", value='tab-petri', children=[
                        dcc.Tab(label='Petri Net', value='tab-petri'),
                        dcc.Tab(label='Gantt Chart', value='tab-gantt'),
                        ]),
                    html.Div(id='tabs-progress-content', style={'border':'2px black solid', 'padding': '0px'}),
                    ],
                    width=8),
                 dbc.Col([
                     html.H2('Event Log'),
                     get_event_log()
                     ],
                     width=4,
                     style={
                         "paddingLeft": "10px",
                         "fontSize": "18px"})
                 ],
                 style={
                     "paddingBottom": "30px"
                     }),
             dbc.Row([
                 dbc.Col([
                     html.H2('Letzte Tätigkeiten', style={'paddingBottom': '20px'}),
                     get_last_activities()
                     ],style={"fontSize": "18px"}, width=3),
                 dbc.Col([
                     html.H2('Nächste Tätigkeiten', style={'paddingBottom': '20px'}),
                     get_next_activities()
                     ],style={"fontSize": "18px"}, width=5),
                 dbc.Col([
                     html.H2('Restliche Projektdauer', style={'paddingBottom': '20px'}),
                     get_remaining_duration()
                     ],style={"fontSize": "18px"}, width=4),
                 ])
            ]
    else: # Wirtschaftlichkeitsanalyse
        return [
            dbc.Row([
                dbc.Col([
                    html.H2(['Soll-Ist Vergleich der Projektkosten über die Zeit']),
                    get_cost_over_time()
                    ],
                    width=8),
                 dbc.Col([
                     html.H2('Projektkosten'),
                     '' #TODO: get_costs
                     ],
                     style={
                         "paddingLeft": "10px",
                         "fontSize": "18px"})
                 ],
                 style={
                     "paddingBottom": "30px"
                     }),
             dbc.Row([
                 dbc.Col([
                     html.H2('Kosten nach Partnern', style={'paddingBottom': '20px'}),
                     'Partnerkosten' #TODO: get_cost_by_partners
                     ],style={"fontSize": "18px"}, width=4),
                 dbc.Col([
                     html.H2('Kosten nach Kostenarten', style={'paddingBottom': '20px'}),
                     'Kostenartenkosten' #TODO: get_cost_by_kind
                     ],style={"fontSize": "18px"}, width=4),
                 dbc.Col([
                     html.H2('Restliche Projektkosten', style={'paddingBottom': '20px'}),
                     get_remaining_costs()
                     ],style={"fontSize": "18px"}, width=4),
                 ])
            ]

#------------------------------------------------------------------------------
# Page project view
#------------------------------------------------------------------------------

# Petri Net and Gantt Chart View
#------------------------------------------------------------------------------
@app.callback(Output('tabs-progress-content', 'children'),
              Input('tabs-progress', 'value'))
def render_progress(tab):
    if tab == 'tab-petri':
        return [html.Div('petri net is loading...', id='petri-net'),
                get_petri_filtering()]
    elif tab == 'tab-gantt':
        return get_gantt()

@app.callback(Output('petri-net', 'children'),
              Input('petri-filtering', 'value'))
def update_petri(petri_filter):
    generate_petri(petri_filter)

    fig = go.Figure()
    fig.add_layout_image(
            dict(
                source=app.get_asset_url('progress' + str(hash(str(petri_filter))) + '.gv.svg'),
                xref="x",
                yref="y",
                x=-5,
                y=0.5,
                sizex=10,
                sizey=4,
                sizing='contain',
                layer='below'
            )
    )
    fig.update_layout(xaxis={'range':[-4, 4], 'visible': False},
                      yaxis={'range':[-2, 2], 'visible': False},
                      margin={'pad': 0, 'l': 0, 't': 0, 'r': 0, 'b': 0},
                      dragmode='pan',
                      clickmode='none',
                      plot_bgcolor='#ffffff',
                      autosize=True)

    return dcc.Graph(figure=fig,
                     config = {'scrollZoom': True, 'displayModeBar': False})

def generate_petri(petri_filter):
    net, im, fm = pnml_importer.apply(project_path + 'temp/petri_net.pnml')

    if not os.path.exists(project_path + 'processes.csv'):
        print("WARNING: Couldn't find processes for coloring completed activities")

    if not os.path.exists(project_path + 'next_activities.csv'):
        print("WARNING: Couldn't find next activities for coloring")

    df = pandas.read_csv(project_path + 'processes.csv')
    next_activities = pandas.read_csv(project_path + 'next_activities.csv')
    completed = df[df['isfinished'] == True]
    res = get_ressources()

    nodes = {}
    arcs = []

    for node in net.transitions:
        nodes[node.name] = node.label

    for place in net.places:
        in_arcs = list(place.in_arcs)
        out_arcs = list(place.out_arcs)

        if len(in_arcs) == 1 and len(out_arcs) == 1:
            arcs.append([in_arcs[0].source.name, out_arcs[0].target.name])
        elif len(in_arcs) == 0 and len(out_arcs) == 1:
            arcs.append([place.name, out_arcs[0].target.name])
            nodes[place.name] = 'Start'
        elif len(in_arcs) == 1 and len(out_arcs) == 0:
            arcs.append([in_arcs[0].source.name, place.name])
            nodes[place.name] = 'End'
        else:
            print(f'WARNING: MORE THAN 1 ARCS IN PLACE {place.name}')

    dot = graphviz.Digraph('progress' + str(hash(str(petri_filter))), graph_attr={'rankdir':'LR'})

    for name in nodes.keys():
        if not nodes[name] == None:
            process = df[df['processname'] == nodes[name]]

            # determine colors
            if nodes[name] in list(completed['processname']):
                color = 'green'
            elif nodes[name] in list(next_activities['activity']):

                if process['isstarted'].iloc[0]:
                    color = 'limegreen'
                else:
                    if datetime.datetime.strptime(process['starttime'].iloc[0], '%d.%m.%Y %H:%M:%S') < curr_date:
                        color = 'red'
                    else:
                        color = 'orange'
            else:
                color = 'black'

            if not nodes[name] in ['Start', 'End']:
                if not petri_filter == res:
                    filter_true = False
                    for f in petri_filter:
                        print(f)
                        if f in process['resdescription'].iloc[0]:
                            print(f"[{f} is in {process['resdescription']}")
                            filter_true = True

                    if filter_true:
                        fontcolor = 'navy'
                    else:
                        fontcolor = 'gray40'
                else:
                    fontcolor = 'black'
            else:
                fontcolor = 'black'

            dot.node(name, nodes[name], shape='box', color=color, fontcolor=fontcolor)
        else:
            dot.node(name, '', shape='circle')

    for arc in arcs:
        if not arc[0] in nodes.keys():
            dot.node(arc[0], '', shape='circle')
        if not arc[1] in nodes.keys():
            dot.node(arc[1], '', shape='circle')

        dot.edge(arc[0], arc[1])

    dot.format= 'svg'
    dot.render(directory=app.config.assets_folder)

def get_petri_filtering(petri_filter='all'):
    res = get_ressources()
    if petri_filter == 'all':
        selection = res
    else:
        selection = petri_filter

    return dcc.Checklist(res, selection, id='petri-filtering', inputStyle={'margin-left': '20px', 'margin-right': '5px'})

def get_gantt():
    df = pandas.read_csv(project_path + 'processes.csv', usecols=['processname', 'starttime', 'endtime', 'isfinished'])#.sort_values('endtime', ascending=True)
    df['starttime'] = pandas.to_datetime(df['starttime'], dayfirst=True)
    df['endtime'] = pandas.to_datetime(df['endtime'], dayfirst=True)
    df = df.rename({'starttime': 'Start', 'endtime': 'Finish', 'processname': 'Task'}, axis=1)
    fig = pff.create_gantt(df)
    fig.update_yaxes(autorange="reversed")
    return dcc.Graph(figure=fig,
                     config = {'scrollZoom': True, 'displayModeBar': False})

# Upper Right: Event Log
#------------------------------------------------------------------------------
def get_event_log(max_rows=8):
    if not os.path.exists(project_path + 'event_log.csv'):
        return html.P("couldn't load event log, file is not existing")

    df = pandas.read_csv(project_path + 'event_log.csv').sort_values('timestamp', ascending=False).rename({'process': 'Tätigkeit', 'key': 'Faktor', 'from': 'Von', 'to': 'zu', 'timestamp': 'Zeitstempel'}, axis=1)
    return generate_table(df, 8)

# Bottom Left: Completed Activities
#------------------------------------------------------------------------------
def get_last_activities():
    if not os.path.exists(project_path + 'processes.csv'):
        return html.P("couldn't load last activites, processes are not existing")

    df = pandas.read_csv(project_path + 'processes.csv', usecols=['processname', 'endtime', 'isfinished']).sort_values('endtime', ascending=False).rename({'processname': 'Tätigkeit', 'endtime': 'Erledigt am'}, axis=1)
    completed = df[df['isfinished'] == True]
    completed = completed.drop(['isfinished'], axis=1)
    return generate_table(completed, 5)

# Bottom Middle: Next Activities with relevance
#------------------------------------------------------------------------------
def get_next_activities(max_rows=5):
    if not os.path.exists(project_path + 'next_activities.csv'):
        return html.P("couldn't load next activities, file is not existing")

    df = pandas.read_csv(project_path + 'next_activities.csv').sort_values('until', ascending=False).rename({'activity': 'Tätigkeit', 'until': 'Erledigen bis', 'relevance': 'Dringlichkeit', 'starttime': 'Startdatum'}, axis=1)
    colors = []

    for index, row in df.iterrows():
        color = 'black'

        if row['started']:
            color = 'green'

        colors.append(color)

    return html.Table([
        html.Thead(
            html.Tr([html.Th(col, style={'padding': '10px'}) for col in df.columns if col in ['Tätigkeit', 'Erledigen bis', 'Dringlichkeit', 'Startdatum']])
        ),
        html.Tbody([
            html.Tr([
                html.Td(df.iloc[i][col], style={'paddingLeft': '10px', 'paddingRight': '10px'}) for col in df.columns if col in ['Tätigkeit', 'Erledigen bis', 'Dringlichkeit','Startdatum']
            ], style={'color': colors[i]}) for i in range(min(len(df), max_rows))
        ])
    ])

# Bottom Right: Remaining Duration
#------------------------------------------------------------------------------
def get_remaining_duration():
    if not os.path.exists(project_path + 'temp/duration.csv'):
        return html.P("couldn't load remaining duration, file is not existing")

    try:
        with open(project_path + 'temp/duration.csv', 'r') as f:
            durs = [float(l) for l in f.readlines()]
    except:
        return html.P("couldn't load remaining duration, file is not accessible, retrying...")

    fig = px.histogram(durs)
    fig.update_layout({'xaxis': {'title': {'text': 'Restdauer (in h)'}},
                       'yaxis': {'title': {'text': 'Häufigkeit'}},
                       'showlegend': False})
    return dcc.Graph(figure=fig, config = {'displayModeBar': False})

#------------------------------------------------------------------------------
# Page economic analysis
#------------------------------------------------------------------------------

# Main Cost over Time
#------------------------------------------------------------------------------
def get_cost_over_time():
    if not os.path.exists(project_path + 'processes.csv'):
        return html.P("couldn't load processes, file is not existing")
    try:
        proc = pandas.read_csv(project_path + 'processes.csv')
    except:
        return html.P("couldn't load processes, file is not accessible, retrying...")

    if not os.path.exists(cost_plan_path):
        return html.P("couldn't load cost plan, file is not existing")
    try:
        planned_costs = pandas.read_csv(cost_plan_path)
    except:
        return html.P("couldn't load cost plan, file is not accessible, retrying...")

    if not os.path.exists(actual_costs_path):
        return html.P("couldn't load actaul costs, file is not existing")
    try:
        actual_costs = pandas.read_csv(actual_costs_path)
    except:
        return html.P("couldn't load actaul costs, file is not accessible, retrying...")

    df = pandas.merge(proc, planned_costs, on='processname').sort_values('endtime')
    df['total_planned_costs'] = df['personal'] + df['material'] + df['transport'] + df['vertrieb'] + df['equipment']
    df['accumulated_planned_costs'] = df['total_planned_costs'].cumsum()
    df = df.drop(['personal', 'material', 'transport', 'vertrieb', 'equipment', 'total_planned_costs'], axis=1)

    df = pandas.merge(df, actual_costs, on='processname')
    df['total_actual_costs'] = df['personal'] + df['material'] + df['transport'] + df['vertrieb'] + df['equipment']
    df['accumulated_actual_costs'] = df['total_actual_costs'].cumsum()
    df = df.drop(['personal', 'material', 'transport', 'vertrieb', 'equipment', 'total_actual_costs'], axis=1)

    graph_df = df[['endtime', 'accumulated_planned_costs', 'accumulated_actual_costs']]
    fig = go.Figure()

    fig.add_trace(go.Scatter(x=graph_df['endtime'], y=graph_df['accumulated_planned_costs'], mode='lines'))
    fig.add_trace(go.Scatter(x=graph_df['endtime'], y=graph_df['accumulated_actual_costs'], mode='lines'))

    #fig.update_layout({'xaxis': {'title': {'text': 'Verbleibende Kosten (in EUR)'}},
    #                   'yaxis': {'title': {'text': 'Häufigkeit'}},
    #                   'showlegend': False})
    return dcc.Graph(figure=fig, config = {'displayModeBar': False})

def get_remaining_costs():
    if not os.path.exists(project_path + 'temp/costs.csv'):
        return html.P("couldn't load remaining duration, file is not existing")
    try:
        df = pandas.read_csv(project_path + 'temp/costs.csv')
    except:
        return html.P("couldn't load remaining duration, file is not accessible, retrying...")

    total_costs = df.sum(axis=1).to_list()

    fig = px.histogram(total_costs)
    fig.update_layout({'xaxis': {'title': {'text': 'Verbleibende Kosten (in EUR)'}},
                       'yaxis': {'title': {'text': 'Häufigkeit'}},
                       'showlegend': False})
    return dcc.Graph(figure=fig, config = {'displayModeBar': False})

#------------------------------------------------------------------------------
# Helper Functions
#------------------------------------------------------------------------------
def generate_table(dataframe, max_rows=10):
    return html.Table([
        html.Thead(
            html.Tr([html.Th(col, style={'padding': '10px'}) for col in dataframe.columns])
        ),
        html.Tbody([
            html.Tr([
                html.Td(dataframe.iloc[i][col], style={'paddingLeft': '10px', 'paddingRight': '10px'}) for col in dataframe.columns
            ]) for i in range(min(len(dataframe), max_rows))
        ])
    ])

def get_ressources():
    df = pandas.read_csv(project_path + 'processes.csv')
    ressources = df['resdescription'].unique()
    res = []
    for r in ressources:
        r = r.replace('[', '').replace(']', '')
        while '|' in r:
            res.append(r[:r.index('|')].lstrip().rstrip().lstrip("'").rstrip("'"))
            r = r[r.index('|') + 1:]
        res.append(r.lstrip().rstrip().lstrip("'").rstrip("'"))
    return list(dict.fromkeys(res))

if __name__ == '__main__':
    app.run_server(debug=True)#, dev_tools_hot_reload=False)


import cv2

cap = cv2.VideoCapture("ds1.mp4")

while True:
    _, frame = cap.read()
    images = cv2.resize(frame,(1280,720))
    cv2.imshow("frame",images)
    key = cv2.waitKey(1)
    if key == 27:
        break

cap.release()
cv2.destroyAllWindows()


from src.controllers.login import post_login
from flask import Blueprint, request, jsonify, make_response, g

login_blueprint = Blueprint(
    'login', __name__, template_folder='routes', static_folder='routes')

@login_blueprint.route('/', methods=['POST'], strict_slashes=False)
def post():
    try:
        user_id = g.user_id
        token = post_login(user_id)
        return make_response(jsonify({'success': True, 'data': token, 'message': 'OK'}), 200)
    except Exception as e:
        raise e


from config import file

class TimeRange:
    day = ''
    start_time = ''
    end_time= ''
    hours = []

    def __init__(self, time_range):
        self.hours = []
        self.day = time_range[:2]
        self.start_time = time_range[2:7]
        self.end_time = time_range[8:]

        if len(time_range) > 1:
            for hour in range (int(self.start_time[:2]), int(self.end_time[:2])):
                self.hours.append(str(hour))

class Schedule:
    time_ranges = []

    def __init__(self, schedule):
        self.time_ranges = []
        time_ranges = schedule.split(',')

        for time_range in time_ranges:
            new_time_range = TimeRange(time_range)
            self.time_ranges.append(new_time_range)

class Employee:
    def __init__(self, name, schedule) -> None:
        self.name = name
        self.schedule = schedule

class FileParser:
    rows = []

    def __init__(self, file) -> None:
        self.data_file = file

    def _load_rows(self):
        with open(self.data_file) as f:
            self.rows = f.readlines()

    def get_employees(self):
        data = []
        self._load_rows()
        for row in self.rows:
            name = row.split('=')[0]
            schedule = row.split('=')[1]
            employee_schedule = Schedule(schedule)
            employee = Employee(name, employee_schedule)
            data.append(employee)
        return data

class SalaryCalculator:
    sat_sun = {'SA', 'SU'}
    first_turn_hours = {'0','1','2','3','4','5','6','7','8'}
    second_turn_hours = {'9','10','11','12','13','14','15','16','17'}
    salary_matrix = {'special': {'first_turn':30, 'second_turn':20, 'third_turn':25},
                     'normal' : {'first_turn':25, 'second_turn':15, 'third_turn':20}}

    def calculate_salary(self, schedule):
        salary = 0
        turn = ''

        for time_range in schedule.time_ranges:
            if time_range.day in self.sat_sun:
                day_type = 'special'
            else:
                day_type = 'normal'
            for hour in time_range.hours:
                if hour in self.first_turn_hours:
                    turn = 'first_turn'
                elif hour in self.second_turn_hours:
                    turn = 'second_turn'
                else:
                    turn = 'third_turn'

                if turn:
                    salary += self.salary_matrix[day_type][turn]

        return salary

if __name__=='__main__':

    fp = FileParser(file)
    salary_calculator = SalaryCalculator()

    employees = fp.get_employees()
    for employee in employees:
        salary = salary_calculator.calculate_salary(employee.schedule)
        print(f'The amount to pay {employee.name.upper()} is: {salary} USD'), employee.name, salary


import collections

class Solution:
    # my solution is correct, but it takes a lot of time!
    # O(k * (n - k))
    def maxSlidingWindow(self, nums, k):
        res = []
        window = []

        for i in range(k):
            window.append(nums[i])

        windowMax = max(window)
        res.append(windowMax)

        l = 0

        for r in range(k, len(nums)):
            window.remove(nums[l])
            window.append(nums[r])

            windowMax = max(window)

            res.append(windowMax)

            l += 1

        return res

    # O(1) * O(n)
    # Monotonically Decreasing Que
    def neetcode_maxSlidingWindow(self, nums, k):
        output = []
        q = collections.deque()  # index

        l = r = 0

        while r < len(nums):
            # pop smaller values from q
            while q and nums[q[-1]] < nums[r]:
                q.pop()

            q.append(r)

            # remove left value from window
            if l > q[0]:
                q.popleft()

            if (r + 1) >= k:
                output.append(nums[q[0]])
                l += 1

            r += 1

        return output

leetcode#150/Sliding Window/239. Sliding Window Maximum.py


# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####

import bpy, os, math, subprocess, datetime, multiprocessing
from math import sin, cos, acos, asin, pi
from mathutils import Vector, Matrix
from subprocess import PIPE, Popen
try:
    import numpy as numpy
    np = 1
except:
    np = 0
nproc = multiprocessing.cpu_count()

class LiVi_bc(object):
    def __init__(self, filepath, scene):
        self.filepath = filepath
        self.filename = os.path.splitext(os.path.basename(self.filepath))[0]
        self.filedir = os.path.dirname(self.filepath)
        if not os.path.isdir(self.filedir+"/"+self.filename):
            os.makedirs(self.filedir+"/"+self.filename)
        self.newdir = self.filedir+"/"+self.filename
        self.filebase = self.newdir+"/"+self.filename
        self.scene = scene
        self.scene['newdir'] = self.newdir

class LiVi_e(LiVi_bc):
    def __init__(self, filepath, scene, sd, tz, export_op):
        LiVi_bc.__init__(self, filepath, scene)
        self.scene = scene
        self.simtimes = []
        self.TZ = tz
        self.StartD = sd
        self.scene.display_legend = -1
        self.clearscenee()
        self.clearscened()
        self.sky_type = int(scene.livi_export_sky_type)
        self.time_type = int(scene.livi_export_time_type)
        self.merr = 0

        if scene.livi_anim == "0":
            scene.frame_start = 0
            scene.frame_end = 0
            if scene.livi_export_time_type == "0":
                self.starttime = datetime.datetime(2010, int(scene.livi_export_start_month), int(scene.livi_export_start_day), int(scene.livi_export_start_hour), 0)
            self.fe = 0
            self.frameend = 0

        elif scene.livi_anim == "1":
            self.starttime = datetime.datetime(2010, int(scene.livi_export_start_month), int(scene.livi_export_start_day), int(scene.livi_export_start_hour), 0)
            self.endtime = datetime.datetime(2010, int(scene.livi_export_end_month), int(scene.livi_export_end_day), int(scene.livi_export_end_hour), 0)
            self.hours = (self.endtime-self.starttime).seconds/3600
            scene.frame_start = 0
            scene.frame_end = int(self.hours/scene.livi_export_interval)
            self.fe = int(self.hours/scene.livi_export_interval)
            self.frameend = int(self.hours/scene.livi_export_interval)

        elif scene.livi_anim in ("2", "3", "4"):
            self.fe = scene.frame_end
            self.frameend = 0
            if scene.livi_export_time_type == "0":
                self.starttime = datetime.datetime(2010, int(scene.livi_export_start_month), int(scene.livi_export_start_day), int(scene.livi_export_start_hour), 0)

        if self.sky_type < 4:
            self.skytypeparams = ("+s", "+i", "-c", "-c")[self.sky_type]

        self.rtrace = self.filebase+".rtrace"

        if self.scene.livi_export_time_type == "0" and self.sky_type in (0, 1, 2, 3) or self.scene.livi_anim == "1":
            self.sunexport()

        elif self.sky_type == 4:
            self.hdrexport(self.scene.livi_export_hdr_name)

        elif self.scene.livi_export_time_type == "1" and self.scene.livi_anim != "1":
            self.ddsskyexport()

        for frame in range(0, self.fe + 1):
            if scene.livi_anim == "4":
                self.radlights(frame)
            else:
                if frame == 0:
                    self.radlights(frame)

            if scene.livi_anim == "3":
                self.radmat(frame)
            else:
                if frame == 0:
                    self.radmat(frame)

        self.rtexport(export_op)

        for frame in range(0, self.fe + 1):
            self.merr = 0
            if scene.livi_anim == "2":
                self.obexport(frame, [geo for geo in self.scene.objects if geo.type == 'MESH' and 'lightarray' not in geo.name and geo.hide == False and geo.layers[0] == True], 0, export_op)
            if scene.livi_anim == "3":
                self.obmexport(frame, [geo for geo in self.scene.objects if geo.type == 'MESH' and 'lightarray' not in geo.name and geo.hide == False and geo.layers[0] == True], 0, export_op)
            else:
                if frame == 0:
                    self.obexport(frame, [geo for geo in self.scene.objects if geo.type == 'MESH' and 'lightarray' not in geo.name and geo.hide == False and geo.layers[0] == True], 0, export_op)

            self.fexport(frame, export_op)

    def poly(self, fr):
        if self.scene.livi_anim == "2" or (self.scene.livi_anim == "3" and self.merr == 0):
            return(self.filebase+"-"+str(fr)+".poly")
        else:
            return(self.filebase+"-0.poly")

    def obj(self, fr):
        if self.scene.livi_anim == "2":
            return(self.filebase+"-"+str(fr)+".obj")
        else:
            return(self.filebase+"-0.obj")

    def mesh(self, fr):
        if self.scene.livi_anim in ("2", "3"):
            return(self.filebase+"-"+str(fr)+".mesh")
        else:
            return(self.filebase+"-0.mesh")

    def mat(self, fr):
        if self.scene.livi_anim == "3":
            return(self.filebase+"-"+str(fr)+".mat")
        else:
            return(self.filebase+"-0.mat")

    def lights(self, fr):
        if self.scene.livi_anim == "4":
            return(self.filebase+"-"+str(fr)+".lights")
        else:
            return(self.filebase+"-0.lights")

    def sky(self, fr):
        if self.scene.livi_anim == "1":
            return(self.filebase+"-"+str(fr)+".sky")
        else:
            return(self.filebase+"-0.sky")

    def clearscenee(self):
        for sunob in [ob for ob in self.scene.objects if ob.type == 'LAMP' and ob.data.type == 'SUN']:
            self.scene.objects.unlink(sunob)

        for ob in [ob for ob in self.scene.objects if ob.type == 'MESH']:
            self.scene.objects.active = ob
            for vcol in ob.data.vertex_colors:
                bpy.ops.mesh.vertex_color_remove()

    def clearscened(self):
        for ob in [ob for ob in self.scene.objects if ob.type == 'MESH']:
            try:
                if ob['res'] == 1:
                   self.scene.objects.unlink(ob)
            except Exception as e:
                print(e)

        for mesh in bpy.data.meshes:
            if mesh.users == 0:
                bpy.data.meshes.remove(mesh)

        for lamp in bpy.data.lamps:
            if lamp.users == 0:
                bpy.data.lamps.remove(lamp)

        for oldgeo in bpy.data.objects:
            if oldgeo.users == 0:
                bpy.data.objects.remove(oldgeo)

        for sk in bpy.data.shape_keys:
            if sk.users == 0:
                for keys in sk.keys():
                    keys.animation_data_clear()

    def sparams(self, acc):
        if acc == "3":
            return(self.scene.livi_calc_custom_acc)
        else:
            if acc == "0":
                num = ("2", "256", "128", "128", "0.3", "1", "1", "1", "0", "1", "0.004")
            elif acc == "1":
                num = ("2", "1024", "512", "512", "0.15", "1", "1", "2", "1", "1", "0.001")
            elif acc == "2":
                num = ("3", "4098", "1024", "1024", "0.08", "1", "1", "3", "5", "1", "0.0003")
            return(" -ab %s -ad %s -ar %s -as %s -av 0 0 0 -aa %s -dj %s -ds %s -dr %s -ss %s -st %s -lw %s " %(num))

    def pparams(self, acc):
        if acc == "3":
            return(self.scene.livi_calc_custom_acc)
        else:
            if acc == "0":
                num = ("2", "256", "128", "128", "0.3", "1", "1", "1", "0", "1", "0.004")
            elif acc == "1":
                num = ("3", "1024", "512", "512", "0.15", "1", "1", "2", "1", "1", "0.001")
            elif acc == "2":
                num = ("3", "4098", "1024", "1024", "0.08", "1", "1", "3", "5", "1", "0.0003")
            return(" -ab %s -ad %s -ar %s -as %s -av 0 0 0 -aa %s -dj %s -ds %s -dr %s -ss %s -st %s -lw %s " %(num))

    def sunexport(self):
        hdr_skies = []
        for frame in range(0, self.frameend + 1):
            bpy.ops.time.end_frame_set = frame
            simtime = self.starttime + frame*datetime.timedelta(seconds = 3600*self.scene.livi_export_interval)
            self.simtimes.append(simtime)
            subprocess.call("gensky "+str(self.simtimes[frame].month)+" "+str(self.simtimes[frame].day)+" "+str(self.simtimes[frame].hour)+":"+str(self.simtimes[frame].minute)+str(self.TZ)+" -a "+str(self.scene.livi_export_latitude)+" -o "+str(self.scene.livi_export_longitude)+" "+self.skytypeparams+" > "+self.sky(frame), shell=True)
            deg2rad = 2*math.pi/360
            if self.scene.livi_export_summer_enable:
                DS = 1
            else:
                DS = 0
            ([solalt, solazi]) = solarPosition(simtime.timetuple()[7], simtime.hour - DS + (simtime.minute)*0.016666, self.scene.livi_export_latitude, self.scene.livi_export_longitude)
            if frame == 0:
                bpy.ops.object.lamp_add(type='SUN')
                sun = bpy.context.object
                sun.data.shadow_method = 'RAY_SHADOW'
                sun.data.shadow_ray_samples = 8
                sun.data.sky.use_sky = 1
                if self.scene['skytype'] == 0:
                    sun.data.shadow_soft_size = 0.1
                    sun.data.energy = 5
                elif self.scene['skytype'] == 1:
                    sun.data.shadow_soft_size = 1
                    sun.data.energy = 3
                sun.location = (0,0,10)
            sun.rotation_euler = (90-solalt)*deg2rad, 0, solazi*deg2rad
            sun.keyframe_insert(data_path = 'location', frame = frame)
            sun.keyframe_insert(data_path = 'rotation_euler', frame = frame)
            bpy.ops.object.select_all()
            if self.scene['skytype'] == 3:
                sun.data.energy = 0
                subprocess.call("gensky 12 25 07 "+"-b 22.86 -c"+" > "+self.sky(frame), shell=True)
            self.skyexport(open(self.sky(frame), "a"))
            subprocess.call("oconv "+self.sky(frame)+" > "+self.filebase+"-"+str(frame)+"sky.oct", shell=True)
            subprocess.call("rpict -vta -vp 0 0 0 -vd 1 0 0 -vu 0 0 1 -vh 360 -vv 360 -x 1000 -y 1000 "+self.filebase+"-"+str(frame)+"sky.oct > "+self.newdir+"/"+str(frame)+".hdr", shell=True)
            hdr_skies.append(self.newdir+"/"+str(frame)+".hdr")

            self.hdrexport(hdr_skies)

    def hdrexport(self, hdr_skies):
        for frame, sky in enumerate(hdr_skies):
            if self.scene.world.texture_slots[0] == None:
                imgPath = sky
                img = bpy.data.images.load(imgPath)
                if len(hdr_skies) == 1:
                    img.source = 'FILE'
                else:
                    img.source = 'SEQUENCE'
                imtex = bpy.data.textures.new('Radsky', type = 'IMAGE')
                imtex.image = img
                imtex.factor_red = (0.05, 0.000001)[int(self.scene.livi_export_time_type)]
                imtex.factor_green = (0.05, 0.000001)[int(self.scene.livi_export_time_type)]
                imtex.factor_blue = (0.05, 0.000001)[int(self.scene.livi_export_time_type)]

                w = bpy.data.worlds['World']
                slot = w.texture_slots.add()
                slot.texture = imtex
                slot.use_map_horizon = True
                slot.use_map_blend = False
                slot.texture_coords = 'ANGMAP'

                bpy.context.scene.world.light_settings.use_environment_light = True
                bpy.context.scene.world.light_settings.use_indirect_light = False
                bpy.context.scene.world.light_settings.use_ambient_occlusion = True
                bpy.context.scene.world.light_settings.environment_energy = 1
                bpy.context.scene.world.light_settings.environment_color = 'SKY_COLOR'
                bpy.context.scene.world.light_settings.gather_method = 'APPROXIMATE'
                bpy.context.scene.world.light_settings.passes = 1
                bpy.context.scene.world.use_sky_real = True
                bpy.context.scene.world.use_sky_paper = False
                bpy.context.scene.world.use_sky_blend = False
                if self.scene.livi_export_time_type == "0":
                    bpy.context.scene.world.ambient_color = (0.04, 0.04, 0.04)
                else:
                    bpy.context.scene.world.ambient_color = (0.000001, 0.000001, 0.000001)
                bpy.context.scene.world.horizon_color = (0, 0, 0)
                bpy.context.scene.world.zenith_color = (0, 0, 0)
                render = bpy.context.scene.render
                render.use_raytrace = True
                render.use_textures = True
                render.use_shadows = True
                render.use_color_management = True
                bpy.ops.images.reload
            else:
                for im in bpy.data.images:
                    if ".hdr" in im.name or ".HDR" in im.name:
                        im.filepath = sky
                        bpy.ops.image.reload()
            if self.sky_type == 4:
                self.hdrsky(open(self.sky(frame), "w"), self.scene.livi_export_hdr_name)
            elif self.time_type == 1:
                self.hdrsky(open(self.sky(frame), "w"), sky)

    def skyexport(self, rad_sky):
        rad_sky.write("skyfunc glow skyglow\n0\n0\n")
        if self.scene['skytype'] < 3:
            rad_sky.write("4 .8 .8 1 0\n\n")
        else:
            rad_sky.write("4 1 1 1 0\n\n")
        rad_sky.write("skyglow source sky\n0\n0\n4 0 0 1  180\n\n")
        rad_sky.write("skyfunc glow groundglow\n0\n0\n4 .8 1.1 .8  0\n\n")
        rad_sky.write("groundglow source ground\n0\n0\n4 0 0 -1  180\n\n")
        rad_sky.close()

    def ddsskyexport(self):
        if np == 0:
            vecvals = []
        else:
            vecvals = numpy.zeros((8766, 151))
        i = 0
        j = 0
        null = "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"
        prevline = b"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"
        if os.path.splitext(os.path.basename(self.scene.livi_export_epw_name))[1] in (".epw", ".EPW"):
            epw = open(self.scene.livi_export_epw_name, "r")
            vecfile = open(self.newdir+"/"+os.path.splitext(os.path.basename(self.scene.livi_export_epw_name))[0]+".vec", "w")
            for line in epw:
                if i == 0:
                    lat = line.split(",")[6]
                    lon = -float(line.split(",")[7])
                    mer = -15*float(line.split(",")[8])
                elif i > 8 and float(line.split(",")[15]) > 0:
                    time = datetime.datetime(int(line.split(",")[0]), int(line.split(",")[1]), int(line.split(",")[2]), int(line.split(",")[3])-1, int(line.split(",")[4])-60)
                    dirnorm = line.split(",")[14]
                    diffhoz = line.split(",")[15]
                    dglcmd = "gendaylit "+str(time.month)+" "+str(time.day)+" "+str(time.hour)+" -a "+str(lat)+" -o "+str(lon)+" -m "+str(mer)+" -W "+str(dirnorm)+" "+str(diffhoz)+" | genskyvec -c 1 1 1 -m 1 |cut -f1 |tr '\n' ' '"
                    dglrun = Popen(dglcmd, shell = True, stdout = PIPE, stderr = PIPE).communicate()

                    if dglrun[1] == b'':
                        vecfile.write(str(time.hour)+" "+str(time.weekday())+" ")
                        vecfile.write(dglrun[0].decode()+"\n")
                        prevline = dglrun[0]
                    else:
                        if dirnorm == 0:
                            vecfile.write(str(time.hour)+" "+str(time.weekday())+" ")
                            vecfile.write(null+"\n")
                        else:
                            vecfile.write(str(time.hour)+" "+str(time.weekday())+" ")
                            vecfile.write(prevline.decode()+"\n")

                i = i + 1

            vecfile.close()
            epw.close()

        if os.path.splitext(os.path.basename(self.scene.livi_export_epw_name))[1] in (".epw", ".EPW", ".vec"):
            if os.path.splitext(os.path.basename(self.scene.livi_export_epw_name))[1] in (".vec"):
                vecfile = open(self.scene.livi_export_epw_name, "r")
            else:
                vecfile = open(self.newdir+"/"+os.path.splitext(os.path.basename(self.scene.livi_export_epw_name))[0]+".vec", "r")
            if np == 0:
                for li, line in enumerate(vecfile):
                    vecvals.append([negneg(x) for x in line.strip("\n").strip("  ").split(" ")])
                vecfile.close()
            else:
                vecvals = numpy.fromfile(self.newdir+"/"+os.path.splitext(os.path.basename(self.scene.livi_export_epw_name))[0]+".vec", dtype = float, count = -1, sep = " ")
                vecvals = vecvals.reshape((-1, 148))
                vecvals[vecvals < 0] = 0

            if np == 0:
                vals = [sum(a) for a in zip(*vecvals)]
            else:
                vals = vecvals.sum(axis=0)
            skyrad = open(self.filebase+".whitesky", "w")
            skyrad.write("void glow sky_glow \n0 \n0 \n4 1 1 1 0 \nsky_glow source sky \n0 \n0 \n4 0 0 1 180 \nvoid glow ground_glow \n0 \n0 \n4 1 1 1 0 \nground_glow source ground \n0 \n0 \n4 0 0 -1 180\n\n")
            skyrad.close()
            subprocess.call("oconv "+self.filebase+".whitesky > "+self.filebase+"-whitesky.oct", shell=True)
            subprocess.call("vwrays -ff -x 600 -y 600 -vta -vp 0 0 0 -vd 0 1 0 -vu 0 0 1 -vh 360 -vv 360 -vo 0 -va 0 -vs 0 -vl 0 | rtcontrib -bn 146 -fo -ab 0 -ad 512 -n "+str(nproc)+" -ffc $(vwrays -d -x 600 -y 600 -vta -vp 0 0 0 -vd 0 1 0 -vu 0 0 1 -vh 360 -vv 360 -vo 0 -va 0 -vs 0 -vl 0) -V+ -f tregenza.cal -b tbin -o p%d.hdr -m sky_glow "+self.filebase+"-whitesky.oct", shell = True)

            for j in range(0, 146):
                subprocess.call("pcomb -s "+str(vals[j+2])+" p"+str(j)+".hdr > ps"+str(j)+".hdr", shell = True)
                subprocess.call("rm  p"+str(j)+".hdr", shell = True)
            subprocess.call("pcomb -h  ps*.hdr > "+self.newdir+"/"+os.path.splitext(os.path.basename(self.scene.livi_export_epw_name))[0]+".hdr", shell = True)
            for j in range(0, 146):
                subprocess.call("rm ps"+str(j)+".hdr" , shell = True)

        self.hdrexport([self.newdir+"/"+os.path.splitext(os.path.basename(self.scene.livi_export_epw_name))[0]+".hdr"])

    def hdrsky(self, rad_sky, skyfile):
        rad_sky.write("# Sky material\nvoid colorpict hdr_env\n7 red green blue "+skyfile+" angmap.cal sb_u sb_v\n0\n0\n\nhdr_env glow env_glow\n0\n0\n4 1 1 1 0\n\nenv_glow bubble sky\n0\n0\n4 0 0 0 500\n\n")
        rad_sky.close()

    def radmat(self, frame):
        mats = bpy.data.materials
        self.scene.frame_set(frame)
        rad_mat = open(self.mat(frame), "w")
        for meshmat in mats:
            diff = [meshmat.diffuse_color[0]*meshmat.diffuse_intensity, meshmat.diffuse_color[1]*meshmat.diffuse_intensity, meshmat.diffuse_color[2]*meshmat.diffuse_intensity]
            if "calcsurf" in meshmat.name:
                meshmat.use_vertex_color_paint = 1
            if meshmat.use_shadeless == 1:
                rad_mat.write("# Antimatter material\n")
                rad_mat.write("void antimatter " + meshmat.name.replace(" ", "_") +"\n1 void\n0\n0\n\n")

            elif meshmat.use_transparency == False and meshmat.raytrace_mirror.use == True and meshmat.raytrace_mirror.reflect_factor >= 0.99:
                rad_mat.write("# Mirror material\n")
                rad_mat.write("void mirror " + meshmat.name.replace(" ", "_") +"\n0\n0\n")
                rad_mat.write("3 " + str(meshmat.mirror_color[0])+ " " +  str(meshmat.mirror_color[1]) + " " +
                                    str(meshmat.mirror_color[2]) + " " + "\n\n")

            elif meshmat.use_transparency == True and meshmat.transparency_method == 'RAYTRACE' and round(meshmat.raytrace_transparency.ior, 2) == 1.52 and meshmat.alpha >= 0.01 and meshmat.translucency == 0:
                rad_mat.write("# Glass material\n")
                rad_mat.write("void glass " + meshmat.name.replace(" ", "_") +"\n0\n0\n")
                rad_mat.write("3 %s %s %s %s" % (diff[0], diff[1], diff[2], "\n\n"))

            elif meshmat.use_transparency == True and meshmat.transparency_method == 'RAYTRACE' and round(meshmat.raytrace_transparency.ior, 2) != 1.52 and meshmat.alpha >= 0.01 and meshmat.translucency == 0:
                rad_mat.write("# Dielectric material\n")
                rad_mat.write("void dielectric " + meshmat.name.replace(" ", "_") +"\n0\n0\n")
                rad_mat.write("5 %s %s %s %s" % (diff[0], diff[1], diff[2], " ") +
    				        str(meshmat.raytrace_transparency.ior) + " " + "0" + "\n\n")

            elif meshmat.use_transparency == True and meshmat.alpha < 1.0 and meshmat.translucency > 0.001:
                rad_mat.write("# translucent material\n")
                rad_mat.write("void trans " + meshmat.name.replace(" ", "_")+"\n0\n0\n")
                rad_mat.write("7 %s %s %s %s" % (diff[0], diff[1], diff[2], " ") +
    				        str(meshmat.specular_intensity) + " " +
    				        str(1.0 - meshmat.specular_hardness/511.0) + " " +
    				        str(1.0 - meshmat.alpha) + " " +
                                            str(1.0 - meshmat.translucency) + "\n\n")

            elif meshmat.use_transparency == False and meshmat.raytrace_mirror.use == True and meshmat.raytrace_mirror.reflect_factor < 0.99:
                rad_mat.write("# Metal material\n")
                rad_mat.write("void metal " + meshmat.name.replace(" ", "_") +"\n0\n0\n")
                rad_mat.write("5 %s %s %s %s" % (diff[0], diff[1], diff[2], " ") + str(meshmat.specular_intensity) + " " +
                              str(1.0-meshmat.specular_hardness/511.0) + "\n\n")
            else:
                rad_mat.write("# Plastic material\n")
                rad_mat.write("void plastic " + meshmat.name.replace(" ", "_") +"\n0\n0\n")
                rad_mat.write("5 %s %s %s %s" % (diff[0], diff[1], diff[2], " ") + str(meshmat.specular_intensity) + " " +
                                   str(1.0-meshmat.specular_hardness/511.0) + "\n\n")
        rad_mat.close()

    def obexport(self,frame, obs, obno, export_op):
        self.scene.frame_current = frame
        rad_poly = open(self.poly(frame), 'w')
        if obno == 0:
            bpy.ops.export_scene.obj(filepath=self.obj(frame), check_existing=True, filter_glob="*.obj;*.mtl", use_selection=False, use_animation=False, use_apply_modifiers=True, use_edges=False, use_normals=True, use_uvs=True, use_materials=True, use_triangles=True, use_nurbs=True, use_vertex_groups=False, use_blen_objects=True, group_by_object=False, group_by_material=False, keep_vertex_order=True, global_scale=1.0, axis_forward='Y', axis_up='Z', path_mode='AUTO')
            objcmd = "obj2mesh -w -a "+self.mat(frame)+" "+self.obj(frame)+" "+self.mesh(frame)
            objrun = Popen(objcmd, shell = True, stderr = PIPE)
            for line in objrun.stderr:
                if 'fatal' in str(line):
                    self.merr = 1

        if self.merr == 0 and obno == 0:
            rad_poly.write("void mesh id \n1 "+self.mesh(frame)+"\n0\n0\n")

        if self.merr == 1:
            for geo in obs:
                geomatrix = geo.matrix_world
                for face in geo.data.faces:
                    try:
                        vertices = face.vertices[:]
                        rad_poly.write("# Polygon \n")
                        rad_poly.write(geo.data.materials[face.material_index].name.replace(" ", "_") + " polygon " + "poly_"+geo.data.name.replace(" ", "_")+"_"+str(face.index) + "\n")
                        rad_poly.write("0\n0\n"+str(3*len(face.vertices))+"\n")
                        try:
                            if geo.data.shape_keys.key_blocks[0] and geo.data.shape_keys.key_blocks[1]:
                                for vertindex in vertices:
                                    sk0 = geo.data.shape_keys.key_blocks[0]
                                    sk0co = geomatrix*sk0.data[vertindex].co
                                    sk1 = geo.data.shape_keys.key_blocks[1]
                                    sk1co = geomatrix*sk1.data[vertindex].co
                                    rad_poly.write(" " +str(sk0co[0]+(sk1co[0]-sk0co[0])*sk1.value) +  " " + str(sk0co[1]+(sk1co[1]-sk0co[1])*sk1.value) +" "+ str(sk0co[2]+(sk1co[2]-sk0co[2])*sk1.value) + "\n")
                        except:
                            for vertindex in vertices:
                                rad_poly.write(" " +str((geomatrix*geo.data.vertices[vertindex].co)[0]) +  " " + str((geomatrix*geo.data.vertices[vertindex].co)[1]) +" "+ str((geomatrix*geo.data.vertices[vertindex].co)[2]) + "\n")
                        rad_poly.write("\n")
                    except:
                        export_op.report({'ERROR'},"Make sure your object "+geo.name+" has an associated material")
            rad_poly.close()

    def obmexport(self, frame, obs, ob, export_op):
        self.scene.frame_current = frame
        if ob == 0:
            if frame == 0:
                bpy.ops.export_scene.obj(filepath=self.obj(frame), check_existing=True, filter_glob="*.obj;*.mtl", use_selection=False, use_animation=False, use_apply_modifiers=True, use_edges=False, use_normals=True, use_uvs=True, use_materials=True, use_triangles=True, use_nurbs=True, use_vertex_groups=False, use_blen_objects=True, group_by_object=False, group_by_material=False, keep_vertex_order=True, global_scale=1.0, axis_forward='Y', axis_up='Z', path_mode='AUTO')
            objcmd = "obj2mesh -w -a "+self.mat(frame)+" "+self.obj(0)+" "+self.mesh(frame)
            objrun = Popen(objcmd, shell = True, stderr = PIPE)
            for line in objrun.stderr:
                if 'fatal' in str(line):
                    self.merr = 1

            if self.merr == 0 and ob == 0:
                rad_poly = open(self.poly(frame), 'w')
                rad_poly.write("void mesh id \n1 "+self.mesh(frame)+"\n0\n0\n")

            if self.merr == 1:
                if frame == 0:
                    rad_poly = open(self.poly(frame), 'w')
                    for geo in obs:
                        geomatrix = geo.matrix_world
                        for face in geo.data.faces:
                            try:
                                vertices = face.vertices[:]
                                rad_poly.write("# Polygon \n")
                                rad_poly.write(geo.data.materials[face.material_index].name.replace(" ", "_") + " polygon " + "poly_"+geo.data.name.replace(" ", "_")+"_"+str(face.index) + "\n")
                                rad_poly.write("0\n0\n"+str(3*len(face.vertices))+"\n")
                                try:
                                    if geo.data.shape_keys.key_blocks[0] and geo.data.shape_keys.key_blocks[1]:
                                        for vertindex in vertices:
                                            sk0 = geo.data.shape_keys.key_blocks[0]
                                            sk0co = geomatrix*sk0.data[vertindex].co
                                            sk1 = geo.data.shape_keys.key_blocks[1]
                                            sk1co = geomatrix*sk1.data[vertindex].co
                                            rad_poly.write(" " +str(sk0co[0]+(sk1co[0]-sk0co[0])*sk1.value) +  " " + str(sk0co[1]+(sk1co[1]-sk0co[1])*sk1.value) +" "+ str(sk0co[2]+(sk1co[2]-sk0co[2])*sk1.value) + "\n")
                                except:
                                    for vertindex in vertices:
                                        rad_poly.write(" " +str((geomatrix*geo.data.vertices[vertindex].co)[0]) +  " " + str((geomatrix*geo.data.vertices[vertindex].co)[1]) +" "+ str((geomatrix*geo.data.vertices[vertindex].co)[2]) + "\n")
                                rad_poly.write("\n")
                            except:
                                export_op.report({'ERROR'},"Make sure your object "+geo.name+" has an associated material")

                    rad_poly.close()

    def radlights(self, frame):
        os.chdir(self.newdir)
        self.scene.frame_set(frame)
        rad_lights = open(self.lights(frame), "w")
        for geo in bpy.context.scene.objects:
            if geo.ies_name != "":
                iesname = os.path.splitext(os.path.basename(geo.ies_name))[0]
                if geo.type == 'LAMP':
                    subprocess.call("ies2rad -t default -m "+str(geo.ies_strength)+" -l "+self.newdir+" -d"+geo.ies_unit+" -o "+iesname+"-"+str(frame)+" "+geo.ies_name+" > "+self.filebase+"-"+str(frame)+".lights", shell=True)
                    rad_lights.write("!xform -rx "+str((180/pi)*geo.rotation_euler[0])+" -ry "+str((180/pi)*geo.rotation_euler[1])+" -rz "+str((180/pi)*geo.rotation_euler[2])+" -t "+str(geo.location[0])+" "+str(geo.location[1])+" "+str(geo.location[2])+" "+self.newdir+"/"+iesname+"-"+str(frame)+".rad\n\n")
                if 'lightarray' in geo.name:
                    spotmatrix = geo.matrix_world
                    subprocess.call("ies2rad -t default -m "+str(geo.ies_strength)+" -l "+self.newdir+" -o "+iesname+"-"+str(frame)+" -d"+geo.ies_unit+" "+geo.ies_name+" > "+self.filebase+"-"+str(frame)+".lights", shell=True)
                    rotation = geo.rotation_euler
#                    for face in [face for face in geo.data.faces if 'lightarray' in geo.material_slots[face.material_index].name]:
                    for face in geo.data.faces:
                         rad_lights.write("!xform -rx "+str((180/pi)*rotation[0])+" -ry "+str((180/pi)*rotation[1])+" -rz "+str((180/pi)*rotation[2])+" -t "+str((spotmatrix*face.center)[0])+" "+str((spotmatrix*face.center)[1])+" "+str((spotmatrix*face.center)[2])+" "+self.newdir+"/"+iesname+"-"+str(frame)+".rad\n\n")
        rad_lights.close()

    def rtexport(self, export_op):
    # Function for the exporting of Blender geometry and materials to Radiance files
        rtrace = open(self.rtrace, "w")
        calcsurfverts = []
        calcsurffaces = []

        if 0 not in [len(mesh.materials) for mesh in bpy.data.meshes]:
            for o, geo in enumerate(self.scene.objects):
                csf = []
                cverts = []
                cvox = []
                cvoy = []
                cvoz = []

                self.scene.objects.active = geo
                if geo.type == 'MESH' and 'lightarray' not in geo.name and geo.hide == False and geo.layers[0] == True:
                    bpy.ops.object.mode_set(mode = 'EDIT')
                    bpy.ops.mesh.select_all(action='SELECT')
#                    bpy.ops.mesh.normals_make_consistent(inside=False)
                    bpy.ops.object.mode_set(mode = 'OBJECT')
                    meshorig = geo.data
                    mesh = meshorig.copy()
                    mesh.transform(geo.matrix_world)

                    if len([mat.name for mat in geo.material_slots if 'calcsurf' in mat.name]) != 0:
                        for face in mesh.faces:
                            if "calcsurf" in str(mesh.materials[face.material_index].name):
                                bpy.context.scene.objects.active = geo
                                geo.select = True
                                bpy.ops.object.mode_set(mode = 'OBJECT')
                                for vc in geo.data.vertex_colors:
                                    bpy.ops.mesh.vertex_color_remove()
                                fnormx, fnormy, fnormz = (face.normal * geo.matrix_world)[0], (face.normal * geo.matrix_world)[1], (face.normal * geo.matrix_world)[2]
                                if self.scene.livi_export_calc_points == "0":
                                    rtrace.write(str(face.center[0])+" "+str(face.center[1])+" "+str(face.center[2])+" "+str(face.normal[0])+" "+str(face.normal[1])+" "+str(face.normal[2])+"\n")
                                calcsurffaces.append((o, face))
                                csf.append(face.index)
                                geo['calc'] = 1

                                for vert in face.vertices:
                                    if (mesh.vertices[vert]) not in calcsurfverts:
                                        vcentx = mesh.vertices[vert].co[0]
                                        vcenty = mesh.vertices[vert].co[1]
                                        vcentz = mesh.vertices[vert].co[2]
                                        vnormx = mesh.vertices[vert].normal[0]
                                        vnormy = mesh.vertices[vert].normal[1]
                                        vnormz = mesh.vertices[vert].normal[2]
                                        if self.scene.livi_export_calc_points == "1":
                                            rtrace.write(str(vcentx)+" "+str(vcenty)+" "+str(vcentz)+" "+str(vnormx)+" "+str(vnormy)+" "+str(vnormz)+"\n")

                                        calcsurfverts.append(mesh.vertices[vert])
                                        cvox.append(mesh.vertices[vert].co[0] - geo.location[0])
                                        cvoy.append(mesh.vertices[vert].co[1] - geo.location[1])
                                        cvoz.append(mesh.vertices[vert].co[2] - geo.location[2])
                                        cverts.append(vert)

                                geo['cverts'] = cverts
                                geo['cvox'] = cvox
                                geo['cvoy'] = cvoy
                                geo['cvoz'] = cvoz
                        if geo['calc'] == 1:
                            geo['cfaces'] = csf

                        if self.scene.livi_export_calc_points == "1":
                            self.reslen = len(calcsurfverts)
                        else:
                            self.reslen = len(calcsurffaces)
                else:
                    geo['calc'] = 0
                    for mat in geo.material_slots:
                        mat.material.use_transparent_shadows = True

                self.export = 1
            rtrace.close()

        else:
            self.export = 0
            for geo in self.scene.objects:
                if geo.type == 'MESH' and geo.name != 'lightarray':
                    if not geo.data.materials:
                        export_op.report({'ERROR'},"Make sure your object "+geo.name+" has an associated material")

    def fexport(self, frame, export_op):
        try:
            subprocess.call("oconv -w "+self.lights(frame)+" "+self.sky(frame)+" "+self.mat(frame)+" "+self.poly(frame)+" > "+self.filebase+"-"+str(frame)+".oct", shell=True)
        except Exception as e:
            print(e)
            export_op.report({'ERROR'},"There is a problem with geometry export. If created in another package simplify te geometry, and turn off smooth shading")
        self.scene.livi_display_panel = 0
        export_op.report({'INFO'},"Export is finished")
        self.scene.frame_set(0)
#Compute solar position (altitude and azimuth in degrees) based on day of year (doy; integer), local solar time (lst; decimal hours), latitude (lat; decimal degrees), and longitude (lon; decimal degrees).
def solarPosition(doy, lst, lat, lon):
    #Set the local standard time meridian (lsm) (integer degrees of arc)
    lsm = int(lon/15)*15
    #Approximation for equation of time (et) (minutes) comes from the Wikipedia article on Equation of Time
    b = 2*math.pi*(doy-81)/364
    et = 9.87 * math.sin(2*b) - 7.53 * math.cos(b) - 1.5 * math.sin(b)
    #The following formulas adapted from the 2005 ASHRAE Fundamentals, pp. 31.13-31.16
    #Conversion multipliers
    degToRad = 2*math.pi/360
    radToDeg = 1/degToRad
    #Apparent solar time (ast)
    ast = lst + et/60 + (lsm-lon)/15
    #Solar declination (delta) (radians)
    delta = degToRad*23.45 * math.sin(2*math.pi*(284+doy)/365)
    #Hour angle (h) (radians)
    h = degToRad*15 * (ast-12)
     #Local latitude (l) (radians)
    l = degToRad*lat
    #Solar altitude (beta) (radians)
    beta = asin(cos(l) * cos(delta) * cos(h) + sin(l) * sin(delta))
    #Solar azimuth phi (radians)
    phi = acos((sin(beta) * sin(l) - sin(delta))/(cos(beta) * cos(l)))
    #Convert altitude and azimuth from radians to degrees, since the Spatial Analyst's Hillshade function inputs solar angles in degrees
    altitude = radToDeg*beta
    if ast<=12:
        azimuth = radToDeg*phi
    else:
        azimuth = 360 - radToDeg*phi
    return([altitude, azimuth])

def negneg(x):
    if float(x) < 0:
        x = 0
    return float(x)


###########################################################
    #  CSE 231 Project #9
    #
    #  Dictionaries and Functions
    #    open and read CSV files
    #       read for certain values in a CSV file
    #    output appropriate value in the function
    #       call appropriate functions
    #    display closing message
    #
    ###########################################################

import csv
import matplotlib.pyplot as plt
plt.style.use("ggplot")
from operator import itemgetter

def open_file():
    ''' This function prompts for a file and opens it in read '''
    x = True
    #create a loop until correct file is input
    while x is True:
        try:
            filename = input("Data file: ")
            if filename == '':
                fp = open('ncov.csv', 'r')
            else:
                fp = open(filename, 'r')
            x = False
        #output error message
        except FileNotFoundError:
            print("Error. Try again.")
    #return openned file
    return fp

def build_dictionary(fp):
    ''' This function accepts the file pointer as input and returns the required dictionary '''
    #read csv file and create a master list
    reader = csv.reader(fp)
    next(reader,None)
    master_list = []
    #append master_list with each line list
    for i in reader:
        master_list.append(i)
    #create an empty dictionary for all the countries
    master_dict = {}
    for line in master_list:
        #iterate through each value in the master list
        areadict = {}
        country = line[2].strip()
        area = line[1].strip()
        if area == '':
            area = 'N/A'
        last_update = line[3].strip()
        cases = int(line[4].strip())
        deaths = int(line[5].strip())
        recovered = int(line[6].strip())
        #create a tuple to add into a smaller dictionary
        area_tup = (last_update, cases, deaths, recovered)
        areadict[area] = area_tup
        if country in master_dict:
            #if country is already in dictionary then append the smaller dictionary to the list
            master_dict[country].append(areadict)
        else:
            #if country is not already in dictionary then create a list with the smaller dictionary
            master_dict[country] = [areadict]
    #return the dictionary
    return master_dict

def top_affected_by_spread(master_dict):
    ''' This function accepts the dictionary and returns a list of the top 10 most affected countries '''
    #create an empty list
    area_list = []
    #iterate through each list in the dictionary
    for key,value in master_dict.items():
        #append the country and the length of its list to area list created above
        x = len(value)
        area_tup = (key, x)
        area_list.append(area_tup)
    #sort the list alphabetically and numerically
    area_list.sort()
    area_list.sort(key = itemgetter(1), reverse = True)
    #return the top ten results
    return area_list[:10]

def top_affected_by_numbers(master_dict):
    ''' This function accepts the dictionary and returns a list of the countries with the top 10 cases '''
    #create an empty list
    area_list = []
    #iterate through each list in the dictionary
    for key,value in master_dict.items():
        x = 0
        #iterate through each dictionary in the list
        for case in value:
            #iterate through each value in the dictionary
            for i in case.values():
        #find the sum of the values and append the tuple to area list
                x += i[1]
        area_tup = (key, x)
        area_list.append(area_tup)
    #sort the list alphabetically and numerically
    area_list.sort()
    area_list.sort(key = itemgetter(1), reverse = True)
    #return the top ten results
    return area_list[:10]

def is_affected(master_dict, country):
    ''' This function accepts in the dictionary and a country and returns a Boolean on whether a country is affected '''
    #set country to lowercase and provide a false boolean variable
    country = country.lower()
    x = False
    #iterate through the keys in the dictionary
    for keys in master_dict.keys():
        #change the boolean variable if the country matches the key
        if country == keys.lower():
            x = True
        #if country is not in the dictionary then continue
        else:
            continue
    #return the boolean
    return x

def plot_by_numbers(list_of_countries, list_of_numbers):
    '''
        This function plots the number of areas/people inffected by country.

        parameters:
            list_of_countries: list of countries
            list_of_numbers: list of the number of areas/people inffected

        Returns: None
    '''
    fig, ax = plt.subplots()

    x_pos = [i for i, _ in enumerate(list_of_countries)]

    ax.barh(x_pos, list_of_numbers, align='center', color='red')
    ax.set_yticks(x_pos)
    ax.set_yticklabels(list_of_countries)
    ax.invert_yaxis()
    ax.set_xlabel('Count')
    ax.set_title('Novel Coronavirus statistics')

    plt.show()

def affected_states_in_country(master_dict, country):
    ''' This function accepts in the dictionary and a country and returns a set of affected areas '''
    #set country to lowercase and create an empty set
    country = country.lower()
    areas = set()
    #iterate through each item in the dictionary
    for keys,values in master_dict.items():
        #find a country that matches a key
        if country == keys.lower():
            #iterate through each key in each dictionary in the list
            for i in values:
                for area in i.keys():
                    #add the area to the empty set
                    areas.add(area)
        #if country is not in the dictionary then continue
        else:
            continue
    #return the set
    return areas

def main():
    BANNER = '''
.__   __.   ______   ______   ____    ____
|  \ |  |  /      | /  __  \  \   \  /   /
|   \|  | |  ,----'|  |  |  |  \   \/   /
|  . `  | |  |     |  |  |  |   \      /
|  |\   | |  `----.|  `--'  |    \    /
|__| \__|  \______| \______/      \__/
    '''
    print(BANNER)
    MENU = '''
[1] Countries with most areas infected
[2] Countries with most people affected
[3] Affected areas in a country
[4] Check if a country is affected
[5] Exit

Choice: '''
    #open file and call dictionary function
    fp = open_file()
    master_dict = build_dictionary(fp)
    x = True
    y = True
    #create a loop to prompt for the choices
    while y ==True:
        #create a nested loop to produce the error line in case of an error
        while x == True:
            #prompt for choice between 1 and 5
            try:
                choice = int(input(MENU))
                if 1 <= choice <= 5:
                    break
                #raise error if choice does not satisfy rules
                else:
                    raise ValueError
            #print error statement and loop
            except:
                print("Error. Try again.")

        if choice == 1:
            #create a table for areas affected
            print("{:<20s} {:15s}".format("Country", "Areas affected"))
            print("-"*40)
            #call function
            areas = top_affected_by_spread(master_dict)
            #create empty plot lists for x and y values
            plot_x = []
            plot_y = []
            #iterate through the tuples and print the values appropriately
            for tups in areas:
                area = tups[0]
                number = tups[1]
                #add the values to the plot lists
                plot_x.append(area)
                plot_y.append(number)
                print("{:<20s} {:5d}".format(area,number))
            #plot first five points if plot prompt is yes
            plot = input('Plot? (y/n) ')
            if plot == 'y':
                plot_by_numbers(plot_x[:5],plot_y[:5])

        if choice == 2:
            #create a table for people affected
            print("{:<20s} {:15s}".format("Country", "People affected"))
            print("-"*40)
            #call function
            areas = top_affected_by_numbers(master_dict)
            #create empty plot lists for x and y values
            plot_x = []
            plot_y = []
            #iterate through the tuples and print the values appropriately
            for tups in areas:
                area = tups[0]
                number = tups[1]
                #add the values to the plot lists
                plot_x.append(area)
                plot_y.append(number)
                print("{:<20s} {:5d}".format(area,number))
            #plot first five points if plot prompt is yes
            plot = input('Plot? (y/n) ')
            if plot == 'y':
                plot_by_numbers(plot_x[:5],plot_y[:5])

        if choice == 3:
            #prompt for a country and create table
            country = input("Country name: ")
            print("-"*30)
            #call function
            states = affected_states_in_country(master_dict,country)
            #if country is not in dictionary (or set is empty) then print error line
            if len(states) == 0:
                print("Error. Country not found.")
            else:
                #create table for the affected areas
                print("{:<30s}".format("Affected area"))
                print("-"*30)
                val = 1
                for state in sorted(states):
                    print("[{:02d}] {:<30s}".format(val,state))
                    val += 1

        if choice == 4:
            #prompt for a country and create table
            country = input("Country name: ")
            print("-"*30)
            #call function
            covid = is_affected(master_dict, country)
            #print appropriate lines
            if covid == True:
                print("{} is affected.".format(country))
            else:
                print("{} is not affected.".format(country))

        if choice == 5:
            #print exit line and break loop
            print("Stay at home. Protect your community against COVID-19")
            break

if __name__ == "__main__":
    #call main function
    main()


# This is a sample Python script.

# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.
import os
import gym
import gym_donkeycar
import numpy as np
def print_hi(name):
    # Use a breakpoint in the code line below to debug your script.
    print(f'Hi, {name}')  # Press Ctrl+F8 to toggle the breakpoint.

# Press the green button in the gutter to run the script.
if __name__ == '__main__':

    # SET UP ENVIRONMENT
    # You can also launch the simulator separately
    # in that case, you don't need to pass a `conf` object
    exe_path = "/home/mao/mysim/DonkeySimLinux/donkey_sim.x86_64"
    port = 9091

    conf = {"exe_path": exe_path, "port": port}

    env = gym.make("donkey-generated-track-v0", conf=conf)

    # PLAY
    obs = env.reset()
    for t in range(100):
        action = np.array([0.2, 0.1])  # drive straight with small speed
        # execute the action
        obs, reward, done, info = env.step(action)

    # Exit the scene
    env.close()

# See PyCharm help at https://www.jetbrains.com/help/pycharm/


"""
Tests for identifying XSS vulnerabilities.
This is currently done when the "q" method is called.
"""
from __future__ import absolute_import

import os
from mock import patch
import pytest

from bok_choy.page_object import XSSExposureError
from bok_choy.web_app_test import WebAppTest
from .pages import SitePage

class XSSExposureTest(WebAppTest):
    """
    Tests for identifying XSS vulnerabilities.
    """
    def __init__(self, *args, **kwargs):
        super(XSSExposureTest, self).__init__(*args, **kwargs)
        self.site_page = None

    def _visit_page(self, page_name):
        """
        Instantiate a ``SitePage`` for the given base filename and visit it.
        """
        self.site_page = SitePage(self.browser)
        self.site_page.name = page_name
        self.site_page.visit()

    @patch.dict(os.environ, {'VERIFY_XSS': 'True'})
    def test_html_exposure(self):
        self._visit_page("xss_html")
        with pytest.raises(XSSExposureError) as excinfo:
            self.site_page.q(css='.unescaped')
        assert '2 XSS issue' in str(excinfo)

    @patch.dict(os.environ, {'VERIFY_XSS': 'True'})
    def test_js_exposure(self):
        self._visit_page("xss_js")
        with pytest.raises(XSSExposureError) as excinfo:
            self.site_page.q(css='.unescaped')
        assert '1 XSS issue' in str(excinfo)

    @patch.dict(os.environ, {'VERIFY_XSS': 'True'})
    def test_mixed_exposure(self):
        self._visit_page("xss_mixed")
        with pytest.raises(XSSExposureError) as excinfo:
            self.site_page.q(css='.unescaped')
        assert '2 XSS issue' in str(excinfo)

    @patch.dict(os.environ, {'VERIFY_XSS': 'True'})
    def test_escaped(self):
        self._visit_page("xss_safe")
        self.site_page.q(css='.escaped')

    @patch.dict(os.environ, {'VERIFY_XSS': 'False'})
    def test_xss_testing_disabled_explicitly(self):
        self._visit_page("xss_html")
        self.site_page.q(css='.unescaped')

    def test_xss_testing_disabled_by_default(self):
        self._visit_page("xss_html")
        self.site_page.q(css='.unescaped')


from urllib.request import urlopen
from bs4 import BeautifulSoup as bsoup

url = 'http://www.pythonscraping.com/pages/warandpeace.html'

html = urlopen(url)
bs = bsoup(html, 'html.parser')

nameList = bs.find_all('span', {'class': 'green'})
for name in nameList:
    print(name.get_text())

nameList = bs.find_all(text='the prince')
print(f'"the prince" frequency: {len(nameList)}')

title = bs.find(id='title')
print(f'Title: {title}')

2 Advanced HTML Parsing/parsespantags.py