# Import necessary libraries
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
import pickle
from flask import Flask, render_template, request

# Load the data
data = pd.read_csv('df.csv')

# Split the data into training and testing sets
X = data[['bookid']]
y = data['rating']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# Train the model
model = RandomForestRegressor()
model.fit(X_train, y_train)

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

# Create a Flask app
app = Flask(__name__)

# Define a route to render the form
@app.route('/')
def form():
    return render_template('form.html')

# Define a route to predict the rating
@app.route('/predict', methods=['POST'])
def predict():
    # Get the book_id from the form
    book_id = request.form['bookid']

    # Use the model to make a prediction
    prediction = model.predict([[book_id]])

    # Return the prediction as a response
    return render_template('result.html', prediction=prediction[0])

if __name__ == '__main__':
    app.run(debug=False,host='0.0.0.0')


"""Models for the users app."""
from django.db import models
from django.contrib.auth.models import User

class Profile(models.Model):
    """
    Created profile model for users.

    Every user will have profile. If the user is deleted the profile will also
    be deleted.
    """

    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE
    )
    image = models.ImageField(
        default='profilepic.jpg',
        upload_to='profile_pictures'
    )
    location = models.CharField(
        max_length=100
    )

    def __str__(self):
        """Represent the profile object as a string."""
        return self.user.username


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Jul  3 11:54:19 2019

"""

# merge od file with mainzone
import pandas
import numpy as np

gpzone = pandas.read_csv(r"D:\METROPOLIS\Brussels calibration\zonetomain.csv", sep=",")
gpzone['MAINZONE'].nunique()
odPW = pandas.read_csv(r"/Users/Desktop/Brussels calibration/s_odPW.tsv", sep="\t")
coordinates = pandas.read_csv(r"/Users/Desktop/Brussels calibration/related files and coor/corr4.csv", sep=",")
#match and insert a "MAINZONE" column
PWzonesgp1 = pandas.merge(odPW,gpzone[['ZONE','MAINZONE']],left_on='origin',right_on='ZONE')
PWzonesgp2 = pandas.merge(PWzonesgp1,gpzone[['ZONE','MAINZONE']],left_on='destination',right_on='ZONE')
PWzonesgp3 = PWzonesgp2.drop_duplicates(subset=['MAINZONE_x','MAINZONE_y'], keep='first')
PWzonesgp4 = pandas.merge(PWzonesgp3,coordinates[['Y','X','id']],left_on='origin',right_on='id')
PWzonesgp5 = pandas.merge(PWzonesgp4,coordinates[['Y','X','id']],left_on='destination',right_on='id')

# importing googlemaps module
import googlemaps
import csv

# Requires API key
#gmaps = googlemaps.Client(key='')

###########################################################
# queries
#my_dist=[]
for i in range(0,9016):
    my_dist.append(gmaps.distance_matrix((PWzonesgp5['Y_x'][i],PWzonesgp5['X_x'][i]),(PWzonesgp5['Y_y'][i],PWzonesgp5['X_y'][i])
                                ,mode="transit")['rows'][0]['elements'][0] )

# Printing the result
#print(my_dist)

# write to tsv
pandas.DataFrame.from_dict(data=my_dist,orient='columns').to_csv('test_pt.csv',header=True)

#write results and google coordinates of o and d to tsv
pt1=open(r'/Users/Desktop/Brussels calibration/pt1.csv','w')
s=[]
u=[]
ocx=[]
ocy=[]
ozone=[]
omzone=[]
dcx=[]
dcy=[]
dzone=[]
dmzone=[]
for k in range(0,len(my_dist)):
    if my_dist[k]['status']=='OK':
        s.append(my_dist[k]['distance']['text'])
        u.append(my_dist[k]['duration']['text'])
    else:
        s.append('NA')
        u.append('NA')
for i in range(0,9016):
           ocx.append(PWzonesgp5['Y_x'][i])
           ocy.append(PWzonesgp5['X_x'][i])
           ozone.append(PWzonesgp5['ZONE_x'][i])
           omzone.append(PWzonesgp5['MAINZONE_x'][i])
           dcx.append(PWzonesgp5['Y_y'][i])
           dcy.append(PWzonesgp5['X_y'][i])
           dzone.append(PWzonesgp5['ZONE_y'][i])
           dmzone.append(PWzonesgp5['MAINZONE_y'][i])

rows = zip(s,u,ocx,ocy,ozone,omzone,dcx,dcy,dzone,dmzone)
with open (r'/Users/Desktop/Brussels calibration/pt1.csv','w') as csvout:
    writer = csv.writer(csvout,delimiter=',',lineterminator='\n')
    for row in rows:
        writer.writerow(row)

#remove units of the columns
with open(r'/Users/Desktop/Brussels calibration/pt1.csv','r') as csvin, open(r'/Users/Desktop/Brussels calibration/pt2.csv','w') as csvout:
    csvin = csv.reader(csvin, delimiter=',',lineterminator='\n')
    csvout = csv.writer(csvout, delimiter=',',lineterminator='\n')

    for line in csvin:
        line[0] = line[0][:-3] #delete km
        if 'hour' not in line[1]:
            line[1] = line[1][:-5] #delete mins
        elif 'hours'in line[1]:
            h,m =line[1].split("hours")
            if 'mins'in m:
                m= m[:-5] #delete mins
            else:
                m = m[:-4]
            m = float(m)
            h=float(h)
            line[1]=60*float(h)+float(m)

        else:
            h,m =line[1].split("hour")
            if 'mins'in m:
                m= m[:-5] #delete mins
            else:
                m = m[:-4]

            m = float(m)
            h=float(h)
            line[1]=60*float(h)+float(m)

        csvout.writerow(line)

pttime = pandas.read_csv(r"/Users/Desktop/Brussels calibration/pt2.csv", sep=",")
PWzonesgp2.rename(columns={'MAINZONE_x':'omzone','MAINZONE_y':'dmzone'},
                 inplace=True)
pttime1 = pandas.merge(PWzonesgp2,pttime[['distance','travel time','omzone','dmzone']],on=['omzone', 'dmzone'])

pttime1.rename(columns={'travel time':'traveltime'},
                 inplace=True)
pttime1.fillna(10,inplace=True)

pttime1.rename(columns={'traveltime':'travel time'},
                 inplace=True)
pttime1[['origin','destination','travel time']].to_csv(r"/Users/Desktop/pttime.tsv",sep="\t",index=False)
pttime1.to_csv(r"/Users/Desktop/pttime_full.tsv",sep="\t",index=False)


# -*- coding: utf-8 -*-

# Looks for musical samples in arbitrary audio
# Adapted from: https://github.com/kylemcdonald/AudioNotebooks/blob/master/Multisamples%20to%20Samples.ipynb
# Usage:
    # python audio_to_images.py -plot 1
    # python audio_to_images.py -save 1
    # python audio_to_images.py -in "../data/usergen/saved_birds.json"

import argparse
import csv
import glob
import json
import librosa
from librosa import display
import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms
from multiprocessing import Pool
from multiprocessing.dummy import Pool as ThreadPool
import os
from os.path import join
import numpy as np
from pprint import pprint
import sys

# input
parser = argparse.ArgumentParser()
parser.add_argument('-in', dest="INPUT_FILES", default="../data/usergen/saved_birds.json", help="Input file pattern")
parser.add_argument('-dir', dest="INPUT_AUDIO_DIR", default="../audio/downloads/birds/%s.mp3", help="Input audio directory")
parser.add_argument('-save', dest="SAVE", default=0, type=int, help="Save files?")
parser.add_argument('-plot', dest="PLOT", default=0, type=int, help="Show plot?")
parser.add_argument('-width', dest="WIDTH", default=3600, type=int, help="Target width")
parser.add_argument('-height', dest="HEIGHT", default=600, type=int, help="Target height")
parser.add_argument('-out', dest="OUTPUT_FILE", default="../data/output/images/%s.png", help="Output file pattern")
parser.add_argument('-overwrite', dest="OVERWRITE", default=0, type=int, help="Overwrite existing images?")
args = parser.parse_args()

# Parse arguments
INPUT_FILES = args.INPUT_FILES
INPUT_AUDIO_DIR = args.INPUT_AUDIO_DIR
SAVE = args.SAVE > 0
PLOT = args.PLOT > 0
OUTPUT_FILE = args.OUTPUT_FILE
OVERWRITE = args.OVERWRITE > 0

# Audio config
FFT = 2048
HOP_LEN = FFT/4

# Read files
files = []
if "*" in INPUT_FILES:
    files = glob.glob(INPUT_FILES)
elif ".json" in INPUT_FILES:
    with open(INPUT_FILES) as f:
        files = [INPUT_AUDIO_DIR % fn for fn in json.load(f)]

fileCount = len(files)
print("Found %s files" % fileCount)

# Make sure output dirs exist
outDirs = [os.path.dirname(OUTPUT_FILE)]
for outDir in outDirs:
    if not os.path.exists(outDir):
        os.makedirs(outDir)

progress = 0
# files = files[:1]

def makeImage(fn):
    global progress
    basename = basename = os.path.splitext(os.path.basename(fn))[0]
    fileout = OUTPUT_FILE % basename
    w = 24
    h = 8

    y, sr = librosa.load(fn)
    D = librosa.amplitude_to_db(np.abs(librosa.stft(y)), ref=np.max)

    figure = plt.figure(figsize=(3600, 600), dpi=1)
    librosa.display.specshow(D, y_axis='log')

    if PLOT:
        plt.show()

    if SAVE and (OVERWRITE or not os.path.isfile(fileout)):
        axis = plt.subplot(1, 1, 1)
        plt.axis('off')
        plt.tick_params(axis='both', left='off', top='off', right='off', bottom='off', labelleft='off', labeltop='off', labelright='off', labelbottom='off')
        extent = axis.get_window_extent().transformed(figure.dpi_scale_trans.inverted())
        pts = extent.get_points()
        pad = 3.5
        pts[0][0] += pad
        pts[0][1] += pad
        pts[1][0] -= pad
        pts[1][1] -= pad
        extent.set_points(pts)
        plt.savefig(fileout, bbox_inches=extent, pad_inches=0)
        # print("Saved %s" % fileout)
    plt.cla()
    plt.clf()
    plt.close()

    progress += 1
    sys.stdout.write('\r')
    sys.stdout.write("%s%%" % round(1.0*progress/fileCount*100,1))
    sys.stdout.flush()

    return fileout

# pool = ThreadPool()
# data = pool.map(makeImage, files)
# pool.close()
# pool.join()
for fn in files:
    makeImage(fn)


import django_filters
from django_filters import DateFilter

from django import forms

from .models import *

class DateInput(forms.DateInput):
    input_type = 'date'

class ExpenseFilter(django_filters.FilterSet):
    start_date = DateFilter(field_name="transaction_date", lookup_expr='gte')
    end_date = DateFilter(field_name="transaction_date", lookup_expr='lte')

    class Meta:
        model = Expense
        fields = '__all__'
        exclude = ['image', 'description', 'date_created',
                   'amount', 'transaction_date', 'title']
        # widgets = {
        #     'transaction_date': forms.DateField(attrs={'type': 'date'})
        # }


# Assignment: Take the radious as input from the user
# and calculate the area using 3.14 as Pi

def main():
    radius = float(input("What is the radius of the circle you want me to calculate: "))

    area = 3.14 * radius ** 2

    print("The area of the circle is %0.2f" %area)

if __name__ == '__main__':
    main()


import math

"""
    Running time O(N)
    space time O(1)
"""

def shortestSubarray(s, arr):
    start, total, min_len = 0, 0, math.inf
    for i in range(len(arr)):
        total += arr[i]
        while total >= s:
            min_len = min(min_len, i - start + 1)
            total -= arr[start]
            start += 1
    return min_len if min_len != math.inf else 0

def longestSubarray(s, arr):
    start, end, max_len = 0, 0, 0
    total = 0
    while end < len(arr):
        if total > s:
            total -= arr[start]
            start += 1
        while total <= s and end < len(arr):
            max_len = max(max_len, end - start)
            total += arr[end]
            end += 1
    return max_len

def longestSubarrayWithCertainSum(s, arr):
    start, end, max_len, total = 0, 0, 0, 0
    stop = len(arr)
    while end < stop:
        if total > s:
            total -= arr[start]
            start += 1
        while total < s and end < stop:
            total += arr[end]
            end += 1
        if total == s:
            max_len = max(max_len, end-start)
            total -= arr[start]
            start += 1
    return max_len

def shortestSubarryWithLessThanSum(s, arr):
    start, total, min_len = 0, 0, math.inf
    for i in range(len(arr)):
        temp = arr[i] + total
        if temp > arr[i]:
            start = i
            total = arr[i]
        else:
            total = temp
        while total <= s and start <= i:
            min_len = min(i-start + 1, min_len)
            total -= arr[start]
            start += 1
    return min_len

# def longestSubarrayWithMoreThanSum(s, arr):
#     start, end, max_len, total = 0, 0, 0, 0
#     stop = len(arr)
#     pre_info = {
#         "prev_sum" : 0,
#         "start" : None
#     }
#     while end < stop:
#         temp = total + arr[end]
#         if temp < arr[end]:
#             start = end
#             total = arr[end]
#         else:
#             total = temp
#         while total > s:
#             max_len = max(max_len, end - start + 1)
#             if total > pre_info["prev_sum"]:

# https://www.geeksforgeeks.org/largest-subarray-having-sum-greater-than-k/

if __name__ == "__main__":
    print(shortestSubarryWithLessThanSum(-2, [1, -1, -1, 4, 5]))


import json
from pamda import pamda
from scgraph.utils import hard_round, distance_converter
from collections import Counter

# This `geojson_file` is not comitted in the git repo for size reasons
# It can be downloaded from:
# https://geodata.bts.gov/datasets/usdot::north-american-rail-network-lines-class-i-freight-railroads-view/about
geojson_file = "utils/north_america_rail_network.geojson"
out_filename = "scgraph/geographs/north_america_rail.py"
initialized_class_name = "north_america_rail_geograph"

data_geojson = json.load(open(geojson_file, "r"))

def lessThanAbs(threshold, a):
    abs_a = abs(a)
    while abs_a > threshold:
        abs_a -= threshold
    return abs_a * (1 if a > 0 else -1)

def format_coord_pair(coord_pair):
    try:
        return [lessThanAbs(180,hard_round(3, coord_pair[0])), lessThanAbs(90,hard_round(3, coord_pair[1]))]
    except:
        print(coord_pair)
        raise Exception()

def get_agg_arc(origin, destination, arcs_dict):
    distance = 0
    current_node = origin
    next_node = destination
    arc_dict = arcs_dict.get(current_node)
    while True:
        distance += arc_dict.get(next_node, 0)
        arc_dict = arcs_dict.get(next_node)
        if len(arc_dict)!=2:
            break
        new_next_node = [k for k in arc_dict.keys() if k != current_node][0]
        current_node = next_node
        next_node = new_next_node
    return {
        'origin':origin,
        'destination':next_node,
        'distance':round(distance,3),
    }

def invert_arc(arc):
    return {
        'origin':arc['destination'],
        'destination':arc['origin'],
        'distance':arc['distance'],
    }

def agg_arcs(arcs, remove_tips:bool=False, tip_threshold:int=5):
    arcs_dict = {}
    for arc in arcs:
        arcs_dict = pamda.assocPath([str(arc['origin']),str(arc['destination'])], arc['distance'], arcs_dict)
        arcs_dict = pamda.assocPath([str(arc['destination']),str(arc['origin'])], arc['distance'], arcs_dict)

    intersections = [k for k, v in arcs_dict.items() if len(v) > 2]
    tips = set([k for k, v in arcs_dict.items() if len(v) == 1])

    agg_arcs = []
    for intersection in intersections:
        for outbound in arcs_dict.get(intersection):
            agg_arc = get_agg_arc(intersection, outbound, arcs_dict)
            if remove_tips:
                # Remove all small arcs that are connected to tips (short offshoots - eg to local factories)
                if agg_arc['origin'] in tips or agg_arc['destination'] in tips:
                    if agg_arc['distance']<tip_threshold:
                        continue
            agg_arcs.append(agg_arc)
            agg_arcs.append(invert_arc(agg_arc))
    return agg_arcs

def get_arcs(geojson):
    arcs = [{
        'origin':format_coord_pair(arc['geometry']['coordinates'][0][0]),
        'destination':format_coord_pair(arc['geometry']['coordinates'][0][-1]),
        'distance':round(distance_converter(distance=pamda.path(["properties","MILES"], arc), input_units='mi', output_units='km'),2),
    } for arc in geojson["features"]]
    # Aggregate up arcs then remove arcs with tips that are too short
    arcs_no_tips = agg_arcs(arcs, remove_tips=True, tip_threshold=5)
    # After removing tips, aggregate up arcs again to merge arcs on intersections that were previously broken by a tip
    return agg_arcs(arcs_no_tips, remove_tips=False)

arcs = get_arcs(data_geojson)

raw_nodes = {}
for i in arcs:
    origin = json.loads(i['origin'])
    raw_nodes[str(origin)] = {"longitude": origin[0], "latitude": origin[1]}

key_mapping = {node_id:idx for idx, node_id in enumerate(raw_nodes.keys())}
nodes = {key_mapping[node_id]: node for node_id, node in raw_nodes.items()}
graph = {}
for arc in arcs:
    origin_id = key_mapping[arc['origin']]
    destination_id = key_mapping[arc['destination']]
    pamda.assocPath([origin_id, destination_id], arc['distance'], graph)
    pamda.assocPath([destination_id, origin_id], arc['distance'], graph)

out_string = f"""
from scgraph.core import GeoGraph
graph={str(graph)}
nodes={str(nodes)}
{initialized_class_name} = GeoGraph(graph=graph, nodes=nodes)
"""

with open(out_filename, "w") as f:
    f.write(out_string)


import time
from pathlib import Path
import pandas as pd
import cv2
from skimage import transform
from src import radon, iradon

if __name__ == '__main__':
    imagePath = Path('res')
    file_name_list = list(imagePath.glob('shepp-logan*.jpg'))

    method_list = ['my algorithm', 'skimage']

    results = []

    for file in file_name_list:
        print('begin ' + str(file))
        for method in method_list:
            if method == 'my algorithm':
                radon1 = radon
                iradon1 = iradon
            else:
                radon1 = transform.radon
                iradon1 = transform.iradon
            img = cv2.imread(str(file), cv2.IMREAD_GRAYSCALE)
            start1 = time.time()
            sinogram = radon1(img)
            end1 = time.time()

            start2 = time.time()
            reconstruct = iradon1(sinogram, filter_name=None)
            end2 = time.time()

            start3 = time.time()
            filtered_reconstruct = iradon1(sinogram, filter_name='ramp')
            end3 = time.time()

            results.append({'file': file, 'method': method, 'radon': end1 - start1, 'iradon(direct)': end2 - start2,
                            'iradon(filter)': end3 - start3})

    df = pd.DataFrame(results).round(2)
    df.set_index(['file', 'method'], inplace=True)
    df.to_csv('time_cost.csv')


import mariadb as db
import DbInteractions.dbhandler as dbh
import traceback
import secrets

# Function to delete a login token(log a user out)

def delete_login(loginToken):
    conn, cursor = dbh.db_connect()
    try:
        # Delete statement, commit disconnect and return true
        cursor.execute(
            "DELETE FROM user_session WHERE logintoken = ? ", [loginToken])
        conn.commit()
    except db.OperationalError:
        traceback.print_exc()
        print('Something went  wrong with the db!')
    except db.ProgrammingError:
        traceback.print_exc()
        print('Error running DB query')
    except:
        traceback.print_exc()
        print("Something unexpected went wrong")
    dbh.db_disconnect(conn, cursor)
    return True

# Function that creates a new user session(log a user in)

def post_login(email, username, pass_hash):
    user = []
    userId = None
    conn, cursor = dbh.db_connect()
    try:
        # Check to see wether we are passed the username or email, and based on which does not have a value of None is which statement is ran to get the userId.
        if(email != None):
            cursor.execute(
                "SELECT `user`.id FROM `user` WHERE email = ? and password = ?", [email, pass_hash])
            userId = cursor.fetchone()
            userId = userId[0]
        elif(username != None):
            cursor.execute(
                "SELECT `user`.id FROM `user` WHERE username = ? and password = ?", [username, pass_hash])
            userId = cursor.fetchone()
            userId = userId[0]
        # Insert statement to insert a session to the user_session table based on the userId we get above. Commit the changes
        token = secrets.token_urlsafe(40)
        cursor.execute(
            "INSERT INTO user_session (user_id, logintoken) VALUES (?, ?)", [userId, token])
        conn.commit()
        # Select statement to grab information about the user, aswell as the just created login token, save data to variable change it to an object and return the data
        cursor.execute(
            "SELECT `user`.id, email, username, bio, birthdate, imageUrl, bannerUrl, loginToken FROM `user` inner join user_session on `user`.id = user_session.user_id WHERE `user`.id = ?", [userId])
        user = cursor.fetchone()
        user = {
            'userId': user[0],
            'email': user[1],
            'username': user[2],
            'bio': user[3],
            'birthdate': user[4],
            'imageUrl': user[5],
            'bannerUrl': user[6],
            'loginToken': user[7]
        }
    except db.OperationalError:
        traceback.print_exc()
        print('Something went  wrong with the db!')
    except db.ProgrammingError:
        traceback.print_exc()
        print('Error running DB query')
    except:
        traceback.print_exc()
        print("Something unexpected went wrong")
    dbh.db_disconnect(conn, cursor)
    return True, user


'''
Arduino
requirement:
    pip3 install pymata-aio --user
'''
import zmq
import subprocess
import pathlib
import platform
import time
import threading

from codelab_adapter import settings
from codelab_adapter.core_extension import Extension

def get_python3_path():
    # If it is not working,  Please replace python3_path with your local python3 path. shell: which python3
    if (platform.system() == "Darwin"):
        # which python3
        # 不如用PATH python
        # 不确定
        path = "/usr/local/bin/python3"
    if platform.system() == "Windows":
        path = "python3"
    if platform.system() == "Linux":
        path = "/usr/bin/python3"
    return path

python3_path = get_python3_path()

class arduinoExtension(Extension):
    def __init__(self):
        name = type(self).__name__  # class name
        super().__init__(name)
        self.scratch3_message = {}
        self.TOPIC = "eim/arduino"
        self.first_start = 1

    def run(self):
        # 抽象掉这部分 Class
        port = 38782  # todo 随机分配
        context = zmq.Context.instance()
        socket = context.socket(zmq.REQ)
        socket.connect("tcp://localhost:%s" % port)

        codelab_adapter_server_dir = pathlib.Path.home(
        ) / "codelab_adapter" / "servers"
        script = "{}/arduino_server.py".format(codelab_adapter_server_dir)

        cmd = [python3_path, script]
        arduino_server = subprocess.Popen(cmd)
        settings.running_child_procs.append(arduino_server)

        lock = threading.Lock()

        def request():
            while self._running:
                lock.acquire()
                self.scratch3_message = self.read()
                lock.release()

        bg_task = threading.Thread(target=request)
        self.logger.debug("thread start")
        bg_task.daemon = True
        bg_task.start()

        while self._running:
            scratch3_message = self.scratch3_message
            self.logger.debug("scratch3_message {}".format(scratch3_message))
            self.scratch3_message = {}
            if scratch3_message == {}:
                scratch3_message = {"topic": self.TOPIC, "payload": ""}

            topic = scratch3_message.get('topic')
            arduino_code = scratch3_message.get("payload")

            if  topic == self.TOPIC:
                socket.send_json({"arduino_code": arduino_code})

            result = socket.recv_json().get("result")

            if self.first_start == 1:
                self.publish({"topic": "eim/arduino/init","payload": ""})
                self.first_start = 0

            # 发往scratch3.0
            self.publish({"topic": self.TOPIC,"payload": result})
            time.sleep(0.05)

        # release socket
        socket.send_json({"arduino_code": "quit!"})
        result = socket.recv_json().get("result")
        arduino_server.terminate()
        arduino_server.wait()
        socket.close()
        context.term()

export = arduinoExtension


from django.shortcuts import render, get_object_or_404, HttpResponseRedirect, redirect
from .models import Post
from .forms import PostForm

# Create your views here.

def gallery(request):
    posts = Post.objects.all()
    return render(request, 'gallery/gallery.html', {'posts': posts})
def drawing(request):
    posts = Post.objects.all().filter(drawing_or_design='drawing')
    return render(request, 'gallery/drawing.html', {'posts': posts})
def design(request):
    posts = Post.objects.filter(drawing_or_design='design')
    return render(request, 'gallery/design.html', {'posts': posts})

def create(request):
    if request.method == "POST":
        form = PostForm(request.POST, request.FILES)
        if form.is_valid():
            post = form.save()
            return HttpResponseRedirect(post.get_absolute_url())

    else:
        form = PostForm()

    context = {
        'form': form,
    }

    # title = request.POST.get('title')
    # image = request.POST.get('image')
    # publishing_date = request.POST.get('publishing_date')
    # Post.objects.create(title=title, image=image, publishing_date=publishing_date)

    return render(request, 'gallery/create.html', context)
def detail(request, id):
    post = get_object_or_404(Post, id=id)
    context = {
        'post': post,
    }
    return render(request, 'gallery/detail.html', context)
def delete(request, id):
    post = get_object_or_404(Post, id=id)
    post.delete()
    return redirect("gallery:gallery")


from django.db import models

class Base(models.Model):
    created = models.DateTimeField('Data de criação', auto_now_add=True)
    updated = models.DateTimeField('Última atualização', auto_now=True)
    availability = models.BooleanField('Disponibilidade', default=True)

    # Configurar para ser usado por qualquer outro modelo
    class Meta:
        abstract = True

class Nouns(Base):
    question = models.CharField('Questão', max_length=100)
    name = models.CharField('Nome do substantivo', max_length=100)
    translation = models.CharField('Tradução do substantivo', max_length=100)

    def __str__(self):
        return self.name

    # Rótulos para o Django template admin
    class Meta:
        verbose_name = 'Substantivo'
        verbose_name_plural = verbose_name + 's'


#polymorphism
class Vscode:
    def execute(self):
        print("Compiling")
        print("Running")

class MyIde:
    def execute(self):
        print("Spell Checking")
        print("Convention Check")
        print("Compiling")
        print("Running")

class Laptop:

    def code(self,ide):
        ide.execute()

ide1=Vscode()       #if it has method execute it will work
ide2=MyIde()
lap1=Laptop()
lap2=Laptop()
lap1.code(ide1)
lap2.code(ide2)


import json
import subprocess
import os

def set_outputs(names_values):
    """Sets the GitHub Action outputs.

    Keyword arguments:
    names_values - Dictionary of output names with values
    """
    if "GITHUB_OUTPUT" in os.environ:
        with open(os.environ["GITHUB_OUTPUT"], "a") as f:
            for name, value in names_values.items():
                print("{0}={1}".format(name, value), file=f)
    else: # Fall-back to deprecated set-output for self-hosted runners
        for name, value in names_values.items():
            print("::set-output name={0}::{1}".format(name, value))

class Statistician:
    """The Statistician class executes GitHub GraphQl queries,
    and parses the query results.
    """

    __slots__ = [
        '_contributionYears',
        '_user',
        '_contrib',
        '_repo',
        '_login',
        '_name',
        '_languages',
        '_autoLanguages',
        '_maxLanguages',
        '_languageRepoExclusions',
        '_featuredRepo'
        ]

    def __init__(
        self,
        fail,
        autoLanguages,
        maxLanguages,
        languageRepoExclusions,
        featuredRepo):
        """The initializer executes the queries and parses the results.
        Upon completion of the intitializer, the user statistics will
        be available.

        Keyword arguments:
        fail - If True, the workflow will fail if there are errors.
        autoLanguages - If True, the number of displayed languages is chosen based on data,
            regardless of value of maxLanguages.
        maxLanguages - The maximum number of languages to display. Must be at least 1. If less than
            1, it treats it as if it was 1.
        languageRepoExclusions - A set of repositories to exclude from language stats
        """
        self._autoLanguages = autoLanguages
        self._maxLanguages = maxLanguages if maxLanguages >= 1 else 1
        self._languageRepoExclusions = languageRepoExclusions
        self._featuredRepo = featuredRepo
        self.ghDisableInteractivePrompts()
        basicStatsQuery = self.loadQuery("/queries/basicstats.graphql",
                                         fail)
        additionalRepoStatsQuery = self.loadQuery("/queries/repostats.graphql",
                                                  fail)
        oneYearContribTemplate = self.loadQuery("/queries/singleYearQueryFragment.graphql",
                                                fail)
        reposContributedTo = self.loadQuery("/queries/reposContributedTo.graphql",
                                                 fail)

        self.parseStats(
            self.executeQuery(basicStatsQuery,
                              failOnError=fail),
            self.executeQuery(additionalRepoStatsQuery,
                              needsPagination=True,
                              failOnError=fail),
            self.executeQuery(reposContributedTo,
                              needsPagination=True,
                              failOnError=fail)
            )
        self.parsePriorYearStats(
            self.executeQuery(
                self.createPriorYearStatsQuery(self._contributionYears, oneYearContribTemplate),
                failOnError=fail
                )
            )

    def getStatsByKey(self, key):
        """Gets a category of stats by key.

        Keyword arguments:
        key - A category key.
        """
        if key == "general":
            return self._user
        elif key == "repositories":
            return self._repo
        elif key == "contributions":
            return self._contrib
        elif key == "languages":
            return self._languages
        else:
            return None # passed an invalid key

    def loadQuery(self, queryFilepath, failOnError=True):
        """Loads a graphql query.

        Keyword arguments:
        queryFilepath - The file with path of the query.
        failOnError - If True, the workflow will fail if there is an error loading the
            query; and if False, this action will quietly exit with no error code. In
            either case, an error message will be logged to the console.
        """
        try:
            with open(queryFilepath, 'r') as file:
                return file.read()
        except IOError:
            print("Error (1): Failed to open query file:", queryFilePath)
            set_outputs({"exit-code" : 1})
            exit(1 if failOnError else 0)

    def parseStats(self, basicStats, repoStats, reposContributedToStats):
        """Parses the user statistics.

        Keyword arguments:
        basicStats - The results of the basic stats query.
        repoStats - The results of the repo stats query.
        """
        # Extract username (i.e., login) and fullname.
        # Name needed for title of statistics card, and username
        # needed if we support committing stats card.
        self._login = basicStats["data"]["user"]["login"]
        self._name = basicStats["data"]["user"]["name"]

        # The name field is nullable, so use the login id if
        # user's public name is null.
        if self._name == None:
            self._name = self._login

        # Extract most recent year data from query results
        pastYearData = basicStats["data"]["user"]["contributionsCollection"]

        # Extract repositories contributes to (owned by others) in past year
        pastYearData[
            "repositoriesContributedTo"] = basicStats[
                "data"]["user"]["repositoriesContributedTo"]["totalCount"]

        # Extract list of contribution years
        self._contributionYears = pastYearData["contributionYears"]
        # Just reorganizing data for clarity
        del pastYearData["contributionYears"]

        # Extract followed and following counts
        self._user = {}
        self._user["followers"] = [
            basicStats["data"]["user"]["followers"]["totalCount"] ]
        self._user["following"] = [
            basicStats["data"]["user"]["following"]["totalCount"] ]
        self._user["joined"] = [ min(self._contributionYears) ]

        # Extract sponsors and sponsoring counts
        self._user["sponsors"] = [
            basicStats["data"]["user"]["sponsorshipsAsMaintainer"]["totalCount"] ]
        self._user["sponsoring"] = [
            basicStats["data"]["user"]["sponsorshipsAsSponsor"]["totalCount"] ]

        #
        if self._featuredRepo != None:
            self._user["featured"] = [ self._featuredRepo ]

        # Extract all time counts of issues and pull requests
        issues = basicStats["data"]["user"]["issues"]["totalCount"]
        pullRequests = basicStats["data"]["user"]["pullRequests"]["totalCount"]

        # Reorganize for simplicity
        repoStats = list(map(lambda x : x["data"]["user"]["repositories"], repoStats))
        reposContributedToStats = list(
            map(lambda x : x["data"]["user"]["topRepositories"], reposContributedToStats))

        # This is the count of owned repos, including all public,
        # but may or may not include all private depending upon token used to authenticate.
        ownedRepositories = repoStats[0]["totalCount"]

        # Count num repos owned by someone else that the user has contributed to
        # NOTE: It doesn't appear that it is currently possible through any query
        # or combination of queries to actually compute this other than for the most recent
        # year's data. Keeping the query in, but changing to leave that stat blank in
        # the SVG.
        repositoriesContributedTo = sum(
            1 for page in reposContributedToStats if page[
                "nodes"] != None for repo in page[
                    "nodes"] if repo["owner"]["login"] != self._login)

        self._contrib = {
            "commits" : [pastYearData["totalCommitContributions"], 0],
            "issues" : [pastYearData["totalIssueContributions"], issues],
            "prs" : [pastYearData["totalPullRequestContributions"], pullRequests],
            "reviews" : [pastYearData["totalPullRequestReviewContributions"], 0],
            # See comment above for reason for this change.
            #"contribTo" : [pastYearData["repositoriesContributedTo"], repositoriesContributedTo],
            "contribTo" : [pastYearData["repositoriesContributedTo"]],
            "private" : [pastYearData["restrictedContributionsCount"], 0]
            }

        # The "nodes" field is nullable so make sure the user owns at least 1 repo.
        if repoStats[0]["totalCount"] > 0:
            # Note that the explicit checks of, if page["nodes"] != None, are
            # precautionary since the above check of totalCount should be sufficient
            # to protect against a null list of repos.

            # Count stargazers, forks of my repos, and watchers
            stargazers = sum(
                repo["stargazerCount"] for page in repoStats if page[
                    "nodes"] != None for repo in page[
                        "nodes"] if not repo["isPrivate"] and not repo["isFork"])
            forksOfMyRepos = sum(
                repo["forkCount"] for page in repoStats if page[
                    "nodes"] != None for repo in page[
                        "nodes"] if not repo["isPrivate"] and not repo["isFork"])
            stargazersAll = sum(
                repo["stargazerCount"] for page in repoStats if page[
                    "nodes"] != None for repo in page[
                        "nodes"] if not repo["isPrivate"])
            forksOfMyReposAll = sum(
                repo["forkCount"] for page in repoStats if page[
                    "nodes"] != None for repo in page[
                        "nodes"] if not repo["isPrivate"])

            # Find repos with most stars and most forks
            try:
                mostStars = max(
                    (repo for page in repoStats if page[
                        "nodes"] != None for repo in page[
                            "nodes"] if not repo["isPrivate"] and not repo["isFork"]),
                    key=lambda x : x["stargazerCount"])["name"]
                self._user["mostStarred"] = [ mostStars ]
            except ValueError:
                pass

            try:
                mostForks = max(
                    (repo for page in repoStats if page[
                        "nodes"] != None for repo in page["nodes"] if not repo[
                            "isPrivate"] and not repo["isFork"]),
                    key=lambda x : x["forkCount"])["name"]
                self._user["mostForked"] = [ mostForks ]
            except ValueError:
                pass

            # Compute number of watchers
            watchers = sum(
                repo["watchers"]["totalCount"] for page in repoStats if page[
                    "nodes"] != None for repo in page["nodes"] if not repo["isPrivate"])

            watchersNonForks = sum(
                repo["watchers"]["totalCount"] for page in repoStats if page[
                    "nodes"] != None for repo in page["nodes"] if not repo[
                        "isPrivate"] and not repo["isFork"])

            # Count of private repos (not accurate since depends on token used to authenticate query,
            # however, all those here are included in count of owned repos.
            privateCount = sum(
                1 for page in repoStats if page[
                    "nodes"] != None for repo in page["nodes"] if repo["isPrivate"])

            publicAll = ownedRepositories - privateCount

            # Counts of archived repos
            publicNonForksArchivedCount = sum(
                1 for page in repoStats if page[
                    "nodes"] != None for repo in page["nodes"] if repo[
                        "isArchived"] and not repo["isPrivate"] and not repo["isFork"])
            publicArchivedCount = sum(
                1 for page in repoStats if page[
                    "nodes"] != None for repo in page["nodes"] if repo[
                        "isArchived"] and not repo["isPrivate"])

            # Counts of template repos
            publicNonForksTemplatesCount = sum(
                1 for page in repoStats if page[
                    "nodes"] != None for repo in page["nodes"] if repo[
                        "isTemplate"] and not repo["isPrivate"] and not repo["isFork"])
            publicTemplatesCount = sum(
                1 for page in repoStats if page[
                    "nodes"] != None for repo in page["nodes"] if repo[
                        "isTemplate"] and not repo["isPrivate"])

            # Count of public non forks owned by user
            publicNonForksCount = ownedRepositories - sum(
                1 for page in repoStats if page["nodes"] != None for repo in page[
                    "nodes"] if repo["isPrivate"] or repo["isFork"])

            # Compute language distribution
            totalSize, languageData = self.summarizeLanguageStats(repoStats)
        else:
            # if no owned repos then set all repo related stats to 0
            stargazers = 0
            forksOfMyRepos = 0
            stargazersAll = 0
            forksOfMyReposAll = 0
            watchers = 0
            watchersNonForks = 0
            privateCount = 0
            publicAll = 0
            publicNonForksArchivedCount = 0
            publicArchivedCount = 0
            publicNonForksCount = 0
            publicNonForksTemplatesCount = 0
            publicTemplatesCount = 0
            totalSize, languageData = 0, {}

        self._repo = {
            "public" : [publicNonForksCount, publicAll],
            "starredBy" : [stargazers, stargazersAll],
            "forkedBy" : [forksOfMyRepos, forksOfMyReposAll],
            "watchedBy" : [watchersNonForks, watchers],
            "archived" : [publicNonForksArchivedCount, publicArchivedCount],
            "templates" : [publicNonForksTemplatesCount, publicTemplatesCount]
        }

        self._languages = self.organizeLanguageStats(totalSize, languageData)

    def organizeLanguageStats(self, totalSize, languageData):
        """Computes a list of languages and percentages in decreasing order
        by percentage.

        Keyword arguments:
        totalSize - total size of all code with language detection data
        languageData - the summarized language totals, colors, etc
        """
        if totalSize == 0:
            return { "totalSize" : 0, "languages" : [] }
        else:
            languages = [ (name, data) for name, data in languageData.items() ]
            languages.sort(key = lambda L : L[1]["size"], reverse=True)
            if self._autoLanguages :
                for i, L in enumerate(languages):
                    if L[1]["percentage"] < 0.01:
                        self._maxLanguages = i
                        break
            if len(languages) > self._maxLanguages:
                self.combineLanguages(languages, self._maxLanguages, totalSize)
            self.checkColors(languages)
            return { "totalSize" : totalSize, "languages" : languages }

    def combineLanguages(self, languages, maxLanguages, totalSize):
        """Combines lowest percentage languages into an Other.

        Keyword arguments:
        languages - Sorted list of languages (sorted by size).
        maxLanguages - The maximum number of languages to keep as is.
        """
        if len(languages) > self._maxLanguages:
            combinedSize = sum(L[1]["size"] for L in languages[maxLanguages:])
            languages[maxLanguages] = (
                "Other",
                { "color" : None,
                  "size" : combinedSize,
                  "percentage" : combinedSize / totalSize
                  }
                )
            del languages[maxLanguages+1:]

    def checkColors(self, languages):
        """Make sure all languages have colors, and assign shades of gray to
        those that don't.

        Keyword arguments:
        languages - Sorted list of languages (sorted by size).
        """
        # Not all languages have colors assigned by GitHub's Linguist.
        # In such cases, we alternate between these two shades of gray.
        colorsForLanguagesWithoutColors = [ "#959da5", "#d1d5da" ]
        index = 0
        for L in languages:
            if L[1]["color"] == None:
                L[1]["color"] = colorsForLanguagesWithoutColors[index]
                index = (index + 1) % 2

    def summarizeLanguageStats(self, repoStats):
        """Summarizes the language distibution of the user's owned repositories.

        Keyword arguments:
        repoStats - The results of the repo stats query.
        """
        totalSize = 0
        languageData = {}
        for page in repoStats:
            if page["nodes"] != None:
                for repo in page["nodes"]:
                    if (not repo["isPrivate"] and not repo["isFork"] and
                        (repo["name"].lower() not in self._languageRepoExclusions)):
                        totalSize += repo["languages"]["totalSize"]
                        if repo["languages"]["edges"] != None :
                            for L in repo["languages"]["edges"]:
                                name = L["node"]["name"]
                                if name in languageData:
                                    languageData[name]["size"] += L["size"]
                                else:
                                    languageData[name] = {
                                        "color" : L["node"]["color"],
                                        "size" : L["size"]
                                        }
        for L in languageData:
            languageData[L]["percentage"] = languageData[L]["size"] / totalSize
        return totalSize, languageData

    def createPriorYearStatsQuery(self, yearList, oneYearContribTemplate):
        """Generates the query for prior year stats.

        Keyword arguments:
        yearList - a list of the years when the user had contributions,
            obtained by one of the other queries.
        oneYearContribTemplate - a string template of the part of a query
            for one year.
        """
        query = "query($owner: String!) {\n  user(login: $owner) {\n"
        for y in yearList:
            query += oneYearContribTemplate.format(y)
        query += "  }\n}\n"
        return query

    def parsePriorYearStats(self, queryResults):
        """Parses one year of commits, PR reviews, and restricted contributions.

        Keyword arguments:
        queryResults - The results of the query.
        """
        queryResults = queryResults["data"]["user"]
        self._contrib["commits"][1] = sum(
            stats["totalCommitContributions"] for k, stats in queryResults.items())
        self._contrib["reviews"][1] = sum(
            stats["totalPullRequestReviewContributions"] for k, stats in queryResults.items())
        self._contrib["private"][1] = sum(
            stats["restrictedContributionsCount"] for k, stats in queryResults.items())

    def executeQuery(self, query, needsPagination=False, failOnError=True):
        """Executes a GitHub GraphQl query using the GitHub CLI (gh).

        Keyword arguments:
        query - The query as a string.
        needsPagination - Pass True to enable pagination of query results.
        failOnError - If True, the workflow will fail if there is an error executing the
            query; and if False, this action will quietly exit with no error code. In
            either case, an error message will be logged to the console.
        """
        if "GITHUB_REPOSITORY_OWNER" in os.environ:
            owner = os.environ["GITHUB_REPOSITORY_OWNER"]
        else:
            print("Error (7): Could not determine the repository owner.")
            set_outputs({"exit-code" : 7})
            exit(7 if failOnError else 0)
        arguments = [
            'gh', 'api', 'graphql',
            '-F', 'owner=' + owner,
            '--cache', '1h',
            '-f', 'query=' + query
            ]
        if needsPagination:
            arguments.insert(5, '--paginate')
        result = subprocess.run(
            arguments,
            stdout=subprocess.PIPE,
            universal_newlines=True
            ).stdout.strip()
        numPages = result.count('"data"')
        if numPages == 0:
            # Check if any error details
            result = json.loads(result) if len(result) > 0 else ""
            if "errors" in result:
                print("Error (2): GitHub api Query failed with error:")
                print(result["errors"])
                code = 2
            else:
                print("Error (3): Something unexpected occurred during GitHub API query.")
                code = 3
            set_outputs({"exit-code" : code})
            exit(code if failOnError else 0)
        elif needsPagination:
            if (numPages > 1):
                result = result.replace('}{"data"', '},{"data"')
            result = "[" + result + "]"
        result = json.loads(result)
        failed = False
        errorMessage = None
        if ((not needsPagination) and
            (("data" not in result) or result["data"] == None)):
            failed = True
            if "errors" in result:
                errorMessage = result["errors"]
        elif needsPagination and ("data" not in result[0] or result[0]["data"] == None):
            failed = True
            if "errors" in result[0] :
                errorMessage = result[0]["errors"]
        if failed:
            print("Error (6): No data returned.")
            if errorMessage != None:
                print(errorMessage)
            set_outputs({"exit-code" : 6})
            exit(6 if failOnError else 0)
        return result

    def ghDisableInteractivePrompts(self):
        """Disable gh's interactive prompts. This is probably unnecessary,
        as all of our testing so far, the queries run fine and don't produce any
        prompts. Disabling as a precaution in case some unexpected condition occurs
        that generates a prompt, so we don't accidentally leave a workflow waiting for
        user itneraction.
        """
        result = subprocess.run(
            ["gh", "config", "set", "prompt", "disabled"],
            stdout=subprocess.PIPE,
            universal_newlines=True
            ).stdout.strip()


__license__ = '''
 License (GPL-3.0) :
    This file is part of PPQT Version 2.
    PPQT 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 3 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 can find a copy of the GNU General Public License in the file
    extras/COPYING.TXT included in the distribution of this program, or see:
    <http://www.gnu.org/licenses/>.
'''
__version__ = "2.0.0"
__author__  = "David Cortesi"
__copyright__ = "Copyright 2013, 2014 David Cortesi"
__maintainer__ = "David Cortesi"
__email__ = "tallforasmurf@yahoo.com"

'''
Unit test for paths.py.
'''
import test_boilerplate as T
T.set_up_paths()
T.make_app()
import os
import logging
import constants as C
import paths
T.settings.clear()
# test readable folder
test_path = T.path_to_Files
assert paths.check_path(test_path)
# nonexistent file
assert not paths.check_path(os.path.join(test_path,'arglebargle'))
# file that has the read perms turned off
assert not paths.check_path(os.path.join(test_path,'unreadable.aff'))

paths.initialize(T.settings)

# with null settings, extras defaults to cwd = test_path
assert T.check_log('initial extras path is '+test_path ,logging.INFO)
assert paths.get_extras_path() == test_path
assert paths.get_dicts_path() == ''
# check assuming bookloupe is installed
if C.PLATFORM_IS_WIN:
    assert paths.get_loupe_path() == '' # TODO FIX WHEN KNOWN
else:
    assert paths.get_loupe_path() == '/usr/local/bin/bookloupe'
# point settings to an extras, expect dicts to follow
test_extras = os.path.join(T.path_to_Files,'extras')
T.settings.setValue("paths/extras_path", test_extras)
paths.initialize(T.settings)
assert T.check_log('initial extras path is '+test_extras ,logging.INFO)
assert paths.get_extras_path() == test_extras
test_dicts = os.path.join(test_extras,'dicts')
assert paths.get_dicts_path() == test_dicts
# Make sure that what we put into loupe, we get back
test_loupe = os.path.join(test_extras,'bookloupe.exe') # which doesn't exist
paths.set_loupe_path(test_loupe)
assert paths.get_loupe_path() == test_loupe
# test shutdown
T.settings.clear()
paths.shutdown(T.settings)
assert T.settings.value("paths/extras_path",'wrong') == test_extras
assert T.settings.value("paths/dicts_path",'wrong') == test_dicts
assert T.settings.value("paths/loupe_path",'wrong') == test_loupe
# set bad values because paths expects caller to verify validity
dummy_dicts = '/some/where/dicts'
paths.set_dicts_path(dummy_dicts)
dummy_extras = '/what/ever/extras'
paths.set_extras_path(dummy_extras)
dummy_loupe = 'nexist/pas/bookloupe'
paths.set_loupe_path(dummy_loupe)
assert paths.get_dicts_path() == dummy_dicts
assert paths.get_extras_path() == dummy_extras
assert paths.get_loupe_path() == dummy_loupe
# shut down with those bad values
paths.shutdown(T.settings)
# start up with bad values, expect defaults
paths.initialize(T.settings)
assert paths.get_extras_path() == test_path # bad path -> cwd
assert paths.get_dicts_path() == '' # bad path -> null
assert paths.get_loupe_path() == '' # bad path -> null
# Check sending of signal
sig_value = None
def catcher(what):
    global sig_value
    sig_value = what
paths.notify_me(catcher)
paths.set_extras_path('/somewhere/over/the/rainbow')
assert sig_value == 'extras'
paths.set_loupe_path('/somewhere/over/the/rainbow')
assert sig_value == 'loupe'
paths.set_dicts_path('/somewhere/over/the/rainbow')
assert sig_value == 'dicts'


# ---------------------------------------------------------------------------------
#  /\_/\  🌐 This module was loaded from github.com
# ( o.o )  🔐 Licensed under the CC BY-NC-ND 4.0.
#  > ^ <   ⚠ Owner of heta.hikariatama.ru doesn't take any responsibilities or intellectual property rights regarding this script
# ---------------------------------------------------------------------------------
# Name                                           : NewPostsNotifier
# Description                                    : Модуль для уведомления о новых постах в канале
# Author                                         : romaterabyte
# Commands                                       :
# .setchannel | .setfavorite
# ---------------------------------------------------------------------------------

import random

from telethon.sync import TelegramClient
from telethon.events import NewMessage
from telethon.tl.types import PeerChannel

from .. import loader, utils

@loader.tds
class NewPostsNotifierMod(loader.Module):
    strings = {"name": "Уведомитель о новых постах"}

    def __init__(self):
        self.client = None
        self.channel_id = None
        self.favorite_chat_id = None

    async def client_ready(self, client, db):
        self.client = client

    async def on_message(self, event):
        if self.favorite_chat_id is not None:
            if event.is_channel and event.message.to_id.channel_id == self.channel_id:
                if event.message.post:
                    # Отправляем уведомление о новом посте в избранное
                    await self.client.send_message(self.favorite_chat_id, "Новый пост в канале!")

    async def setchannelcmd(self, m):
        """.setchannel <канал> - установить канал, для которого будет производиться отслеживание новых постов"""
        args = utils.get_args_raw(m)
        if not args:
            await m.edit("Укажите айди канала!")
            return

        try:
            self.channel_id = int(args)
        except ValueError:
            await m.edit("Неверный формат айди канала!")
            return

        await m.edit(f"Канал успешно установлен: {args}")

    async def setfavoritecmd(self, m):
        """.setfavorite <чат> - установить чат, в который будет отправляться уведомление о новых постах"""
        args = utils.get_args_raw(m)
        if not args:
            await m.edit("Укажите айди чата избранного!")
            return

        try:
            self.favorite_chat_id = int(args)
        except ValueError:
            await m.edit("Неверный формат айди чата избранного!")
            return

        await m.edit(f"Чат избранного успешно установлен: {args}")


import json
import time

import pytest
import requests_mock
from django.core import mail
from django.core.management import call_command
from django.utils.crypto import get_random_string
from django.utils.encoding import force_str

from gore.models import Event
from gore.tests.conftest import project, raven_with_project  # noqa: F401
from gore.tests.data import exc_payload
from gotify.models import SlackNotifier
from gotify.models.email_notifier import EmailNotifier

@pytest.mark.django_db  # noqa: F811
def test_email_notifier(project, settings):  # noqa: F811
    settings.GOTIFY_IMMEDIATE = False
    en = EmailNotifier.objects.create(emails='test@example.com')
    en.projects.add(project)
    event = Event.objects.create_from_raven(project_id=project.id, body=json.loads(exc_payload))
    call_command('gotify_send')
    message = mail.outbox[-1]
    assert event.message in message.subject
    assert event.project.name in message.subject

@pytest.mark.django_db  # noqa: F811
def test_slack_notifier(project, settings):  # noqa: F811
    settings.GOTIFY_IMMEDIATE = False
    sn = SlackNotifier.objects.create(
        webhook_url='http://example.com',
        message_header_suffix=get_random_string(12),
    )
    sn.projects.add(project)
    event = Event.objects.create_from_raven(project_id=project.id, body=json.loads(exc_payload))
    with requests_mock.mock() as m:
        m.post('http://example.com', text='ok')
        call_command('gotify_send')
    assert m.called
    req = m.request_history[0]
    assert req.method == 'POST'
    payload = json.loads(force_str(req.body))
    assert event.message in payload['text']
    assert event.project.name in payload['text']
    assert sn.message_header_suffix in payload['text']

@pytest.mark.django_db(transaction=True)
@pytest.mark.parametrize('thread', [True, False])
def test_immediate_notify(raven_with_project, settings, thread):  # noqa: F811
    settings.GOTIFY_IMMEDIATE = True
    settings.GOTIFY_IMMEDIATE_THREAD = thread
    project = raven_with_project.project  # noqa: F811
    en = EmailNotifier.objects.create(emails='test@example.com')
    en.projects.add(project)
    raven_with_project.captureMessage('hello world')
    if thread:
        time.sleep(1)
    assert len(mail.outbox) == 1

@pytest.mark.django_db  # noqa: F811
def test_exclude(raven_with_project, settings):  # noqa: F811
    settings.GOTIFY_IMMEDIATE = True
    project = raven_with_project.project  # noqa: F811
    en = EmailNotifier.objects.create(emails='test@example.com')
    en.excludes.create(pattern='hello')
    en.projects.add(project)
    raven_with_project.captureMessage('hello world')
    assert len(mail.outbox) == 0


import os
import numpy as np
import tensorflow as tf
from tensorflow.python.framework import ops

flags = tf.app.flags
flags.DEFINE_string("logdir", "saved_models/", "where to save the model")
flags.DEFINE_integer("num_filters", 100, "cnn number of output unit")
flags.DEFINE_float("lrn_rate", 0.01, "learning rate")
flags.DEFINE_float("l2_coef", 0.01, "l2 loss coefficient")
flags.DEFINE_float("keep_prob", 0.5, "dropout keep probability")

FLAGS = tf.app.flags.FLAGS

FILTER_SIZES = [3, 4, 5]

class BaseModel(object):

  def set_saver(self, save_dir):
    '''
    Args:
      save_dir: relative path to FLAGS.logdir
    '''
    # shared between train and valid model instance
    self.saver = tf.train.Saver(var_list=None)
    self.save_dir = os.path.join(FLAGS.logdir, save_dir)
    self.save_path = os.path.join(self.save_dir, "model.ckpt")

  def restore(self, session):
    ckpt = tf.train.get_checkpoint_state(self.save_dir)
    self.saver.restore(session, ckpt.model_checkpoint_path)

class LinearLayer(tf.layers.Layer):
  '''inherit tf.layers.Layer to cache trainable variables
  '''
  def __init__(self, layer_name, out_size, is_regularize, **kwargs):
    self.layer_name = layer_name
    self.out_size = out_size
    self.is_regularize = is_regularize
    super(LinearLayer, self).__init__(**kwargs)

  def build(self, input_shape):
    in_size = input_shape[1]

    with tf.variable_scope(self.layer_name):
      w_init = tf.truncated_normal_initializer(stddev=0.1)
      b_init = tf.constant_initializer(0.1)

      self.w = self.add_variable('W', [in_size, self.out_size], initializer=w_init)
      self.b = self.add_variable('b', [self.out_size], initializer=b_init)

      super(LinearLayer, self).build(input_shape)

  def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)
  def call(self, x):
    x_list_size = x.shape.as_list()
    y_size = 1
    for i in x_list_size:
      y_size *= i
    loss_l2 = tf.constant(0, dtype=tf.float32)
    # y_size = [-1, 15 * 100 * 32]
    x = tf.reshape(x, [-1, y_size])
    w = tf.Variable(tf.truncated_normal([y_size, self.out_size], stddev=0.1))
    b = tf.Variable(tf.truncated_normal([self.out_size], stddev=0.1))
    o = tf.nn.xw_plus_b(x, w, b)
    if self.is_regularize:
      loss_l2 += tf.nn.l2_loss(w) + tf.nn.l2_loss(b)
    return o, loss_l2

class ConvLayer(tf.layers.Layer):
  '''inherit tf.layers.Layer to cache trainable variables
  '''
  def __init__(self, layer_name, filter_sizes, **kwargs):
    self.layer_name = layer_name
    self.filter_sizes = filter_sizes
    self.conv = {} # trainable variables for conv
    super(ConvLayer, self).__init__(**kwargs)
    # print("--init--")

  def build(self, input_shape):
    input_dim = 200

    with tf.variable_scope(self.layer_name):
      w_init = tf.truncated_normal_initializer(stddev=0.1)
      b_init = tf.constant_initializer(0.1)

      for fsize in self.filter_sizes:
        w_shape = [fsize, input_dim, 1, FLAGS.num_filters]
        b_shape = [FLAGS.num_filters]
        w_name = 'conv-W%d' % fsize
        b_name = 'conv-b%d' % fsize
        self.conv[w_name] = self.add_variable(
                                           w_name, w_shape, initializer=w_init)
        self.conv[b_name] = self.add_variable(
                                           b_name, b_shape, initializer=b_init)

      super(ConvLayer, self).build(input_shape)

  def call(self, x):
    # print('--new call--')
    x = tf.reshape(x, [-1, 30, 200, 1])
    filter = tf.Variable(tf.random_normal([5, 5, 1, 64]))
    b_conv1 = tf.Variable(tf.random_normal([64]))
    conv = tf.nn.conv2d(x, filter, strides=[1, 1, 1, 1], padding='SAME')
    conv = tf.nn.relu(conv + b_conv1)
    return conv

def max_pool(conv_outs, max_len):
  pool = tf.nn.max_pool(conv_outs, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
  return pool

def optimize(loss):
  optimizer = tf.train.AdamOptimizer(FLAGS.lrn_rate)

  update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
  with tf.control_dependencies(update_ops): # for batch_norm
    train_op = optimizer.minimize(loss)
  return train_op

class FlipGradientBuilder(object):
  '''Gradient Reversal Layer from https://github.com/pumpikano/tf-dann'''
  def __init__(self):
    self.num_calls = 0

  def __call__(self, x, l=1.0):
    grad_name = "FlipGradient%d" % self.num_calls
    @ops.RegisterGradient(grad_name)
    def _flip_gradients(op, grad):
      return [tf.negative(grad) * l]

    g = tf.get_default_graph()
    with g.gradient_override_map({"Identity": grad_name}):
      y = tf.identity(x)

    self.num_calls += 1
    return y

flip_gradient = FlipGradientBuilder()


import sys
sys.stdin = open('swea/input.txt', "r")

# 1 입력으로 주어진 문장에 모든 소문자 알파벳을 찾아 대문자로 변환한 다음,
#   그 결과를 출력하는 프로그램을 작성하라.

string = input().split()

answer = string[0].upper()
print(answer)

# 2 1부터 주어진 숫자만큼 모두 더한 값을 출력하시오.

number = int(input())

answer = 0
for n in range(1,number + 1):
    answer += n
print(answer)

# 3 가위바위보 승자 확인

a ,b = list(map(int,input().split()))

if a == 1:
    if b == 2:
        print('B')
    elif b == 3:
        print('A')
elif a == 2:
    if b == 1:
        print('A')
    elif b == 3:
        print('B')
elif a == 3:
    if b == 1:
        print('B')
    elif b == 2:
        print('A')

# 4 대각선

a = '+++++'

for i in a:
    i = '#'
    print(a)


import torch
import torch.nn as nn
import torch.nn.functional as F
from torch import Tensor

class LateTemporalTokenizer(nn.Module):
    """
    Late Temporal Tokenizer is a 3D feature map tokenizer modules. It creates spatio-temporal tokens that summarize
    information along the spatial and temporal dimensions of the input feature map.
    Params:
    - in_channels: channel size of input feature map
    - spatial_dim: spatial dimension size of tokens
    - temporal_dim: temporal dimension size of tokens
    - token_dim: dimension of each spatio-temporal token
    """

    def __init__(self, in_channels: int, spatial_dim: int, temporal_dim: int, token_dim: int) -> None:
        super().__init__()

        self.in_channels = in_channels
        self.spatial_dim = spatial_dim
        self.temporal_dim = temporal_dim
        self.token_dim = token_dim

        self.spatial_proj = nn.Linear(in_channels, token_dim)
        self.temporal_proj = nn.Linear(token_dim, token_dim)

        self.spatial_linear = nn.Linear(in_channels, spatial_dim)
        self.temporal_linear = nn.Linear(token_dim, temporal_dim)

    def forward(self, x: Tensor) -> Tensor:
        """
        Expected Input Dimensions: (B, T, HW, C), where:
        - B: batch size
        - T: number of video frames
        - HW: number of pixels
        - C: size of input feature map channels

        Expected Output Dimensions: (B, F, L, D), where:
        - L: spatial dimension of tokens
        - F: temporal dimension of tokens
        - D: size of token dimension
        """

        # spatial tokenization
        x_proj = self.spatial_proj(x)  # -> (B, T, HW, D)
        a = self.spatial_linear(x)  # -> (B, T, HW, L)
        a = F.softmax(a, dim=2)  # -> (B, T, HW, L)
        a = torch.einsum('btij, btik -> btjk', a, x_proj)  # -> (B, T, L, D)

        # temporal tokenization
        a_proj = self.temporal_proj(a)  # -> (B, T, L, D)
        t = self.temporal_linear(a)  # -> (B, T, L, F)
        t = F.softmax(t, dim=1)  # -> (B, T, L, F)
        t = torch.einsum('btlf, btld -> bfld', t, a_proj)  # -> (B, F, L, D)

        return t


# 문자열 피라미드

'''
Description

문자열 피라미드를 만드는 pyramid(char, n, alignment=-1) 함수를 구현하시오.

같은 동작을 하는 프로그램을 문자열 서식화를 이용하지 않고 만들어보고, 문자열 서식화를 이용해서 만들어 보면 도움이 됨.

함수동작
피라미드 출력
   - 표시하고자 하는 문자(char)와 행(n)을 인자로 받아서 n줄 만큼 char를 피라미드 형태로 출력
   - 피라미드 출력은 week4의 21번과 동일하나 alignment값에 따라서 정렬함.
   - char이 한글자 이상인 경우 None를 반환.

매개변수
char: 한 글자를 포함한 문자열
   - 한 글자가 아닌 경우에는 반환값에 나타난대로 None을 반환해야 함
n: 0 이상의 정수
   - 문자열 피라미드를 몇 칸에 맞추어서, 그리고 몇 줄에 걸쳐 만들 것을 지정
alignment: -1, 0, 1 중 하나의 값
   - -1: 왼쪽에 char를 맞추어 문자열 피라미드를 만듦 (기본값)
   - 0: 가운데에 char를 맞추어 문자열 피라미드를 만듦
   - 1: 오른쪽에 char를 맞추어 문자열 피라미드를 만듦

반환값
문자열: 아래 조건에 맞춘 문자열 피라미드를 포함하는 문자열
   -문자열 char에 포함된 문자의 수가 1이 아닐 때: None (문자열 'None'이 아닌 None값)
   -문자열 cahr에 포함된 문자의 수가 1일 때: n개의 줄을 가지는 문자열을 반환함
   -1번째 줄에 char 1개, 2번째 줄에 char 2개, ..., n번째 줄에 char를 n개 포함
   -각 줄은 (공백을 포함한) n개의 문자열로 만드는데, 이 때 char들을 alignment의 값에 따라 포함함. alignment의 의미는 인자에 있는 내용을 참고할 것.

주의
왼쪽 또는 가운제 정렬인 경우, 오른쪽에 빈 공간이 있어야함
'''

'''
함수 사용 예시

print("Output of pyramid('**', 3)")
print(pyramid('**', 3))
print("Output of pyramid('+', 3)")
print(pyramid('+', 3))
print("Output of pyramid('*', 5)")
print(pyramid('*', 5))
print("Output of pyramid('*', 5, 0)")
print(pyramid('*', 5, 0))
print("Output of pyramid('*', 5, 1)")
print(pyramid('*', 5, 1))
'''

'''
실행결과

Output of pyramid('**', 3)
None
Output of pyramid('+', 3)
+
++
+++

Output of pyramid('*', 5)
*
**
***
****
*****

Output of pyramid('*', 5, 0)
  *
 **
 ***
****
*****

Output of pyramid('*', 5, 1)
    *
   **
  ***
 ****
*****
'''

#Code

def pyramid(char, n, alignment=-1):
    """Return text pyramid"""
    result = ''
    space = ' '
    if len(char) == 1:
        if alignment == -1:
            for row in range(n):
                result = result + char*(row+1) + space*(n-row-1) + '\n'

        elif alignment == 0:
            for row in range(n):
                if (n-row)%2 == 0:
                    result = result + space*int((n-row-2)/2) + char*int(row+1) + space*int((n-row)/2) + '\n'
                else:
                    result = result + space*int((n-row-1)/2) + char*(row+1) + space*int((n-row-1)/2) + '\n'

        else:
            for row in range(n):
                result = result  + space*(n-row-1) + char*(row+1) + '\n'
        return result

    else: return None

print("Output of pyramid('**', 3)")
print(pyramid('**', 3))
print("Output of pyramid('+', 3)")
print(pyramid('+', 3))
print("Output of pyramid('*', 5)")
print(pyramid('*', 5))
print("Output of pyramid('*', 5, 0)")
print(pyramid('*', 5, 0))
print("Output of pyramid('*', 5, 1)")
print(pyramid('*', 5, 1))

Week8&9_Str function, Str processing, File input and output/W8ExampleProblems/W8P40_AdvancedStrPyramidPrinter/W8P40_AdvancedStrPyramidPrinter.py


from classifier import BinClassifier, test
from utils import get_dataset, EXAMPLE_NAMES, EXAMPLE_ANSWERS
from skimage.io import imread
import numpy as np

def test_all_local(bc: BinClassifier, full_res: bool):
    correct = 0
    for name, res in zip(EXAMPLE_NAMES, EXAMPLE_ANSWERS):
        pred, cur_res = test_local(bc, name, full_res)
        if full_res:
            print(f"prediction = {pred}")
        print(f"current result = {cur_res}, real answer = {res} --- {cur_res == res} filename = {name}")
        correct += (res == cur_res)
    print(f"num of correct answers = {correct}")
    print(f"all number of examples = {len(EXAMPLE_NAMES)}")

def test_local(bc: BinClassifier, pict_name: str, full_res: bool):
    image = imread(fname=f'data/{pict_name}.png', as_gray=True)
    # image = image*255
    pred = bc.test(image.reshape(1, image.shape[0] * image.shape[1]), full_return=full_res)
    res = np.argmax(pred)
    return pred, res

def check_classifier(with_external_picture: bool):
    bc = BinClassifier()
    bc.load(classifier_name="classifier_without_examples")

    if not with_external_picture:
        (x_train, y_train), (x_test, y_test) = get_dataset()
        test(bc, x_test, y_test)
    else:
        test_all_local(bc, full_res=False)

if __name__ == '__main__':
    check_classifier(with_external_picture=True)


# -*- coding: UTF-8 -*-
"""
-------------------------------------------------
   FileName：        main
   Description：     钉钉消息通知机器人API服务
   Author：          kizai
   Date：            2023/3/1
-------------------------------------------------
"""
import os.path
from flask import request, Flask, jsonify
from flask_json import as_json, FlaskJSON
import requests
import time
import hmac
import urllib
import base64
import hashlib
import json
import logging

log_path = './run.log'
logging.basicConfig(filename=log_path, filemode='a+', level=logging.INFO,
                    format='%(asctime)s %(levelname)s %(filename)s %(funcName)s %(lineno)d %(message)s',
                    datefmt="%Y-%m-%d %H:%M:%S")

config_path = os.path.join(os.path.dirname(__file__), "config.json")

# 读取配置文件
with open(config_path, 'r', encoding='utf8') as f:
    config = json.load(f)

webhook = config['ws']['webhook']
secrets = config['ws']['secret']

app = Flask(__name__)
FlaskJSON(app)

# 加签
def signature_url(webhook_url: str, secret: str):
    # 生成当前时间戳，单位是毫秒，与请求调用时间误差不能超过1小时
    timestamp = str(round(time.time() * 1000))
    # 修改编码格式为utf-8
    secret_enc = secret.encode('utf-8')
    # 将timestamp和secret合并
    string_to_sign = '{}\n{}'.format(timestamp, secret)
    # 修改编码格式为utf-8
    string_to_sign_enc = string_to_sign.encode('utf-8')
    # 将字段进行加密，加密类型采用sha256
    hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
    sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
    # 生成请求的URL，WebHook地址
    post_url = ("%s&timestamp=%s&sign=%s" % (webhook_url, timestamp, sign))
    logging.info(post_url)
    return post_url

# 发送Text信息
def send_msg(text: str, is_at_all: str, at_user_id: str = None):
    headers = {'Content-Type': 'application/json;charset=utf-8'}
    url = signature_url(webhook, secrets)
    data = {
        "msgtype": "text",
        "text": {
            "content": text
        },
        "at": {
            "atMobiles": [
            ],
            "atUserIds": [at_user_id
                          ],
            "isAtAll": is_at_all
        }
    }
    r = requests.post(url, data=json.dumps(data), headers=headers)
    logging.info(r.text)
    return r.text

# 发送MarkDown信息
def send_markdown_msg(text: str, is_at_all: str = False, at_user_id: str = None):
    headers = {'Content-Type': 'application/json;charset=utf-8'}
    url = signature_url(webhook, secrets)
    data = {
        "msgtype": "markdown",
        "markdown": {"title": 'Markdown Message',
                     "text": text},
        "at": {
            "atMobiles": [
            ],
            "atUserIds": [at_user_id
                          ],
            "isAtAll": is_at_all
        }
    }
    r = requests.post(url, data=json.dumps(data), headers=headers)
    logging.info(r.text)
    return r.text

# 检查服务端口是否正常
@app.route('/api/v1', methods=['GET', 'POST'])
def check():
    return jsonify({"code": 0, "message": config['msg']['0']})

# 发送文本信息接口
@app.route('/api/v1/text', methods=['POST'])
@as_json
def dingbot_text():
    if request.method == 'POST':
        try:
            data = request.args
            message = data['message']
            is_at_all = data.get('is_at_all')
            at_user_id = data.get('at_user_id')
            if message:
                send_msg(message, is_at_all, at_user_id)
                return jsonify({"code": 0, "message": config['msg']['0']})
            else:
                logging.error(config['msg']['-1'])
                return jsonify({"code": -1, "message": config['msg']['-1']})
        except:
            logging.error(config['msg']['400'])
            return jsonify({"code": 400, "message": config['msg']['400']})

# 发送markdown信息接口
@app.route('/api/v1/md', methods=['POST'])
@as_json
def dingbot_link():
    if request.method == 'POST':
        try:
            data = request.args
            text = data['text']
            message_url = data['message_url']
            is_at_all = data.get('is_at_all')
            at_user_id = data.get('at_user_id')
            if text and message_url:
                if at_user_id:
                    text_content = "{},[消息链接]({}),\n@{}".format(text, message_url, at_user_id)
                    send_markdown_msg(text_content, is_at_all, at_user_id)
                    return jsonify({"code": 0, "message": config['msg']['0']})
                else:
                    text_content = "{},[消息链接]({})".format(text, message_url)
                    send_markdown_msg(text_content, is_at_all)
                    return jsonify({"code": 0, "message": config['msg']['0']})
            else:
                logging.error(config['msg']['-1'])
                return jsonify({"code": -1, "message": config['msg']['-1']})
        except:
            logging.error(config['msg']['400'])
            return jsonify({"code": 400, "message": config['msg']['400']})

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=config['port'], debug=True)


import vtk

def main():
    rw = vtk.vtkRenderWindow()
    rw.SetSize(1000, 600)
    rw.SetWindowName("Alya")

    iren = vtk.vtkRenderWindowInteractor()
    iren.SetRenderWindow(rw)

    #Create a sphere
    sphereSource = []
    sphereSource.append( vtk.vtkSphereSource() )
    sphereSource.append( vtk.vtkSphereSource() )
    sphereSource.append( vtk.vtkSphereSource() )

    sphereSource[0].SetCenter(0.0, 0.0, 0.0)
    sphereSource[0].SetRadius(0.5)
    sphereSource[1].SetCenter(0.0, 0.0, 0.0)
    sphereSource[1].SetRadius(2.5)
    sphereSource[2].SetCenter(0.0, 0.0, 0.0)
    sphereSource[2].SetRadius(5.0)

    color = []
    color.append( (1.0,0.0,0.0) )
    color.append( (0.0,1.0,0.0) )
    color.append( (0.0,0.0,1.0) )

    color_background = []
    color_background.append( (0.8,0.8,0.9) )
    color_background.append( (0.8,0.8,0.8) )
    color_background.append( (0.8,0.8,0.7) )

    xmins=[0.0, 0.5, 0.5]
    ymins=[0.0, 0.5, 0.0]
    xmaxs=[0.5, 1.0, 1.0]
    ymaxs=[1.0, 1.0, 0.5]

    iren_list = []
    for i in range(3):
        ren = vtk.vtkRenderer()
        rw.AddRenderer(ren)
        ren.SetViewport(xmins[i],ymins[i],xmaxs[i],ymaxs[i])

        mapper = vtk.vtkPolyDataMapper()
        actor  = vtk.vtkActor()

        mapper.SetInputConnection(sphereSource[i].GetOutputPort())
        actor.SetMapper(mapper)
        actor.GetProperty().SetColor(color[i])
        actor.GetProperty().SetRepresentationToWireframe()

        ren.AddActor(actor)
        ren.SetBackground(color_background[i])
        ren.ResetCamera()

    rw.Render()
    iren.Start()

if __name__ == '__main__':
    main()


from itertools import permutations
from collections import deque
from cmath import inf

class GraphAL:
    def init(self, size):
        self.size=size
        self.arregloDeListas = [0]*size # = [0,0,0,0...]
        for i in range(size):
            self.arregloDeListas[i] = deque()

    def addArc(self, source, destination, weight):
        laListaLlegada = self.arregloDeListas[source]
        unaPareja = (destination,weight)
        laListaLlegada.append(unaPareja)

    def getWeight(self, source, destination):
        laListaLlegada = self.arregloDeListas[source]
        if destination not in self.getSuccessors(source):
            return inf
        for i in range(len(laListaLlegada)):
            pareja = laListaLlegada[i] # O(n)
            theDestination = pareja[0]
            theWeight = pareja[1]
            if theDestination == destination:
                return theWeight
        for (theDestination,theWeight) in laListaLlegada:
            if theDestination == destination:
                return theWeight
        return 0
    def getSuccessors(self, source):
        otraListica = deque()
        laListaLlegada = self.arregloDeListas[source]
        for (theDestination,theWeight) in laListaLlegada:
            otraListica.append(theDestination)
        return otraListica
def recorridos(grafo):
    lista = []
    visitado=[False]*grafo.size
    for i in range(grafo.size):
        if not visitado[i]:
            visitado[i]=True
            lista.append(i)
            for sucesor in grafo.getSuccessors(i):
                if not visitado[i]:
                    visitado[sucesor]=True
                    lista.append(i)
    return lista

def permutaciones(grafo,perm):
    perm1 = permutations(perm)
    for i in list(perm1):
        print
        print (i)
    perm1 = permutations(perm)
    pesoT = inf
    for i in list(perm1):
        peso = 0
        count = 0
        for j in i:
            count = count + 1
            if j != i[-1]:
                peso += grafo.getWeight(j,i[count])
            else :
                peso += grafo.getWeight(j,i[0])
                print(peso)
                if peso < pesoT:
                    pesoT = peso
    print("este es el menor peso: " + str(pesoT) )

def main():
    grafo=GraphAL(3)
    grafo.addArc(0,0,4)
    grafo.addArc(0,1,8)
    grafo.addArc(0,2,3)
    grafo.addArc(1,0,1)
    grafo.addArc(1,1,7)
    grafo.addArc(1,2,3)
    grafo.addArc(2,0,6)
    grafo.addArc(2,1,2)
    grafo.addArc(2,2,5)
    lista = recorridos(grafo)
    permutaciones(grafo,lista)
main()

laboratorios/lab02/codigo/lab 01 punto 1.py


#! /usr/bin/env python
"""
Parameter estimation for DIS xsec based on least squares method.
"""
from __future__ import print_function
import os
from itertools import product

import numpy as np
import numpy.ma as ma
from numpy.linalg import inv
import scipy.optimize as opt
import h5py

from pisa.utils.log import logging, set_verbosity
from uncertainties import ufloat, unumpy
import ROOT

TYPE = 14
NAME = r'gevgen_{0}'.format(TYPE)
CACHE = '/data/icecube/data/NuTeV/{0}/cache.hdf5'.format(TYPE)
DATA_NU = '/data/icecube/data/NuTeV/nutev_data/data/nutevpack/NuVec.dat'
DATA_NUBAR= '/data/icecube/data/NuTeV/nutev_data/data/nutevpack/NubarVec.dat'
DATA_NU_COV = '/data/icecube/data/NuTeV/nutev_data/data/nutevpack/NuMatr.hdf5'
DATA_NUBAR_COV = '/data/icecube/data/NuTeV/nutev_data/data/nutevpack/NubarMatr.hdf5'
Y_BINNING = np.array([0, 0.001, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8,
                      0.9, 0.97, 1.0])
X_BINNING = np.array([0.0001, 0.03, 0.06, 0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5,
                      0.6, 0.7, 0.8])
E_BINNING = np.array([30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200,
                      230, 260, 290, 320, 360])
Y_CENTERS = np.array([0.0005, 0.026, 0.075, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65,
                      0.75, 0.85, 0.935, 0.985])
X_CENTERS = np.array([0.015, 0.045, 0.08, 0.125, 0.175, 0.225, 0.275, 0.35,
                      0.45, 0.55, 0.65, 0.75])
E_CENTERS = np.array([35, 45, 55, 65, 75, 85, 95, 110, 130, 150, 170, 190, 215,
                      245, 275, 305, 340])
WA_NU = 0.677E-38
WA_NUBAR = 0.334E-38

def get_bin_sizes(bin_edges):
    return np.abs(np.diff(bin_edges))

def load_nutev_xsec_vec():
    """Load the NuTeV xsec data along with the total (stat+syst) error."""
    logging.info('Loading NuTeV data from {0} and {1}'.format(DATA_NU,
                                                              DATA_NUBAR))
    with open(DATA_NU, 'r') as f:
        table_nu = np.genfromtxt(f, usecols=range(9), skip_header=1)
    with open(DATA_NUBAR, 'r') as f:
        table_nubar = np.genfromtxt(f, usecols=range(9), skip_header=1)

    def decode_index(index):
        ybin = index % 100 - 1
        xbin = ((index % 10000) - ybin) / 100 - 1 - 1
        ebin = ((index % 1000000) - xbin*100 -ybin)/10000 - 1 - 1
        return [map(int, (ebin, xbin, ybin))]

    nu_decoded_index, nubar_decoded_index = [], []
    for index in table_nu[:,0]:
        nu_decoded_index.append(decode_index(index))
    for index in table_nubar[:,0]:
        nubar_decoded_index.append(decode_index(index))

    nu_decoded_index = np.vstack(nu_decoded_index)
    nubar_decoded_index = np.vstack(nubar_decoded_index)

    nu_sys = table_nu[:,3:].T
    nubar_sys = table_nubar[:,3:].T
    nu_sys_err_2 = nu_sys[0]**2 + nu_sys[1]**2 + nu_sys[2]**2 + \
            nu_sys[3]**2 + nu_sys[4]**2 + nu_sys[5]**2
    nubar_sys_err_2 = nubar_sys[0]**2 + nubar_sys[1]**2 + \
            nubar_sys[2]**2 + nubar_sys[3]**2 + nubar_sys[4]**2 + \
            nubar_sys[5]**2
    nu_xsec_array = unumpy.uarray(
        table_nu[:,1], np.sqrt(table_nu[:,2]**2 + nu_sys_err_2)
    )
    nubar_xsec_array = unumpy.uarray(
        table_nubar[:,1], np.sqrt(table_nubar[:,2]**2 + nubar_sys_err_2)
    )

    nu_data_matrix = np.zeros(map(len, (E_CENTERS, X_CENTERS, Y_CENTERS)))
    nubar_data_matrix = np.zeros(map(len, (E_CENTERS, X_CENTERS, Y_CENTERS)))
    nu_data_matrix = unumpy.uarray(nu_data_matrix, nu_data_matrix)
    nubar_data_matrix = unumpy.uarray(nubar_data_matrix, nubar_data_matrix)
    for idx, entry in enumerate(nu_decoded_index):
        nu_data_matrix[tuple(entry)] = nu_xsec_array[idx]
    for idx, entry in enumerate(nubar_decoded_index):
        nubar_data_matrix[tuple(entry)] = nubar_xsec_array[idx]
    nu_data_matrix = ma.masked_equal(nu_data_matrix, 0)
    nubar_data_matrix =  ma.masked_equal(nubar_data_matrix, 0)

    return nu_data_matrix, nubar_data_matrix

def load_nutev_corrmatrix():
    """Load the inverse correlation matrix from a HDF5 file."""
    logging.info('Loading correlation matrix from {0} and '
                 '{1}'.format(DATA_NU_COV, DATA_NUBAR_COV))
    h5file_nu = h5py.File(DATA_NU_COV, 'r')
    h5file_nubar = h5py.File(DATA_NUBAR_COV, 'r')
    inv_cov_table_nu = np.array(h5file_nu['NuMatr'][:])
    inv_cov_table_nubar = np.array(h5file_nubar['NubarMatr'][:])
    h5file_nu.close()
    h5file_nubar.close()

    inv_cov_matrix_nu = inv_cov_table_nu.reshape(
        map(len, (E_CENTERS, X_CENTERS, Y_CENTERS)) * 2
    )
    inv_cov_matrix_nubar = inv_cov_table_nubar.reshape(
        map(len, (E_CENTERS, X_CENTERS, Y_CENTERS)) * 2
    )

    return inv_cov_matrix_nu, inv_cov_matrix_nubar

def load_genie_mc():
    """Load parameters from a GENIE gst ROOT file or from a cached HDF5
    file if it exists.
    """
    logging.info('Loading GENIE parameteters...')
    is_cache = False
    if os.path.isfile(CACHE):
        is_cache = True

    STR_R = ['pdg_array', 'energy_array', 'y_array', 'x_array', 'dis_array',
             'cc_array']
    def cache_events(params_dict):
        h5file = h5py.File(CACHE, 'w')
        for key in params_dict.iterkeys():
            h5file.create_dataset(key, data=params_dict[key])
        h5file.close()

    params_dict = {}
    if not is_cache:
        logging.info('Loading gst files from folder {0}'.format(DIR))
        infiles = []
        for file_name in os.listdir(DIR):
            file_path = DIR + '/' + file_name
            if os.path.isfile(file_path) and (file_path.endswith('.gst.root')):
                infiles.append(ROOT.TFile(file_path))
        for key in STR_R.iterkeys():
            params_dict[key] = []
        for r_file in infiles:
            for event in r_file.gst:
                params_dict['pdg_array'].append(event.neu)
                params_dict['energy_array'].append(event.Ev)
                params_dict['y_array'].append(event.y)
                params_dict['x_array'].append(event.x)
                params_dict['dis_array'].append(event.dis)
                params_dict['cc_array'].append(event.cc)
        for key in STR_R.iterkeys():
            params_dict[key] = np.array(params_dict[key])
        cache_events(params_dict)
    else:
        logging.info('Loading from cached file {0}'.format(CACHE))
        h5file = h5py.File(CACHE, 'r')
        for key in h5file.iterkeys():
            params_dict[key] = np.array(h5file[key][:])
        h5file.close()

    return params_dict

def only_discc(params_dict):
    x_array = params_dict['x_array']
    invalid_entries = x_array < 0
    discc = (params_dict['dis_array'] & params_dict['cc_array']).astype(bool)
    params_dict['x_array'] = x_array[~invalid_entries & discc]
    params_dict['energy_array'] = \
            params_dict['energy_array'][~invalid_entries & discc]
    params_dict['y_array'] = \
            params_dict['y_array'][~invalid_entries & discc]
    params_dict['pdg_array'] = \
            params_dict['pdg_array'][~invalid_entries & discc]
    params_dict['dis_array'] = \
            params_dict['dis_array'][~invalid_entries & discc]
    params_dict['cc_array'] = \
            params_dict['cc_array'][~invalid_entries & discc]

    return params_dict

def make_histo(array, weights):
    hist, edges = np.histogram(array, bins=Y_BINNING, weights=weights)
    hist_2, edges = np.histogram(array, bins=Y_BINNING, weights=weights**2)

    u_hist = unumpy.uarray(hist, np.sqrt(hist_2))
    return ma.masked_equal(u_hist, 0)

def evaluate(params_dict, systematics, nu=True, shape_only=False):
    a_sys = systematics
    # a_sys, b_sys, c_sys = systematics
    e_bin_sizes = get_bin_sizes(E_BINNING).astype(float)
    x_bin_sizes = get_bin_sizes(X_BINNING).astype(float)
    y_bin_sizes = get_bin_sizes(Y_BINNING).astype(float)

    nu_histograms = unumpy.uarray(
        np.zeros(map(len, (e_bin_sizes, x_bin_sizes,
                           y_bin_sizes))).astype(float),
        np.zeros(map(len, (e_bin_sizes, x_bin_sizes,
                           y_bin_sizes))).astype(float)
    )
    scaling = []

    logging.info('a_systematic {0}'.format(a_sys))
    # logging.info('b_systematic {0}'.format(b_sys))
    # logging.info('c_systematic {0}'.format(c_sys))
    # weights = c_sys + np.power(params_dict['x_array'], -a_sys) * b_sys
    weights = np.power(params_dict['x_array'], -a_sys)

    if nu: nu_mask = params_dict['pdg_array'] > 0
    else: nu_mask = params_dict['pdg_array'] < 0
    for e_idx, e_bin in enumerate(E_BINNING[:-1]):
        energy_array = params_dict['energy_array']
        energy_mask = (energy_array >= e_bin) & \
                (energy_array < E_BINNING[e_idx + 1])
        weights_e = weights[energy_mask]
        y_array_e = params_dict['y_array'][energy_mask]
        x_array_e = params_dict['x_array'][energy_mask]
        nu_mask_e = nu_mask[energy_mask]

        sigma_nu  = 0
        nu_histograms[e_idx] = {}
        for x_idx, x_bin in enumerate(X_BINNING[:-1]):
            x_mask = (x_array_e >= x_bin) & (x_array_e < X_BINNING[x_idx+1])
            y_array_e_x = y_array_e[x_mask]
            weights_e_x = weights_e[x_mask]
            nu_mask_e_x = nu_mask_e[x_mask]

            sigma_nu_x_nw = make_histo(
                y_array_e_x[nu_mask_e_x], np.ones(weights_e_x[nu_mask_e_x].shape)
            )
            sigma_nu_x = make_histo(
                y_array_e_x[nu_mask_e_x], weights_e_x[nu_mask_e_x]
            )
            sigma_nu_x_e_nw = sigma_nu_x_nw * (1 / E_CENTERS[e_idx].astype(float))
            sigma_nu_x_e = sigma_nu_x * (1 / E_CENTERS[e_idx].astype(float))

            factors = 1 / (y_bin_sizes * x_bin_sizes[x_idx])
            nu_histograms[e_idx][x_idx] = sigma_nu_x_e * factors
            if shape_only:
                sigma_nu += np.sum(unumpy.nominal_values(sigma_nu_x_e.data))
            else:
                sigma_nu += np.sum(unumpy.nominal_values(sigma_nu_x_e_nw.data))

        if nu: scaling.append((WA_NU / 1E-38) / sigma_nu)
        else: scaling.append((WA_NUBAR / 1E-38) / sigma_nu)
    scaling = ma.masked_invalid(scaling)
    nu_histograms = ma.masked_equal(nu_histograms, 0)

    scaled_histograms = nu_histograms * \
            scaling[:, np.newaxis][:, np.newaxis]
    return scaled_histograms

def calculate_chi2(data, mc, corrmatr):
    data = unumpy.nominal_values(data).data.astype(float)
    mc = unumpy.nominal_values(mc).data.astype(float)
    diff = data - mc
    chi_squared = np.einsum('ijk,ijklmn,lmn->', diff, corrmatr, diff)

    return chi_squared

def wrap_calculation(systematics, args=None):
    NU_HISTOGRAMS = evaluate(
        args['params_dict'], systematics, nu=args['nu'],
        shape_only=args['shape_only']
    )
    chi_squared = calculate_chi2(
        args['data'], NU_HISTOGRAMS, args['inv_cov_matrix']
    )

    # if args['nu']: wa = WA_NU / 1E-38
    # else: wa = WA_NUBAR / 1E-38
    # x_bin_sizes = get_bin_sizes(X_BINNING).astype(float)
    # y_bin_sizes = get_bin_sizes(Y_BINNING).astype(float)
    # nuisance = 0
    # for e_idx in xrange(len(E_CENTERS)):
    #     integral = np.dot(np.dot(unumpy.nominal_values(NU_HISTOGRAMS[e_idx]),
    #                              y_bin_sizes), x_bin_sizes)
    #     nuisance += (((integral / wa) - 1) / 0.02) ** 2

    # chi_squared += nuisance
    logging.info('chi_squared = {0}\n'.format(chi_squared))
    return chi_squared

if __name__ == '__main__':
    set_verbosity(3)
    nu_data_matrix, nubar_data_matrix = load_nutev_xsec_vec()
    inv_cov_matrix_nu, inv_cov_matrix_nubar = load_nutev_corrmatrix()

    params_dict = load_genie_mc()
    params_dict = only_discc(params_dict)

    # nu = True
    nu = False

    # if nu:
    #     minim_result = opt.minimize(
    #         fun=wrap_calculation,
    #         x0=0.0757,
    #         args={'params_dict'    : params_dict,
    #               'data'           : nu_data_matrix,
    #               'inv_cov_matrix' : inv_cov_matrix_nu,
    #               'shape_only'     : True,
    #               'nu'             : True},
    #         method='L-BFGS-B',
    #         options={"disp"    : 0,
    #                  "ftol"    : 2e-7,
    #                  "eps"     : 1.0e-4,
    #                  "gtol"    : 1.0e-5,
    #                  "maxcor"  : 10,
    #                  "maxfun"  : 15000,
    #                  "maxiter" : 200}
    #     )

    # else:
    #     minim_result = opt.minimize(
    #         fun=wrap_calculation,
    #         x0=0.1008,
    #         args={'params_dict'    : params_dict,
    #               'data'           : nubar_data_matrix,
    #               'inv_cov_matrix' : inv_cov_matrix_nubar,
    #               'shape_only'     : True,
    #               'nu'             : False},
    #         method='L-BFGS-B',
    #         options={"disp"    : 0,
    #                  "ftol"    : 2e-7,
    #                  "eps"     : 1.0e-4,
    #                  "gtol"    : 1.0e-5,
    #                  "maxcor"  : 10,
    #                  "maxfun"  : 15000,
    #                  "maxiter" : 200}
    #     )

    # logging.info('{0}'.format(minim_result))
    if nu:
        opt_histogram = evaluate(
            # params_dict, minim_result.x, nu=True, shape_only=False
            params_dict, 0.15, nu=True, shape_only=False
        )
    else:
        opt_histogram = evaluate(
            # params_dict, minim_result.x, nu=False, shape_only=False
            params_dict, 0.15, nu=False, shape_only=False
        )

    x_bin_sizes = get_bin_sizes(X_BINNING).astype(float)
    y_bin_sizes = get_bin_sizes(Y_BINNING).astype(float)
    for e_idx, e_bin in enumerate(E_CENTERS):
        integral = 0
        for x_idx, x_bin in enumerate(X_CENTERS):
            integral += np.sum(opt_histogram[e_idx][x_idx].data * \
                               y_bin_sizes) * x_bin_sizes[x_idx]
        # print(integral)
        if nu: b = (WA_NU / 1E-38) / integral
        else: b = (WA_NUBAR / 1E-38) / integral
        print(b)

    # jacobian = np.array([1, minim_result.jac[0],
    #                      minim_result.jac[1], 1]).reshape((2, 2))
    # covariance = inv(np.dot(jacobian.T, jacobian))
    # logging.info('Covariance = {0}'.format(covariance))


import re
import sys

def parse_rule(rule):
    splitted_rule = rule.split(' bags contain ')
    out = splitted_rule[0]
    ins_raw = splitted_rule[1].split(', ')
    ins = []
    for in_raw in ins_raw:
        c = capture_color(in_raw)
        if c:
            ins.append(c)
    return out, ins

def capture_color(in_raw):
    if in_raw == "no other bags.":
        return
    capture_color_regex = re.compile("\d (.*) bags?")
    return capture_color_regex.match(in_raw).group(1)

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Missing input file: python {} file.".format(sys.argv[0]))
        sys.exit()

    with open(sys.argv[1]) as f:
        l = f.read().splitlines()

    ins_outs = {}

    for rule in l:
        out, ins = parse_rule(rule)
        for i in ins:
            ins_outs[i] = ins_outs.get(i, []) + [out]

    bags = set(["shiny gold"])
    colors_result = set()

    while bags:
        new_bags = set()
        for bag in bags:
            colors_result = colors_result.union(set(ins_outs.get(bag, [])))
            new_bags = new_bags.union(set(ins_outs.get(bag, [])))
        bags = new_bags

    print(len(colors_result))


# -*- indent-tabs-mode: t -*-

import soya
import soya.pudding as pudding

soya.init()
pudding.init()

scene = soya.World()

camera = soya.Camera(scene)

soya.set_root_widget(pudding.core.RootWidget())
soya.root_widget.add_child(camera)

text = pudding.control.SimpleLabel(soya.root_widget, label = "Hello World!",  autosize = True)

pudding.main_loop.MainLoop(scene).main_loop()


import math
import matplotlib.pyplot as plt
import tensorflow as tf
import tensordiffeq as tdq
from tensordiffeq.boundaries import *
from tensordiffeq.models import CollocationSolverND
from tensorflow.math import sin
from tensordiffeq.utils import constant

Domain = DomainND(["x", "y"])

Domain.add("x", [-1.0, 1.0], 1001)
Domain.add("y", [-1.0, 1.0], 1001)

N_f = 10000
Domain.generate_collocation_points(N_f)

def f_model(u_model, x, y):
    u = u_model(tf.concat([x, y], 1))
    u_x = tf.gradients(u, x)[0]
    u_y = tf.gradients(u, y)[0]
    u_xx = tf.gradients(u_x, x)[0]
    u_yy = tf.gradients(u_y, y)[0]

    a1 = constant(1.0)
    a2 = constant(4.0)
    ksq = constant(1.0)
    pi = constant(math.pi)

    # we use this specific forcing term because we have an exact analytical solution for this case
    # to compare the results of the PINN solution
    # note that we must use tensorflow math primitives such as sin, cos, etc!
    forcing = - (a1 * pi) ** 2 * sin(a1 * pi * x) * sin(a2 * pi * y) - \
              (a2 * pi) ** 2 * sin(a1 * pi * x) * sin(a2 * pi * y) + \
              ksq * sin(a1 * pi * x) * sin(a2 * pi * y)

    f_u = u_xx + u_yy + ksq * u - forcing  # = 0

    return f_u

upper_x = dirichletBC(Domain, val=0.0, var='x', target="upper")
lower_x = dirichletBC(Domain, val=0.0, var='x', target="lower")
upper_y = dirichletBC(Domain, val=0.0, var='y', target="upper")
lower_y = dirichletBC(Domain, val=0.0, var='y', target="lower")

BCs = [upper_x, lower_x, upper_y, lower_y]

layer_sizes = [2, 50, 50, 50, 50, 1]

model = CollocationSolverND()
model.compile(layer_sizes, f_model, Domain, BCs)

model.fit(tf_iter=10000, newton_iter=10000)

# get exact solution
nx, ny = (1001, 1001)
x = np.linspace(-1, 1, nx)
y = np.linspace(-1, 1, ny)

xv, yv = np.meshgrid(x, y)

x = np.reshape(x, (-1, 1))
y = np.reshape(y, (-1, 1))

# Exact analytical soln is available:
Exact_u = np.sin(math.pi * xv) * np.sin(4 * math.pi * yv)

# Flatten for use
u_star = Exact_u.flatten()[:, None]

# Plotting
x = Domain.domaindict[0]['xlinspace']
y = Domain.domaindict[1]["ylinspace"]

X, Y = np.meshgrid(x, y)

# print(np.shape((X,Y))) # 2, 256, 256
X_star = np.hstack((X.flatten()[:, None], Y.flatten()[:, None]))

lb = np.array([-1.0, -1.0])
ub = np.array([1.0, 1])

u_pred, f_u_pred = model.predict(X_star)

error_u = tdq.helpers.find_L2_error(u_pred, u_star)
print('Error u: %e' % (error_u))

U_pred = tdq.plotting.get_griddata(X_star, u_pred.flatten(), (X, Y))
FU_pred = tdq.plotting.get_griddata(X_star, f_u_pred.flatten(), (X, Y))

lb = np.array([-1.0, -1.0])
ub = np.array([1.0, 1.0])

tdq.plotting.plot_solution_domain1D(model, [x, y], ub=ub, lb=lb, Exact_u=Exact_u)


# Licensed to the .NET Foundation under one or more agreements.
# The .NET Foundation licenses this file to you under the Apache 2.0 License.
# See the LICENSE file in the project root for more information.

'''
Operations on enum type and its' members
'''
#------------------------------------------------------------------------------

import unittest

from iptest import IronPythonTestCase, run_test, skipUnlessIronPython

@skipUnlessIronPython()
class FieldMiscTest(IronPythonTestCase):
    def setUp(self):
        super(FieldMiscTest, self).setUp()
        self.add_clr_assemblies("fieldtests", "typesamples")

    def test_accessibility(self):
        from Merlin.Testing.FieldTest import DerivedMisc, Misc
        o = Misc()
        o.Set()
        self.assertEqual(o.PublicField, 100)
        self.assertIn('ProtectedField', dir(o))
        with self.assertRaises(TypeError):
            hasattr(o, 'ProtectedField')
        self.assertRaisesRegexp(AttributeError, "'Misc' object has no attribute 'PrivateField'", lambda: o.PrivateField)
        self.assertEqual(o.InterfaceField.PublicStaticField, 500)

        o = DerivedMisc()
        o.Set()
        self.assertEqual(o.PublicField, 400)
        self.assertIn('ProtectedField', dir(o))
        with self.assertRaises(TypeError):
            hasattr(o, 'ProtectedField')

run_test(__name__)