import json
from django.apps import apps
from django.core import serializers
from django.urls import reverse, reverse_lazy
from django.http import HttpResponse, JsonResponse
from django.db.models import Q
from django.views.generic import DetailView, ListView, TemplateView, View
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.mixins import LoginRequiredMixin

from directory.utils import get_model, get_linked_obj, get_detail_fields_mapping, get_child_list
from directory.views.routers import DIRECTORY_ITEMS
from utils.choices import get_choices, filters_choices

class ModelDetail(LoginRequiredMixin, DetailView):
    template_name = 'model_detail.jinja2'

    def dispatch(self, request, *args, **kwargs):
        self.model = get_model(kwargs.get('model_name', None))
        return super().dispatch(request, *args, **kwargs)

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data()
        context.update({
            'url': self.request.path,
            'title': self.model._meta.verbose_name,
            'model_name': self.model.__name__.lower(),
            'menu_items': DIRECTORY_ITEMS,
            'detail_list': get_detail_fields_mapping(context['object']),
            'child_list': get_child_list(self.object),
            'bread_crumbs': self.object.get_bread_crumbs()
        })
        obj = get_object_or_404(self.model, pk=self.kwargs.get('pk'))
        return context

class ModelList(LoginRequiredMixin, ListView):
    parent_model = None
    object = None
    related_name = None
    list_display = None
    count = 0
    permissions = []
    paging = dict()
    filters = {}

    def dispatch(self, request, *args, **kwargs):
        self.paging = dict(
            range=9,
            page=1,
            page_items=100,
            pages=1
        )
        # try:
        #     self.model = apps.get_model(request.GET.get('meta_label'))
        # except (ValueError, LookupError):
        self.model = get_model(kwargs.get('model_name') or request.GET.get('model_name'))
        self.permissions = self.model.get_permissions(request)
        parent_model_name = request.GET.get('parent_model_name', kwargs.get('parent_model_name'))
        if parent_model_name:
            self.parent_model = get_model(parent_model_name)
            pk = request.GET.get('parent_pk', kwargs.get('parent_pk'))
            self.object = self.parent_model.objects.get(pk=pk)
            self.related_name = request.GET.get('related_name', kwargs.get('related_name'))
            self.model = getattr(self.object, self.related_name).model
        self.list_display = ['id'] + getattr(self.model, 'list_display', [])

        self.paging['page'] = int(request.GET.get('page', 1))
        filters = self.model.get_filters(request)
        self.filters = filters_choices(request, filters, self.model)
        return super().dispatch(request, *args, **kwargs)

    def get_queryset(self):
        list_related = getattr(self.model, 'list_related', [])
        queryset = self.model.objects.all()
        if self.object and self.related_name:
            queryset = getattr(self.object, self.related_name).all()
        queryset = queryset.filter(self.model.get_filters_q(self.request)).select_related(*list_related)
        return queryset.distinct()

    def get_item_actions(self, pk):
        return [
            dict(
                name='edit', label='Редактировать'
            ),
            dict(
                name='detail', label='Детализация',
                url=reverse_lazy('directory:model_detail', kwargs={
                    'model_name': self.model.__name__.lower(), 'pk': pk
                }),
            )
        ]

    def get_items(self):
        items = []
        _queryset = self.get_queryset()

        # TODO: отфильтровать по группам доступа
        if self.model.__name__.lower() == 'servicetimetable':
            _queryset = _queryset.filter(service__in=get_choices(self.request, 'deal.Service', get_list=True))

        elif self.model.__name__.lower() == 'client':
            if (self.request.GET.get('phones') and len(self.request.GET.get('phones')) > 5) or \
                    (self.request.GET.get('full_name') and len(self.request.GET.get('full_name')) > 3):
                pass
            else:
                _queryset = _queryset.filter(
                    Q(rel_deals__deal__branch__in=get_choices(self.request, 'company.Branch', get_list=True)) |
                    Q(rel_deals=None)
                )

        begin = 1
        self.count = _queryset.count()
        if self.count:
            self.paging['pages'] = round(self.count / self.paging['page_items'] + 0.5)
            self.paging['page'] = \
                self.paging['page'] if self.paging['page'] <= self.paging['pages'] else self.paging['pages']
            begin = (self.paging['page'] - 1) * self.paging['page_items']
        for q_item in _queryset[begin:begin + self.paging['page_items']]:
            item = dict()  # {'actions': self.get_item_actions(q_item.pk)}
            for field_name in self.list_display:
                _q_item = q_item
                for field in field_name.split('__'):
                    try:
                        _q_item = getattr(q_item, 'get_%s_display' % field)()
                    except AttributeError:
                        if hasattr(_q_item, field):
                            _q_item = getattr(_q_item, field)
                item[field_name] = _q_item.__str__() if _q_item else ''
            items.append(item)

        return items

    def get(self, request, *args, **kwargs):
        if 'view' not in self.permissions:
            return JsonResponse(dict(answer='No permissions'), safe=False)
        if not request.GET:
            return render(request, 'app_vue.jinja2')

        context = dict(
            title=self.model._meta.verbose_name_plural,
            meta_label=self.model._meta.label,
            parent_model_name=self.parent_model.__name__.lower() if self.parent_model else '',
            model_name=self.model.__name__.lower(),
            url=self.request.path,
            actions=self.model.base_actions,
            bread_crumbs=self.object.get_bread_crumbs() if self.object else None,
            child_list=get_child_list(self.object),
            pk=self.object.pk if self.object else '',
            related_name=self.related_name,
            headers=self.model.get_headers(),
            items=self.get_items(),
            count=self.count,
            paging=self.paging,
            permissions=self.permissions,
            filters=self.filters,
        )

        if request.GET.get('debug'):
            from django.shortcuts import render_to_response
            return render_to_response('debug.jinja2', locals())

        return JsonResponse(context)


import time

#Found this on StackOverflow and adapted it to Python.
#http://stackoverflow.com/a/165745
daySuffix = ['th','st','nd','rd','th',
		'th','th','th','th','th'];

def node_to_speech(node):
	_speech_node = {'type':'speech','text':'Unparsed','public':True}

	if node['type'] == 'calendar_event':
		_start_time = time.strptime(node['starts'], '%Y-%m-%d %H:%M:%S')
		_day_name = time.strftime('%A',_start_time)

		#Borrowed from StackOverflow too.
		_day = int(time.strftime('%d',_start_time))
		if _day % 100 >= 11 and _day % 100 <= 13:
			_day = str(_day)+'th';
		else:
			_day = str(_day)+daySuffix[_day % 10];

		_title = node['title']

		_speech_node['text'] = '%s the %s, %s.' % \
			(_day_name,_day,_title)
	else:
		_speech_node['text'] = node['text']

	return _speech_node


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

from __future__ import absolute_import
from vilya.views.api import errors
from vilya.views.api.utils import RestAPIUI

class ContentsUI(RestAPIUI):
    _q_exports = []

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

    def _q_lookup(self, request, part):
        return ContentUI(self.project, part)

class ContentUI(RestAPIUI):
    _q_exports = []
    _q_methods = ['get']

    def __init__(self, project, path):
        self.project = project
        self.paths = [path]

    def get(self, request):
        repo = self.project.repo
        path = '/'.join(self.paths)
        ref = request.get_form_var("ref", "HEAD")
        item = repo.get_path_by_ref("%s:%s" % (ref, path))
        if not item:
            raise errors.NotFoundError('blob %s', path)
        if item.type != "blob":
            raise errors.NotFoundError('blob %s', path)
        commit = repo.get_last_commit(ref, path=path)
        r = item.as_dict()
        r['last_commit'] = commit.as_dict()
        return r

    def _q_lookup(self, request, part):
        self.paths.append(part)
        return self


# Oytun Demirbilek
# 150150032

import moviepy.video.io.VideoFileClip as mpy
import moviepy.editor as edit
import cv2
import numpy as np
from sklearn.svm import SVR
from sklearn.model_selection import KFold
import matplotlib.pyplot as plt

def MSE(y_pred, y_true):
    return np.sqrt(np.square(y_pred - y_true)).mean()

def get_nfold_split(X, number_of_folds, current_fold_id):
    kf = KFold(n_splits=number_of_folds)
    split_indices = kf.split(range(X.shape[0]))
    train_indices, test_indices = [(list(train), list(test)) for train, test in split_indices][current_fold_id]
    #Split train and test
    X_train = X[train_indices]
    X_test = X[test_indices]
    return X_train, X_test

def fix_camera(samples, truths, axis, n_folds=5):
    np.random.seed(1)

    # In part 3, we need to find a learned function that maps the OF with camera motion to the fixed one.
    max_err = 9999999
    best_model = None
    for f in range(n_folds):
        predictor = SVR(C=1.0, epsilon=0.2)
        X_train, X_test = get_nfold_split(samples,n_folds,f)
        Y_train, Y_test = get_nfold_split(truths,n_folds,f)
        predictor.fit(X_train,Y_train[:,axis])
        y_pred = predictor.predict(X_test)
        error = MSE(y_pred,Y_test[:,axis])
        if error < max_err: best_model = predictor
        print(f"MSE Fold {f}:",error)

    return best_model

def lucas_canade(frame0,frame1, x,y, window_size=5,camera_model=None):
    # Get index range of window.
    window_start= window_size // 2
    window_end= window_size // 2 + 1

    # Take derivatives.
    Ix = cv2.filter2D(frame0,-1,np.array([[-1,1],[-1,1]]))[ x-window_start : x+window_end, y-window_start : y+window_end]
    Iy = cv2.filter2D(frame0,-1,np.array([[-1,-1],[1,1]]))[ x-window_start : x+window_end, y-window_start : y+window_end]
    It = (cv2.filter2D(frame0,-1,np.ones((2,2))) + cv2.filter2D(frame1,-1,np.ones((2,2))*-1))[ x-window_start : x+window_end, y-window_start : y+window_end]

    # Find image structure tensor.
    A_T = np.array([Ix.flatten(),Iy.flatten()])
    A = np.array([Ix.flatten(),Iy.flatten()]).transpose()
    b = np.array([It.flatten()]).transpose()
    # Build equation: (u,v) = -(A_T.A)^-1.A_T.b
    motion_vector = np.matmul(np.matmul( -1*(np.linalg.pinv(np.matmul(A_T,A)) ),A_T),b)
    if camera_model is not None:
        x = camera_model[0].predict(motion_vector.T)[0]
        y = camera_model[1].predict(motion_vector.T)[0]
        return np.array([x,y])
    return motion_vector.squeeze()

def optical_flow(video, points=None, background_motion=None, next_images=1, update_pos=True, mark_region=False, camera_model=None):
    frame_count = video.reader.nframes
    video_fps = video.fps
    image_list = []
    frame_displacements = []
    if points is None: find_points = True
    else: find_points = False
    for i in range(frame_count-next_images):
        # Get video frames.
        walker_frame0 = video.get_frame(i*1.0/video_fps)
        if mark_region:
            # In part 2, region is marked as a red rectangle.
            walker_frame0 = cv2.rectangle(walker_frame0, tuple(points[0]), tuple(points[3]), color=(255,0,0), thickness=2)
        # Reduce noise and take the grayscale.
        im0 = cv2.medianBlur(walker_frame0,5)
        im0 = cv2.cvtColor(im0, cv2.COLOR_BGR2GRAY).astype(np.float32)
        if find_points:
            points = find_hand(walker_frame0)
            print("HAND LOC:",points)
        corner_displacements = []
        motion_list = []
        for p in points:
            x = p[0]
            y = p[1]
            # Calculate vectors for the next N frame sequence.
            for j in range(1,next_images+1):
                # j will be delta-t
                walker_frame1 = video.get_frame((i+j)*1.0/video_fps)
                # Reduce noise and take the grayscale.
                im1 = cv2.medianBlur(walker_frame1,5)
                im1 = cv2.cvtColor(im1, cv2.COLOR_BGR2GRAY).astype(np.float32)
                # Find optical flow of a given point between 2 images.
                motion = lucas_canade(im0,im1,y,x,window_size=5,camera_model=camera_model)
                print("OF:",motion)

                if background_motion is not None:
                    # In part 2, we subtract the background motion from calculated hand motion to reduce error.
                    # Background motion is the average/absmax of the calculated motion of the selected region on the wall.
                    fix = background_motion.mean(axis=(0,1))
                    # fix = absmaxND(fix,axis=0) # Take absolute max of the OF vectors of corners.
                    print("BACKGROUND:",fix)
                    motion = motion - fix
                # Normalize calculated velocity vector and find displacement by multiplying with delta-t
                if np.linalg.norm(motion) != 0: motion_list.append(motion*j)# / np.linalg.norm(motion))
                else: motion_list.append(np.zeros(2))
                #motion_list.append(motion)

            # Average displacement in the next N frame sequence.
            avg_displacement = np.round(np.array(motion_list).mean(axis=0)).astype(np.int32)
            displacement_x, displacement_y = avg_displacement[0], avg_displacement[1]
            corner_displacements.append(avg_displacement)
            #print("DISPLACEMENT:",avg_displacement)
            print(f"MOVES FROM: {x},{y} TO: {x-displacement_x},{y-displacement_y}")

            # Draw arrow. Exaggerated for better visualization.
            cv2.arrowedLine(walker_frame0,(x,y),(x+displacement_x*10, y+displacement_y*10),(255,255,255))

            if update_pos:
                # In order to track the hand, we will need to update its position.
                p[0] = x - displacement_x
                p[1] = y - displacement_y
        frame_displacements.append(np.array(corner_displacements))
        image_list.append(walker_frame0)
    return image_list, np.array(frame_displacements)

def part1():
    biped_vid = mpy.VideoFileClip("biped_1.avi")

    # (x,y) Corner of the green hand: (401,336) at first frame.
    x, y = 401, 334
    image_list,frame_displacements = optical_flow(biped_vid,[[x,y]],next_images=1,update_pos=True)

    clip = edit.ImageSequenceClip(image_list,fps=25)
    clip.write_videofile("test_hand_corners_part1_video.mp4",codec="libx264")
    np.save("truth_biped_1_hand.npy",np.array(frame_displacements))

def part2():
    biped_vid = mpy.VideoFileClip("biped_2.avi")

    # Region motion.
    corners = [[210,183],[308,183],[210,315],[308,315]]
    image_list,region_displacements = optical_flow(biped_vid,corners,next_images=1, update_pos=False, mark_region=True)

    clip = edit.ImageSequenceClip(image_list,fps=25)
    clip.write_videofile("test_part2_video_region.mp4",codec="libx264")
    np.save("truth_biped_2_region.npy",np.array(region_displacements))

    # Hand motion.
    x, y = 401, 334
    region_displacements = np.load("truth_biped_2_region.npy")
    image_list,frame_displacements = optical_flow(biped_vid,[[x,y]],next_images=1, background_motion=None) # Considering background motion did not give better results.

    clip = edit.ImageSequenceClip(image_list,fps=25)
    clip.write_videofile("test_part2_video_hand_wallignored.mp4",codec="libx264")
    np.save("truth_biped_2_hand_wallignored.npy",np.array(frame_displacements))

def part3():
    biped_vid = mpy.VideoFileClip("biped_3.avi")

    hand_truth = np.load("truth_biped_1_hand.npy")
    region_truth = np.load("truth_biped_2_region.npy")

    # Region motion.
    corners = [[210,183],[308,183],[210,315],[308,315]]
    image_list,region_displacements = optical_flow(biped_vid,corners,next_images=1,update_pos=False, mark_region=True)

    clip = edit.ImageSequenceClip(image_list,fps=25)
    clip.write_videofile("test_part3_video_region.mp4",codec="libx264")
    np.save("truth_biped_3_region.npy",np.array(region_displacements))

    region_displacements= np.load("truth_biped_3_region.npy")
    print("Mean Squared Error (REGION): ",MSE(region_displacements,region_truth))
    region_shape = region_truth.shape
    print("-------------------------------------------------------------------")
    print("Model X Axis")
    model_x = fix_camera(region_displacements.reshape((region_shape[0]*region_shape[1],region_shape[2])),region_truth.reshape((region_shape[0]*region_shape[1],region_shape[2])), axis=0)
    print("-------------------------------------------------------------------")
    print("Model Y Axis")
    model_y = fix_camera(region_displacements.reshape((region_shape[0]*region_shape[1],region_shape[2])),region_truth.reshape((region_shape[0]*region_shape[1],region_shape[2])), axis=1)
    print("-------------------------------------------------------------------")

    # Hand motion.
    x, y = 401, 334
    image_list,frame_displacements = optical_flow(biped_vid,[[x,y]],next_images=1,camera_model=(model_x,model_y))

    clip = edit.ImageSequenceClip(image_list,fps=25)
    clip.write_videofile("test_part3_video_hand.mp4",codec="libx264")
    np.save("truth_biped_3_hand.npy",np.array(frame_displacements))

    hand_displacements= np.load("truth_biped_3_hand.npy")
    print("Mean Squared Error (HAND): ",MSE(hand_displacements,hand_truth))


import numpy as np
from astropy.io.fits import file

def sign(x):
    """
    Return 1 if x is positive, -1 if it's negative, and 0 if it's zero.
    """
    if x > 0:
        return 1
    elif x < 0:
        return -1
    else:
        return 0

def vertex_sign(P, O):
    """
    Sign of the vertex P with respect to O, as defined above.
    """
    #print("0   ", sign(P[0] - O[0]))
    #print("1   ", sign(P[1] - O[1]))
    #print("2   ", sign(P[2] - O[2]))
    result = sign(P[0] - O[0]) or sign(P[1] - O[1]) or sign(P[2] - O[2])
    print(result)

    if not result:
       raise ValueError("vertex coincides with origin")
    return result

def edge_sign(P, Q, O):
    """
    Sign of the edge PQ with respect to O, as defined above.
    """
    result = (
        sign((P[1] - O[1]) * (Q[0] - O[0]) - (P[0] - O[0]) * (Q[1] - O[1])) or
        sign((P[2] - O[2]) * (Q[0] - O[0]) - (P[0] - O[0]) * (Q[2] - O[2])) or
        sign((P[2] - O[2]) * (Q[1] - O[1]) - (P[1] - O[1]) * (Q[2] - O[2]))
    )
    #if not result:
        # with origin")
    return result

def triangle_sign(P, Q, R, O):
    """
    Sign of the triangle PQR with respect to O, as defined above.
    """
    m1_0 = P[0] - O[0]
    m1_1 = P[1] - O[1]
    m2_0 = Q[0] - O[0]
    m2_1 = Q[1] - O[1]
    m3_0 = R[0] - O[0]
    m3_1 = R[1] - O[1]
    result = sign(
        (m1_0 * m2_1 - m1_1 * m2_0) * (R[2] - O[2]) +
        (m2_0 * m3_1 - m2_1 * m3_0) * (P[2] - O[2]) +
        (m3_0 * m1_1 - m3_1 * m1_0) * (Q[2] - O[2]))
    if not result:
        raise ValueError("vertices coplanar with origin")
    return result

def triangle_chain(v1, v2, v3, origin):
    """
    Return the contribution of this triangle to the winding number.
    Raise ValueError if the face contains the origin.
    """
    v1sign = vertex_sign(v1, origin)
    v2sign = vertex_sign(v2, origin)
    v3sign = vertex_sign(v3, origin)

    face_boundary = 0
    if v1sign != v2sign:
        face_boundary += edge_sign(v1, v2, origin)
    if v2sign != v3sign:
        face_boundary += edge_sign(v2, v3, origin)
    if v3sign != v1sign:
        face_boundary += edge_sign(v3, v1, origin)
    if not face_boundary:
        return 0

    return triangle_sign(v1, v2, v3, origin)

def winding_number(point):
            x, y, z = point
            if -1 < x < 1 and -1 < y < 1 and -1 < z < 1:
                return "inside"
            if -1 <= x <= 1 and -1 <= y <= 1 and -1 <= z <= 1:
                return "boundary"
            return "outside"

class Polyhedron(object):
    def __init__(self, triangles, vertex_positions):
        """
        Initialize from list of triangles and vertex positions.
        """
        # Validate: check the combinatorial data.
        edges = set()
        vertices = set()
        for triangle in triangles:
            vertices.update(triangle)
            P, Q, R = triangle
            for edge in ((P, Q), (Q, R), (R, P)):
                if edge[0] == edge[1]:
                    raise ValueError("Self edge: {!r}".format(edge))
                if edge in edges:
                    raise ValueError("Duplicate edge: {!r}".format(edge))
                edges.add(edge)

        # For each edge that appears, the reverse edge should also appear.
        for P, Q in edges:
            if not (Q, P) in edges:
                raise ValueError("Unmatched edge: {!r}".format((P, Q)))

        # Vertex set should match indices in vertex_positions.
        if vertices != set(range(len(vertex_positions))):
            raise ValueError("Vertex set doesn't match position indices.")

        # Vertex positions in R^3.
        self.vertex_positions = vertex_positions
        # Indices making up each triangle, counterclockwise
        # around the outside of the face.
        self.triangles = triangles

    def triangle_positions(self):
        """
        Triples of vertex positions.
        """
        for triangle in self.triangles:
            yield tuple(self.vertex_positions[vx] for vx in triangle)

    def volume(self):
        """
        Return the volume of this polyhedron.
        """
        acc = 0
        for p1, p2, p3 in self.triangle_positions():
            # Twice the area of the projection onto the x-y plane.
            det = ((p2[1] - p3[1]) * (p1[0] - p3[0]) -
                   (p2[0] - p3[0]) * (p1[1] - p3[1]))
            # Three times the average height.
            height = p1[2] + p2[2] + p3[2]
            acc += det * height
        return acc / 6.0

    def winding_number(self, point):
        """Determine the winding number of *self* around the given point.
        """
        return sum(
            triangle_chain(v1, v2, v3, point)
            for v1, v2, v3 in self.triangle_positions()) // 2
"""
def read_off(file):
    #if 'OFF' != file.readline().strip():
     #   raise('Not a valid OFF header')
    n_verts, n_faces, n_dontknow = tuple([int(s) for s in file.readline().strip().split(' ')])
    verts = [[float(s) for s in file.readline().strip().split(' ')] for i_vert in range(n_verts)]
    faces = [[int(s) for s in file.readline().strip().split(' ')][1:] for i_face in range(n_faces)]
    return verts, faces
"""

import os
import sys

def read_off(file):
    """
    Reads vertices and faces from an off file.

    :param file: path to file to read
    :type file: str
    :return: vertices and faces as lists of tuples
    :rtype: [(float)], [(int)]
    """

    assert os.path.exists(file)

    with open(file, 'r') as fp:

        lines = fp.readlines()
        lines = [line.strip() for line in lines]
        assert lines[0] == 'OFF'

        parts = lines[1].split(' ')
        assert len(parts) == 3

        num_vertices = int(parts[0])
        assert num_vertices > 0

        num_faces = int(parts[1])
        assert num_faces > 0

        vertices = []
        for i in range(num_vertices):

            vertex = lines[2 + i+1].split(' ')

            vertex = [float(point) for point in vertex]
            assert len(vertex) == 3

            vertices.append(vertex)

        faces = []
        for i in range(num_faces):

            face = lines[2 + num_vertices + i + 1].split(' ')
            face = [int(index) for index in face]

            #print(face[0], "  " , len(face) - 1)
            #assert face[0] == len(face) - 1
            for index in face:
                assert index >= 0 and index < num_vertices

            assert len(face) > 1

            faces.append(face)

        return vertices, faces
if __name__ == "__main__":
    file = '0.off'
    vertices, faces = read_off(file)
    point = [0,0,0.25]
    print(Polyhedron(faces,vertices).winding_number(point))
    #return verts, faces


from django.shortcuts import render
from django.http import JsonResponse, HttpResponse
from .models import Student, Course

def get_students(request):
    students = Student.objects.all().values()
    output = [entry for entry in students]
    return JsonResponse(output, safe=False)

def create_student(request):
    if request.method == "POST":
        data = request.POST
        name = data.get("name")
        surname = data.get("surname")
        course_id = data.get("course")

        #course = Course.objects.get(id=course_id)

        student = Student.objects.create(
            name=name,
            surname=surname,
            course_id=course_id
        )

        student.save()
        return HttpResponse(status=200)

def delete_student(request):
    if request.method == "POST":
        data = request.POST
        student_id = data.get("student_id")
        student = Student.objects.get(id=student_id)
        student.delete()
        student.save()
        return HttpResponse(status=200)


# Program to display the Fibonacci sequence up to n-th term

nterms = int(input("How many terms? "))

# first two terms
n1, n2 = 0, 1
count = 0

# check if the number of terms is valid
if nterms <= 0:
    print("Please enter a positive integer")
# if there is only one term, return n1
elif nterms == 1:
    print("Fibonacci sequence upto", nterms, ":")
    print(n1)
# generate fibonacci sequence
else:
    print("Fibonacci sequence:")
    print(n1, ",", n2, end=', ')
    while count < nterms:
        print(n1)
        nth = n1 + n2
        # update values
        n1 = n2
        n2 = nth
        count += 1

# Fibonacci Sequence Using Recursion

def fibo(n):
    if n <= 1:
        return n
    else:
        return(fibo(n-1)+fibo(n-2))

nterms = int(input("Enter the number of Terms you want: "))
if nterms <= 0:
    print("Please enter a positive integer")
else:
    print("Fibonacci Sequence:")
    for i in range(nterms):
        print(fibo(i))


import math
import numpy as np
import matplotlib.pyplot as plt

def A(a1, a2):
    """Створення матриці А з заданими параметрами а1 та а2"""
    A = np.zeros((3, 3))
    A[0][1] = 1
    A[1][2] = 1
    A[2][0] = -1
    A[2][1] = -a1
    A[2][2] = -a2
    return A

def B(b):
    """Створення матриці B з заданим параметром b"""
    B = np.zeros((3, 1))
    B[0][0] = 0
    B[1][0] = 0
    B[2][0] = b
    return B

def C():
    """Створення матриці C"""
    C = []
    for i in range(3):
        value = np.zeros((1, 3))
        if i != 0:
            value[0][i] = 0
        else:
            value[0][i] = 1
        C.append(value)
    return C

def F(x, t, q):
    """Обрахуємо F = e^(A*T0)"""
    I = np.eye(3)  # одинична матриця n*n
    for i in range(1, q + 1):
        I += np.linalg.matrix_power(x.dot(t), i) / math.factorial(i)
    return I

def G(x, q, t, b):
    """Обрахуємо G = I*B*(T0 + (A*T0^2)/2! + ... + (A^q-1*T0^q)/q!)"""
    b1 = B(b)
    I = np.eye(3)
    tmp = b1*I
    for j in range(2, q):
        tmp += (np.linalg.matrix_power(x, j - 1).dot(I) * (t ** j)) / math.factorial(j)
    return tmp.dot(b1)

def formulaX(f, x, u, g):
    """Обрахуємо Xk+1 = F*Xk + G*Uk"""
    res = f.dot(x) + g * u
    return res

def X():
    x = np.zeros((3, 1))
    x[0][0] = 0
    x[1][0] = 0
    x[2][0] = 0
    return x

def formulaY(x, c, y):
    """Обрахуємо y = C*x"""
    y.append(c.dot(x))
    return y

def variables():
    """Задаємо параметри"""
    a1 = float(input('Введіть a1 для матриці A: '))
    a2 = float(input('Введіть a2 для матриці A: '))
    b = float(input('Введіть b для матриці B: '))
    t0 = float(input('Введіть T0:'))
    q = int(input('Введіть q:'))
    var = [a1, a2, t0, q, b]

    return var

def main():
    vars = variables()
    vec = X()
    t = list(np.arange(0, 200 + vars[2], vars[2]))
    a = A(vars[0], vars[1])
    f = F(a, vars[2], vars[3])
    g = G(a, vars[3], vars[2], vars[4])
    x = []
    x.append(vec)
    option = int(input('Виберіть один варіант з трьох: '))
    if option == 1:
        u = 1
        for i in range(len(t)):
            vec = formulaX(f, vec, u, g)
            x.append(vec)
    elif option == 2:
        k0 = 15//vars[2]
        u = 1
        for i in range(len(t)):
            vec = formulaX(f, vec, u, g)
            x.append(vec)
            if t[i] == k0:
                u = -1
    elif option == 3:
        k0 = 15//vars[2]
        u = 1
        k = 0
        for i in range(len(t)):
            vec = formulaX(f, vec, u, g)
            x.append(vec)
            if k == k0:
                u = -1
            elif k == 2 * k0:
                u = -1
            elif k == 3 * k0:
                u = 1
            k += 1
    else:
        print("Немає такого варіанту")
        return 0

    y = []
    for i in x:
        y = formulaY(i, C()[0], y)
    list_x = []
    for i in y:
        a = i.tolist()
        list_x.append(a[0])
    list_y = []
    for i in range(len(list_x) - 1):
        list_y.append(list_x[i][0])

    """Графік"""
    plt.xlabel('t')
    plt.ylabel('y(t)')
    plt.grid()
    plt.xticks(np.arange(t[0], t[-1] + 1, 20))
    plt.plot(t, list_y, color='red')
    plt.show()

main()

"""Параметри для дослідження"""
# 1) a1 = 1, a2 = 10, b = 1, t0 = 0.0001, q = 10
# 2) a1 = 1, a2 = 1, b = 1, t0 = 0.0001, q = 10
# 3) a1 = 10, a2 = 1, b = 1, t0 = 0.0001, q = 10


# swapChars(firstIndex, secondIndex, string)
# Parameters
# firstIndex - an integral JavaScript Number
# secondIndex - an integral JavaScript Number
# string - any JavaScript String
# Return Value
# string with the characters at firstIndex and secondIndex swapped.

# Examples
# swapChars(0, 1, 'lodash') // -> "oldash"
# swapChars(0, 4, 'React') // -> "teacR"
# swapChars(6, 7, 'complete') // -> "compleet"
# swapChars(0, 8, 'LearningFuze') // -> "FearningLuze"
# swapChars(11, 23, 'HTML, CSS, JavaScript, React') // -> "HTML, CSS, RavaScript, Jeact"

def swapChars(firstIndex, secondIndex, string) :
    output = ''
    i = 0
    while i < len(string) :
        if i == firstIndex :
            output = output + string[secondIndex]
        elif i == secondIndex :
            output = output + string[firstIndex]
        else :
            output = output + string[i]
        i = i + 1
    return output

print(swapChars(0, 1, 'lodash'))
print(swapChars(0, 4, 'React'))
print(swapChars(6, 7, 'complete'))
print(swapChars(0, 8, 'LearningFuze'))
print(swapChars(11, 23, 'HTML, CSS, JavaScript, React'))


VERSION = '1.0'

import json
from argparse import ArgumentParser
from os import getenv

def parse_args():
    parser = ArgumentParser('Terraform dynamic inventory for Ansible')
    parser.add_argument('--list', action='store_true', default=True, help='List nodes (default: True)')
    parser.add_argument('--host', help='Get all the variables about a specific node')
    parser.add_argument('--tfstate', '-t', help='Terraform state file (terraform.tfstate default)')
    parser.add_argument('--version', '-v', help='Show version')
    args = parser.parse_args()
    if not args.tfstate:
        args.tfstate = getenv('TF_STATE', 'terraform.state')
    return args

def parse_tfstate(filename):
    return json.load(open(filename))

def find_value(dictionary, keys):
    values = [dictionary[k] for k in keys if k in dictionary]  # get values for existing keys
    values = [v for v in values if v]  # filter empty values
    if values:
        return values[0]

class TerraformInventory:
    def __init__(self):
        self.args = parse_args()
        if self.args.version:
            print(VERSION)
        elif self.args.host:
            print(self.get_host(self.args.host))
        elif self.args.list:
            print(self.get_list())

    def get_list(self):
        hosts = []
        hosts_vars = {}
        for address, vars in self.get_instances():
            hosts.append(address)
            hosts_vars[address] = vars
        return json.dumps({'all': {'hosts': hosts}, '_meta': {'hostvars': hosts_vars}}, indent=2)

    def get_host(self, host):
        for address, vars in self.get_instances():
            if address == host:
                return json.dumps(vars, indent=2)

    def get_instances(self):
        tfstate = parse_tfstate(self.args.tfstate)
        for module in tfstate['modules']:
            for resource in module['resources'].values():
                if resource['type'] not in ('aws_instance', 'openstack_compute_instance_v2'):
                    continue
                if resource['type'] == 'aws_instance':
                    provider = 'aws'
                    address = find_value(resource['primary']['attributes'],
                                         ('public_dns', 'public_ip', 'private_dns', 'private_ip'))
                elif resource['type'] == 'openstack_compute_instance_v2':
                    provider = 'openstack'
                    address = find_value(resource['primary']['attributes'],
                                         ('floating_ip', 'access_ip_v4', 'access_ip_v6'))
                else:
                    continue
                vars = resource['primary']['attributes']
                vars['provider'] = provider
                yield address, vars

if __name__ == '__main__':
    TerraformInventory()


"""
任务：使用作用域中相关的关键字修改下列 begin-end 中的代码，使函数 average 实现计算平均分的功能。
"""

# 请在下面的Begin-End之间按照注释中给出的提示编写正确的代码
##########Begin##########
# 请使用作用域相关的关键字修改下列代码，实现计算平均分的功能
def average(*args):
    def sum(args):
        global score
        score  = 0
        for x in args:
            score += x
    sum(args)
    return score / len(args)
##########End##########
result = average(56,76,84,98,78,79,89,67,86,78,67,67,95,24,96,96,86,65,83,86,80)
print(result)

学习-Python函数之变量的作用域.py


from argparse import ArgumentParser
from os import mkdir
from os.path import join, exists
import h5py
import sys

def write_mesh_as_obj(fname, verts, faces):
    with open(fname, 'w') as fp:
        for v in verts:
            fp.write('v %f %f %f\n' % (v[0], v[1], v[2]))
        for f in faces + 1:  # Faces are 1-based, not 0-based in obj files
            fp.write('f %d %d %d\n' % (f[0], f[1], f[2]))

if __name__ == '__main__':

    # Subject ids
    sids = ['50002', '50004', '50007', '50009', '50020',
            '50021', '50022', '50025', '50026', '50027']
    # Sequences available for each subject id are listed in scripts/subjects_and_sequences.txt

    parser = ArgumentParser(description='Save sequence registrations as obj')
    parser.add_argument('--path', type=str, default='../registrations_f.hdf5',
                        help='dataset path in hdf5 format')
    parser.add_argument('--seq', type=str, default='jiggle_on_toes',
                        help='sequence name')
    parser.add_argument('--sid', type=str, default='50004', choices=sids,
                        help='subject id')
    parser.add_argument('--tdir', type=str, default='./',
                        help='target directory')
    args = parser.parse_args()

    sidseq = args.sid + '_' + args.seq
    with h5py.File(args.path, 'r') as f:
        if sidseq not in f:
            print('Sequence %s from subject %s not in %s' % (args.seq, args.sid, args.path))
            f.close()
            sys.exit(1)
        verts = f[sidseq][...].transpose([2, 0, 1])
        faces = f['faces'][...]

    tdir = join(args.tdir, sidseq)
    if not exists(tdir):
        mkdir(tdir)

    # Write to an obj file
    for iv, v in enumerate(verts):
        fname = join(tdir, '%05d.obj' % iv)
        print('Saving mesh %s' % fname)
        write_mesh_as_obj(fname, v, faces)


from typing import Any, Dict

from app.funcs.query_processors import (
    NetworkPlotSchemaInput,
    TopicQueryProcessor,
)
from app.utils.data_table import NodeCol, RelCol
from app.utils.url_helpers import data_table_node_link, data_table_rel_link

from .diagram import cypher_diagram
from .graph import create_edge_schemas, node_schemas

master_name = "confounder"
EXPOSURE_DESC = "Exposure {gwas}.".format(gwas=data_table_node_link("Gwas"))
OUTCOME_DESC = "Outcome {gwas}".format(gwas=data_table_node_link("Gwas"))
CF_DESC = """
Confounder* {gwas}.

*subject to the option `confounder_type`, `cf`
can be a confounder, intermediate, reverse intermediate, or collider
(see documentation for further details).
""".format(
    gwas=data_table_node_link("Gwas")
)
R1_DESC = """
{MR_EVE_MR} between exposure and `cf`.

Direction of the MR evidence is determined by `confounder_type`
(see documentation for further details).
""".format(
    MR_EVE_MR=data_table_rel_link("MR_EVE_MR")
)
R2_DESC = """
{MR_EVE_MR} from exposure to outcome.
""".format(
    MR_EVE_MR=data_table_rel_link("MR_EVE_MR")
)
R3_DESC = """
{MR_EVE_MR} between outcome and `cf`.

Direction of the MR evidence is determined by `confounder_type`
(see documentation for further details).
""".format(
    MR_EVE_MR=data_table_rel_link("MR_EVE_MR")
)
table_col_configs = {
    "cf.id": NodeCol("Gwas", "id", CF_DESC),
    "cf.trait": NodeCol("Gwas", "trait", CF_DESC),
    "exposure.id": NodeCol("Gwas", "id", EXPOSURE_DESC),
    "exposure.trait": NodeCol("Gwas", "trait", EXPOSURE_DESC),
    "outcome.id": NodeCol("Gwas", "id", OUTCOME_DESC),
    "outcome.trait": NodeCol("Gwas", "trait", OUTCOME_DESC),
    "r1.b": RelCol("MR_EVE_MR", "b", R1_DESC, rounding=True),
    "r1.method": RelCol("MR_EVE_MR", "method", R1_DESC),
    "r1.moescore": RelCol("MR_EVE_MR", "moescore", R1_DESC),
    "r1.pval": RelCol("MR_EVE_MR", "pval", R1_DESC),
    "r1.se": RelCol("MR_EVE_MR", "se", R1_DESC, rounding=True),
    "r1.selection": RelCol("MR_EVE_MR", "selection", R1_DESC),
    "r2.b": RelCol("MR_EVE_MR", "b", R2_DESC, rounding=True),
    "r2.method": RelCol("MR_EVE_MR", "method", R2_DESC),
    "r2.moescore": RelCol("MR_EVE_MR", "moescore", R2_DESC),
    "r2.pval": RelCol("MR_EVE_MR", "se", R2_DESC),
    "r2.se": RelCol("MR_EVE_MR", "se", R2_DESC, rounding=True),
    "r2.selection": RelCol("MR_EVE_MR", "selection", R2_DESC),
    "r3.b": RelCol("MR_EVE_MR", "b", R3_DESC, rounding=True),
    "r3.method": RelCol("MR_EVE_MR", "method", R3_DESC),
    "r3.moescore": RelCol("MR_EVE_MR", "moescore", R3_DESC),
    "r3.pval": RelCol("MR_EVE_MR", "pval", R3_DESC),
    "r3.se": RelCol("MR_EVE_MR", "se", R3_DESC, rounding=True),
    "r3.selection": RelCol("MR_EVE_MR", "selection", R3_DESC),
}

class ConfounderQueryProcessor(TopicQueryProcessor):
    def __init__(self, params: Dict[str, Any], type: str = "confounder"):
        super().__init__(
            master_name=master_name,
            params=params,
            table_col_configs=table_col_configs,
            network_plot_schema=NetworkPlotSchemaInput(
                node_schemas=node_schemas,
                edge_schemas=create_edge_schemas(type=type),
            ),
            cypher_diagram_fn=cypher_diagram,
        )


def cheap_regex(pattern, string):
    i = 0
    max_i = len(string)
    q = 0
    for p, x in enumerate(pattern):
        if i > max_i:
            return False
        if q: #if the placeholder from * is here
            if x == '*':
                continue
            if x == '?':
                i += 1
                continue
            if x != string[i]:
                while i <= max_i:
                    i += 1
                    if x == string[i]:
                        continue
            q = False
        if x == '?': #just iterate through the next character, but advance the index of string by one
            i += 1
            continue
        if x == '*':
            if p == len(pattern)-1: #if this is the last
                return True
            else:
                q = True #otherwise, we put in a placeholer
        if x != string[i]: #if they dont match, it's false
            return False
        i += 1
    if i < max_i:
        return False
    return True #if the pattern is small

import re
def real_regex(pattern, string):
    regex_pattern = ""
    for x in pattern:
        if x == '?':
            regex_pattern += '.'
        elif x == '*':
            regex_pattern += '.*'
        else:
            regex_pattern += x
    print(regex_pattern)
    return (re.search(regex_pattern, string).group(0) == string)

if __name__ == '__main__':
    print(cheap_regex('g*?','gross')) #honestly i give up
    print(real_regex('g*???s','gross'))


#!/usr/bin/env python
from pathlib import Path
import subprocess
from versions import get_versions_data, write_versions_json

INDEX_HTML = r'''<!DOCTYPE html>

    <meta http-equiv="Refresh" content="0; url={default_branch}" />

Got to default documentation.

'''

def write_index_html(default_branch):
    """Write an index.html that redirects to the DEFAULT_BRANCH."""
    with open("index.html", "w") as out_fh:
        out_fh.write(INDEX_HTML.format(default_branch=default_branch))
    subprocess.run(['git', 'add', 'index.html'], check=True)

def find_downloads(folder):
    """Find files in the 'download' subfolder of the given `folder`."""
    downloads = []
    for filename in Path(folder).glob(r'download/*'):
        label = "".join(filename.suffixes).replace('.', '').lower()
        if len(label) > 0:
            downloads.append((label, str(filename)))
    return downloads

def main():
    """Main function."""
    print("Post-processing documentation on gh-pages")
    print("Gather versions info")
    versions_data = get_versions_data(find_downloads=find_downloads)
    latest_release = versions_data['latest_release']
    if latest_release is None:
        latest_release = 'master'
    print("Write index.html")
    write_index_html(latest_release)
    print("Write versions.json")
    write_versions_json(versions_data, outfile='versions.json')
    print("DONE post-processing")

if __name__ == "__main__":
    main()


from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand
from django.db.utils import IntegrityError
from django.core.files import File
import os

class Command(BaseCommand):
    help = 'Creates demo users'

    def handle(self, *args, **options):

        User = get_user_model()

        avatars = ["avatar01.png", "avatar02.png", "avatar03.png", "avatar04.png"]

        demo_users = [
            {
                "name": "rebecca",
                "email": "rebecca@company.com",
                "avatar": avatars[0],
                "is_active": True,
            },
            {
                "name": "williams",
                "email": "williams@company.com",
                "avatar": avatars[1],
                "is_active": True,
            },
            {
                "name": "leo",
                "email": "leo@company.com",
                "avatar": avatars[2],
                "is_active": True,
            },
            {
                "name": "katherine",
                "email": "katherine@company.com",
                "avatar": avatars[3],
                "is_active": True,
            }
        ]

        for demo_user in demo_users:
            try:
                user = User.objects.create_user(
                    demo_user['email'],
                    demo_user['name'],
                    os.getenv('VUE_APP_DEMO_PASSWORD', 'demopwd123'),
                )

                avatar = open(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'img', demo_user['avatar'])), "rb")  # noqa: E501

                django_file = File(avatar)

                user.avatar.save(demo_user['avatar'], django_file, save=True)

                user.save()
                print(f"Created demo user {user.email}.")

            except IntegrityError:
                print(f"Demo user {demo_user['email']} already exists")


import pygame

class Bird:

    def __init__(self, sets, screen):
        """初始化bird设置"""
        self.screen = screen
        self.sets = sets
#       加载鸟儿
        self.image = pygame.image.load('images/bird.png')
        self.rect = self.image.get_rect()
        self.screen_rect = self.screen.get_rect()
#       放置鸟儿
        self.rect.left = self.screen_rect.left + 100
        self.rect.top = 0.5 * self.screen_rect.bottom
#        #在bird的属性y中存储小数值
        self.y = float(self.rect.y)
#        移动标识
        self.moving_down = False
        self.moving_up = False

    def update(self):
        if self.moving_down and self.rect.bottom < self.screen_rect.bottom:
            self.y += self.sets.bird_speed
        if self.moving_up and self.rect.y > 0:
            self.y -= self.sets.bird_speed
        self.rect.y = self.y

    def center(self):
        """居中"""
        self.y = 0.5 * self.screen_rect.bottom

    def blitme(self):
        """绘制鸟儿"""
        self.screen.blit(self.image, self.rect)


import random
import time

# fix sound delay
# import pygame
# pygame.mixer.pre_init(22050, -16, 2, 1024)
# pygame.init()
# pygame.mixer.quit()
# pygame.mixer.init(22050, -16, 2, 1024)

# set height and width of screen
WIDTH = 500
HEIGHT = 400

# setup actor
ball = Actor('beach_ball', anchor=('center', 'bottom'),pos=(WIDTH/2,HEIGHT/2))
ball.xspeed = 0
ball.yspeed = 0

# physics constants
GRAVITY = .1
WIND = 0#random.uniform(-0.2,0.2)

# global variable for score
score = 0

# if player clicks on ball, bounce it up and increase the score
def on_mouse_down(pos, button):
    global score
    if ball.collidepoint(pos) and button == mouse.LEFT:
        ball.yspeed = -3
        ball.xspeed = random.randint(-15,15)
        sounds.pop.play()
        score += 1

# draw ball and score
def draw():
    screen.clear()
    ball.draw()
    screen.draw.text("score: " + str(score), (0,0))

# move the ball and bounce off walls
def update():
    # apply gravity
    ball.yspeed += GRAVITY
    ball.xspeed += WIND

    # update position
    ball.x += ball.xspeed
    ball.y += ball.yspeed

    # bounce off right
    if ball.right > WIDTH:
        ball.right = WIDTH
        ball.xspeed = -ball.xspeed
    # bounce off left
    if ball.left < 0:
        ball.left = 0
        ball.xspeed = -ball.xspeed

def wait():
    time.sleep(1.5)
clock.schedule(wait,0)


from game_of_greed.game_of_greed import GameLogic, Banker
# from game_of_greed import GameLogic, Banker

import sys
class Game:

    def __init__(self, roller=None):
        self.roller= roller or GameLogic.role_dice

    @staticmethod
    def print_roll(roll):
        roll_as_string = [str(i) for i in roll]
        to_be_printed = ','.join(roll_as_string)

        return to_be_printed

    @staticmethod
    def convert_to_tup(str_val):
        new_str = [int(i) for i in str_val]
        new_tup= tuple(new_str)
        return new_tup

    def play(self):
        round = 1
        num_dice = 6
        score = 0
        x = Banker()

        print("Welcome to Game of Greed")
        response = input("Wanna play?")
        if response == 'n':
            print("OK. Maybe another time")
        elif response == 'y':
            print(f"Starting round {round}")
            print(f"Rolling {num_dice} dice...")
            roll = self.roller(num_dice)
            print(Game.print_roll(roll))
            self.print_roll(roll)

            while 0 < round <= 6:

                what_next = input("Enter dice to keep (no spaces), or (q)uit: ")
                if what_next == 'q' or what_next == 'quit':

                    break
                else:
                    generate_new_tupe = Game.convert_to_tup(what_next)
                    score += GameLogic.calculte_score(generate_new_tupe)
                    num_dice = 6-len(generate_new_tupe)
                    print(f"You have {score} unbanked points and {num_dice} dice remaining")
                    inpt = input("(r)oll again, (b)ank your points or (q)uit ")

                    if inpt == 'q' or inpt =='quit':
                        break

                    if inpt == 'r' or inpt =='roll':
                        # new_roll = GameLogic.role_dice(num_dice)
                        new_roll = self.roller(num_dice)
                        print(f"Rolling {num_dice} dice...")
                        rol3 = Game.print_roll(new_roll)
                        num_dice = 6-len(generate_new_tupe)
                        print(rol3)

                    if inpt == 'b' or inpt == 'bank':
                        x.shelf(score)
                        x.bank()
                        print(f"You banked {score} points in round {round}")
                        print(f"Total score is {x.total} points")
                        round +=1
                        print(f"Starting round {round}")
                        print("Rolling 6 dice...")
                        # new_numbers = GameLogic.role_dice(6)
                        new_numbers = self.roller(6)
                        rol3 = Game.print_roll(new_numbers)
                        print(rol3)
                        score = 0

            print(f"Total score is {x.total} points")
            print(f"Thanks for playing. You earned {x.total} points")

if __name__=='__main__':
    game = Game()
    game.play()


import requests

import bs4
import sys

URL = 'https://dhlottery.co.kr/gameResult.do?method=byWin'
raw = requests.get(URL)
html = bs4.BeautifulSoup(raw.text, 'html.parser')

# sys.stdout = open('lotto23.txt','w',encoding="utf-8")
# print(html)
# sys.stdout.close()

target = html.find('div', {'class', 'nums'})
            # beautifulsoup로 갈무리한 html에서,  div태그 안에 class이면서 num이름
            #을 지닌 부분을 변수명 target에 넣어줘라
            #<div class="nums"> xxxxxxxxxxxxxxxxx </div>
# print("target",target)
# print(target)

balls = target.find_all("span", {'class', 'ball_645'})
for ball in balls:
    print(ball.text)

# for ball in balls:
#     print("당첨번호 : ", ball.text)
# print("보너스 번호 :", balls[-1].text)


class Node:
  def __init__(self,data):
    self.data = data
    self.next = None
class ll:
  def __init__(self):
    self.head = None
  def reverse_linklist(self):
    lali = self.head
    temp = self.head
    tempo = self.head
    prev = None
    while temp.next:
      #print("yaha aa gya")
      prev = tempo
      tempo = tempo.next
      temp = temp.next
    newnode = temp
    prev.next = None
    newnode.next = lali
    while newnode :
      print(newnode.data)
      newnode = newnode.next
  def display(self):
    temp = self.head
    while temp:
      print(temp.data,"-->",end=" ")
      temp = temp.next
l = ll()
n = Node(1)
l.head = n
n2 = Node(2)
n.next = n2
n3 = Node(3)
n2.next = n3
n4 = Node(4)
n3.next = n4
n5 = Node(5)
n4.next  = n5
#l.display()

l.reverse_linklist()


# Your code goes here.
# You can delete these comments, but do not change the name of this file
# Write your code to expect a terminal of 80 characters wide and 24 rows high
import gspread
from google.oauth2.service_account import Credentials

SCOPE = [
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/drive.file",
    "https://www.googleapis.com/auth/drive"
    ]

CREDS = Credentials.from_service_account_file('creds.json')
SCOPED_CREDS = CREDS.with_scopes(SCOPE)
GSPREAD_CLIENT = gspread.authorize(SCOPED_CREDS)
SHEET = GSPREAD_CLIENT.open('love_sandwiches')

def get_sales_data():
    """
    Get the sales figures from the input
    """
    while True:
        print("Please enter some data")
        print("Should be 6 numbers")
        print("e.g 10,20,30,40,50,60\n")

        data_str = input("Enter your data here:\n")

        sales_data = data_str.split(",")

        if validate_data(sales_data):
            print("Data is valid!")
            break

    return sales_data

def validate_data(values):
    """
    Tries to convert all the strings vlaues into ints.
    Raise an error if they cant be converted or if
    there are not exatly 6 values entered.
    """
    try:
        [int(v) for v in values]
        if len(values) != 6:
            raise ValueError(f"Exactly 6 values required, you entered {len(values)}")
    except ValueError as e:
        print(f"Invalid data: {e}, please try again\n")
        return False

    return True

def update_worksheet(data, worksheet):
    """ New function """
    print(f"Updating {worksheet}...\n")

    worksheet_to_update = SHEET.worksheet(worksheet)
    worksheet_to_update.append_row(data)
    print(f"{worksheet} has been updated")

def calculate_surplus_data(sales_row):
    """
    Works out stock shortages / extra food made for customers
    """
    print("Calculating suplus / excess\n")
    stock = SHEET.worksheet("stock").get_all_values()
    stock_row = stock[-1]

    new_surplus_data = []
    for stock, sales in zip(stock_row, sales_row):
        surplus = int(stock) - sales
        new_surplus_data.append(surplus)

    return new_surplus_data

def get_last_5_entries_sales():
    """works out the average"""
    sales = SHEET.worksheet("sales")

    columns = []
    for c in range(1, 7):
        col_val = sales.col_values(c)
        columns.append(col_val[-5:])

    return columns

def calculate_stock_data(data):
    """ works out avg stock changes """
    print("Calcualting stock stats")
    new_stock_data = []

    for col in data:
        int_column = [int(num) for num in col]
        average = sum(int_column) / len(int_column)
        stock_num = average * 1.1
        new_stock_data.append(round(stock_num))

    return new_stock_data

def main():
    """
    Run all program functions
    """
    data = get_sales_data()
    sales_data = [int(num) for num in data]
    update_worksheet(sales_data, "sales")
    new_surplus_data = calculate_surplus_data(sales_data)
    update_worksheet(new_surplus_data, "surplus")
    sales_columns = get_last_5_entries_sales()
    stock_data = calculate_stock_data(sales_columns)
    print(stock_data)
    update_worksheet(stock_data, "stock")

print("Welcome to Love sandiwches automation tool")
main()


from json import load
import os
import argparse
import random
from copy import deepcopy
import torchvision
import torchvision.transforms as transforms
from torch import nn
from torch.nn import functional as F
import sys
import torch
import numpy as np

# sys.path.append("../../")
torch.manual_seed(0)

from fedlab.core.client.scale.trainer import SubsetSerialTrainer, SubsetSerialTrainerWithDifferentialUpdate
from fedlab.utils.aggregator import Aggregators
from fedlab.utils.serialization import SerializationTool
from fedlab.utils.dataset.partition import CIFAR10Partitioner
from fedlab.utils.functional import evaluate
from fedlab.utils.functional import get_best_gpu, load_dict

# configuration
parser = argparse.ArgumentParser(description="Standalone training example")
parser.add_argument("--total_client", type=int, default=100)
parser.add_argument("--com_round", type=int, default=10)

parser.add_argument("--sample_ratio", type=float)
parser.add_argument("--batch_size", type=int)
parser.add_argument("--epochs", type=int)
parser.add_argument("--lr", type=float, default=0.1)
parser.add_argument("--cuda", type=bool, default=False)

args = parser.parse_args()

# torch model
class CNN(nn.Module):

    def __init__(self, input_size=32, input_channel=3, output_size=10):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(in_channels=input_channel, out_channels=32, kernel_size=5)
        self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5)
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
        in_features = 64 * ((((input_size - 4) // 2) - 4) // 2) ** 2
        self.fc1 = nn.Linear(in_features, 512)
        self.fc2 = nn.Linear(512, output_size)

    def forward(self, x):
        x = F.relu(self.pool(self.conv1(x)))
        x = F.relu(self.pool(self.conv2(x)))
        x = x.view(x.size(0), -1)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

# get mnist dataset
root = "../dataSet/cifar10/"
trainset = torchvision.datasets.CIFAR10(root=root,
                                      train=True,
                                      download=True,
                                      transform=transforms.Compose([
                                                transforms.RandomHorizontalFlip(0.5),
                                                transforms.RandomCrop(32, 4),
                                                transforms.ToTensor(),
                                                transforms.Normalize(mean=[0.491, 0.482, 0.447], std=[0.247, 0.243, 0.262])]))

testset = torchvision.datasets.CIFAR10(root=root,
                                     train=False,
                                     download=True,
                                     transform=transforms.Compose([transforms.ToTensor(),
                                                                   transforms.Normalize(mean=[0.491, 0.482, 0.447], std=[0.247, 0.243, 0.262])]))

test_loader = torch.utils.data.DataLoader(testset,
                                          batch_size=50,
                                          drop_last=False,
                                          shuffle=False)

# setup
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1,2,3"

if args.cuda:
    gpu = get_best_gpu()
    print("using {}".format(gpu))
    model = CNN().cuda(gpu)
else:
    model = CNN()

# FL settings
num_per_round = int(args.total_client * args.sample_ratio)
aggregator = Aggregators.pca_aggregate
total_client_num = args.total_client  # client总数

data_indices = CIFAR10Partitioner(trainset.targets, args.total_client, True, "iid").client_dict

# fedlab setup
local_model = deepcopy(model)

trainer = SubsetSerialTrainerWithDifferentialUpdate(model=local_model,
                              dataset=trainset,
                              data_slices=data_indices,
                              aggregator=aggregator,
                              args={
                                  "batch_size": args.batch_size,
                                  "epochs": args.epochs,
                                  "max_norm":10,
                                  "optim":{"type":"SGD", "lr": args.lr, "weight_decay":1e-3}
                              })

# train procedure
to_select = [i for i in range(total_client_num)]
for round in range(args.com_round):
    model_parameters = SerializationTool.serialize_model(model)
    selection = random.sample(to_select, num_per_round)
    aggregated_parameters = trainer.train(model_parameters=model_parameters,
                                          id_list=selection,
                                          aggregate=True, n_components=5)

    SerializationTool.deserialize_model(model, aggregated_parameters + model_parameters)

    criterion = nn.CrossEntropyLoss()
    loss, acc = evaluate(model, criterion, test_loader)
    print("round {}, loss: {:.4f}, acc: {:.2f}".format(round + 1, loss, acc))


import tensorflow as tf
import numpy as np
import cv2
import os
from tqdm import tqdm
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from random import shuffle

in_data = '/Users/ibneetkaur/Desktop/coding/image_recognizer/train'

def refining_img():
    labeled_images = []
    for i in tqdm(os.listdir(in_data)):
        path = os.path.join(in_data,i)
        img = cv2.imread(path)
        if img is not None:
            img = cv2.resize((cv2.cvtColor(img,cv2.COLOR_BGR2RGB)),(100, 100))
       #    img = cv2.resize(img,(100,100))
            labeled_images.append([np.array(img), img_label(i)])
        else:
            print('Image not loaded')
        shuffle(labeled_images)
    return labeled_images

def img_label(img):
    img_lbl = []
    label = img.split('.')[0]
    if label == 'Ibneet':
        img_lbl = np.array([1,0])
    elif label == 'Gurjot':
        img_lbl = np.array([0,1])
    return img_lbl

from keras.models import Sequential
from keras.layers import *
from keras.optimizers import *
from keras.models import Model
from keras.utils import print_summary

images_with_label = np.asarray(refining_img())

images = np.array([i[0] for i in images_with_label]).reshape(-1,100,100,3)
label = np.array([i[1] for i in images_with_label])

train_img, test_img, train_lbl, test_lbl = train_test_split(images, label, test_size=0.2,
                                                    random_state=42)

input_img = Input(shape=(100, 100, 3))

x1 = Conv2D(64, (3, 3), activation='relu', padding='same')(input_img)
x2 = MaxPooling2D((2, 2), padding='same')(x1)
x3 = Conv2D(32, (3, 3), activation='relu', padding='same')(x2)
x4 = MaxPooling2D((2, 2), padding='same')(x3)
x5 = Conv2D(32, (3, 3), activation='relu', padding='same')(x4)
encoded = MaxPooling2D((2, 2), padding='same')(x5)

y1 = Flatten()(x5)
y2 = Dense(1024, activation='relu')(y1)
y3 = Dropout(0.2)(y2)
y4 = Dense(2, activation='softmax')(y3)

#x6 = Conv2D(32, (3, 3), activation='relu', padding='same')(encoded)
#x7 = UpSampling2D((2, 2))(x6)
#x8 = Conv2D(32, (3, 3), activation='relu', padding='same')(x7)
#x10 = Conv2D(64, (3, 3), activation='relu')(x9)
#x11 = UpSampling2D((2, 2))(x10)
#decoded = Conv2D(3, (3, 3), activation='sigmoid', padding='same')(x11)

autoencoder = Model(input_img, y4)

encoder = Model(input_img, encoded)

autoencoder.compile(optimizer='adam', loss='categorical_crossentropy',metrics=['accuracy'])

print_summary(autoencoder)

train_img = train_img.astype('float32')
train_img /= 255

test_img = test_img.astype('float32')
test_img /= 255

autoencoder.fit(train_img, train_lbl,
                epochs=50,
                batch_size=20,
                shuffle=True)

predicted_imgs = autoencoder.predict(test_img)

plt.figure(figsize=(40, 40))
for i in range(10):
    # display original images
    ax = plt.subplot(3, 20, i + 1)
    plt.imshow(train_img[i])
    plt.title(train_lbl[i])
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

plt.figure(figsize=(40, 40))
for i in range(20):
    # display original images
    ax = plt.subplot(3, 20, i + 1)
    plt.imshow(test_img[i])
    if np.argmax(predicted_imgs[i]) == 1:
        lbl = 'Gurjot'
    else:
        lbl = 'Ibneet'
    plt.title(lbl)
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

#############################################################################################
from playsound import playsound

def detect():
    faceCascade = cv2.CascadeClassifier('/Users/ibneetkaur/Downloads/haarcascade_frontalface_default.xml')
    cap = cv2.VideoCapture(0)
    cap.set(3,640)
    cap.set(4,480)

    font = cv2.FONT_HERSHEY_SIMPLEX

    while True:
        ret, img = cap.read()
        img = cv2.flip(img, 1)
        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        faces = faceCascade.detectMultiScale(
                img_rgb,
                scaleFactor=1.2,
                minNeighbors=5,
                minSize=(100, 100)
                )
        if len(faces) > 0:
            for (x,y,w,h) in faces:
                cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)

                image = cv2.resize(img[y:y+h,x:x+w],(100,100))
#                image = img_rgb[y:y+h,x:x+w]
                image = np.reshape(image,(-1,100,100,3))
                image = image.astype('float32')
                image /= 255

                predicted_imgs = autoencoder.predict(image)

                if predicted_imgs[:,1] > 0.7:
                    lbl = 'Gurjot'
                    wel = playsound("welcome1.mp3")
                elif predicted_imgs[:,0] > 0.7 :
                    lbl = 'Ibneet'
                    wel = playsound("welcome2.mp3")
                else:
                    lbl = 'Unkown'

                id = lbl
                print(predicted_imgs)

                cv2.putText(
                    img,
                    str(id),
                    (x+5,y-5),
                    font,
                    1,
                    (255,255,255),
                    2
                   )
                wel
                cv2.imshow('Input',img)
                k = cv2.waitKey(10) & 0xff
                if k == 27: # press 'ESC' to quit
                    break
    cap.release()
    cv2.destroyAllWindows()
    cv2.waitKey(1)

enter = input('Press a to start webcam predictions.')

if enter == 'a':
    detect()

from gtts import gTTS

message1 = gTTS(text='Hi Gurjot! How are you.', lang='en', slow=False)
message2 = gTTS(text='Hi Ibneet! How are you.', lang='en', slow=False)

message1.save("welcome1.mp3")
message2.save("welcome2.mp3")


import pytest

# jax imports
import jax
import jax.numpy as jnp

# crs imports
import cr.nimble as cnb
from cr.nimble.dsp import *

atol = 1e-6
rtol = 1e-6

def test_dct1():
    for n in [4,8,16]:
        for i in range(n):
            print(n, i)
            y = cnb.vec_unit(n, i)
            a = dct(y)
            x = idct(a)
            assert jnp.allclose(x, y, rtol=rtol, atol=atol)

def test_orthonormal_dct1():
    for n in [4,8,16]:
        for i in range(n):
            print(n, i)
            y = cnb.vec_unit(n, i)
            a = orthonormal_dct(y)
            x = orthonormal_idct(a)
            assert jnp.allclose(x, y, rtol=rtol, atol=atol)


class Solution(object):
    def wordBreak(self, s, wordDict):
        """
        :type s: str
        :type wordDict: List[str]
        :rtype: bool
        """
        """dp的状态转移方程
        dp[i] is true if dp[j] is true and s[j+1:i+1] in wordDict"""
        if len(s) == 0 or wordDict is None:
            return False
        dp = [False] * len(s)
        for i in range(len(s)):
            if s[:i + 1] in wordDict:
                dp[i] = True
                continue
            for j in range(i):
                if dp[j] and s[j + 1:i + 1] in wordDict:
                    dp[i] = True
                    break

        return dp[-1]

    def wordBreak_better(self, s, wordDict):
        if len(s) == 0 or wordDict is None:
            return False
        dp = [False] * len(s)
        for i in range(len(s)):
            for w in wordDict:
                if w == s[i - len(w) + 1: i + 1] and (dp[i - len(w)] or i - len(w) == -1):
                    dp[i] = True

        return dp[-1]

solution = Solution()
print(solution.wordBreak_better(s = "leetcode", wordDict = ["leet", "code"]))


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

"""
This file contains configuration for the locations of all the static file
libraries, such as JavaScript and CSS libraries. Packagers for individual
distributions can edit or replace this file, in order to change the paths
to match their distribution's standards.
"""

import os

import xstatic.main
import xstatic.pkg.angular
import xstatic.pkg.angular_bootstrap
import xstatic.pkg.angular_fileupload
import xstatic.pkg.angular_gettext
import xstatic.pkg.angular_lrdragndrop
import xstatic.pkg.angular_smart_table
import xstatic.pkg.bootstrap_datepicker
import xstatic.pkg.bootstrap_scss
import xstatic.pkg.bootswatch
import xstatic.pkg.d3
import xstatic.pkg.font_awesome
import xstatic.pkg.hogan
import xstatic.pkg.jasmine
import xstatic.pkg.jquery
import xstatic.pkg.jquery_migrate
import xstatic.pkg.jquery_quicksearch
import xstatic.pkg.jquery_tablesorter
import xstatic.pkg.jquery_ui
import xstatic.pkg.jsencrypt
import xstatic.pkg.mdi
import xstatic.pkg.rickshaw
import xstatic.pkg.roboto_fontface
import xstatic.pkg.spin
import xstatic.pkg.termjs

from horizon.utils import file_discovery

from openstack_dashboard import theme_settings

def get_staticfiles_dirs(webroot='/'):
    STATICFILES_DIRS = [
        ('horizon/lib/angular',
            xstatic.main.XStatic(xstatic.pkg.angular,
                                 root_url=webroot).base_dir),
        ('horizon/lib/angular',
            xstatic.main.XStatic(xstatic.pkg.angular_bootstrap,
                                 root_url=webroot).base_dir),
        ('horizon/lib/angular',
            xstatic.main.XStatic(xstatic.pkg.angular_fileupload,
                                 root_url=webroot).base_dir),
        ('horizon/lib/angular',
            xstatic.main.XStatic(xstatic.pkg.angular_gettext,
                                 root_url=webroot).base_dir),
        ('horizon/lib/angular',
            xstatic.main.XStatic(xstatic.pkg.angular_lrdragndrop,
                                 root_url=webroot).base_dir),
        ('horizon/lib/angular',
            xstatic.main.XStatic(xstatic.pkg.angular_smart_table,
                                 root_url=webroot).base_dir),
        ('horizon/lib/bootstrap_datepicker',
            xstatic.main.XStatic(xstatic.pkg.bootstrap_datepicker,
                                 root_url=webroot).base_dir),
        ('bootstrap',
            xstatic.main.XStatic(xstatic.pkg.bootstrap_scss,
                                 root_url=webroot).base_dir),
        ('horizon/lib/bootswatch',
         xstatic.main.XStatic(xstatic.pkg.bootswatch,
                              root_url=webroot).base_dir),
        ('horizon/lib',
            xstatic.main.XStatic(xstatic.pkg.d3,
                                 root_url=webroot).base_dir),
        ('horizon/lib',
            xstatic.main.XStatic(xstatic.pkg.hogan,
                                 root_url=webroot).base_dir),
        ('horizon/lib/font-awesome',
            xstatic.main.XStatic(xstatic.pkg.font_awesome,
                                 root_url=webroot).base_dir),
        ('horizon/lib/jasmine',
            xstatic.main.XStatic(xstatic.pkg.jasmine,
                                 root_url=webroot).base_dir),
        ('horizon/lib/jquery',
            xstatic.main.XStatic(xstatic.pkg.jquery,
                                 root_url=webroot).base_dir),
        ('horizon/lib/jquery',
            xstatic.main.XStatic(xstatic.pkg.jquery_migrate,
                                 root_url=webroot).base_dir),
        ('horizon/lib/jquery',
            xstatic.main.XStatic(xstatic.pkg.jquery_quicksearch,
                                 root_url=webroot).base_dir),
        ('horizon/lib/jquery',
            xstatic.main.XStatic(xstatic.pkg.jquery_tablesorter,
                                 root_url=webroot).base_dir),
        ('horizon/lib/jsencrypt',
            xstatic.main.XStatic(xstatic.pkg.jsencrypt,
                                 root_url=webroot).base_dir),
        ('horizon/lib/mdi',
         xstatic.main.XStatic(xstatic.pkg.mdi,
                              root_url=webroot).base_dir),
        ('horizon/lib',
            xstatic.main.XStatic(xstatic.pkg.rickshaw,
                                 root_url=webroot).base_dir),
        ('horizon/lib/roboto_fontface',
         xstatic.main.XStatic(xstatic.pkg.roboto_fontface,
                              root_url=webroot).base_dir),
        ('horizon/lib',
            xstatic.main.XStatic(xstatic.pkg.spin,
                                 root_url=webroot).base_dir),
        ('horizon/lib',
         xstatic.main.XStatic(xstatic.pkg.termjs,
                              root_url=webroot).base_dir),
    ]

    if xstatic.main.XStatic(xstatic.pkg.jquery_ui,
                            root_url=webroot).version.startswith('1.10.'):
        # The 1.10.x versions already contain the 'ui' directory.
        STATICFILES_DIRS.append(
            ('horizon/lib/jquery-ui',
             xstatic.main.XStatic(xstatic.pkg.jquery_ui,
                                  root_url=webroot).base_dir))
    else:
        # Newer versions dropped the directory, add it to keep the path the
        # same.
        STATICFILES_DIRS.append(
            ('horizon/lib/jquery-ui/ui',
             xstatic.main.XStatic(xstatic.pkg.jquery_ui,
                                  root_url=webroot).base_dir))

    return STATICFILES_DIRS

def find_static_files(
        HORIZON_CONFIG,
        AVAILABLE_THEMES,
        THEME_COLLECTION_DIR,
        ROOT_PATH):
    import horizon
    import openstack_dashboard
    os_dashboard_home_dir = openstack_dashboard.__path__[0]
    horizon_home_dir = horizon.__path__[0]

    # note the path must end in a '/' or the resultant file paths will have a
    # leading "/"
    file_discovery.populate_horizon_config(
        HORIZON_CONFIG,
        os.path.join(horizon_home_dir, 'static/')
    )

    # filter out non-angular javascript code and lib
    HORIZON_CONFIG['js_files'] = ([f for f in HORIZON_CONFIG['js_files']
                                   if not f.startswith('horizon/')])

    # note the path must end in a '/' or the resultant file paths will have a
    # leading "/"
    file_discovery.populate_horizon_config(
        HORIZON_CONFIG,
        os.path.join(os_dashboard_home_dir, 'static/'),
        sub_path='app/'
    )

    # Discover theme static resources, and in particular any
    # static HTML (client-side) that the theme overrides
    theme_static_files = {}
    theme_info = theme_settings.get_theme_static_dirs(
        AVAILABLE_THEMES,
        THEME_COLLECTION_DIR,
        ROOT_PATH)

    for url, path in theme_info:
        discovered_files = {}

        # discover static files provided by the theme
        file_discovery.populate_horizon_config(
            discovered_files,
            path
        )

        # Get the theme name from the theme url
        theme_name = url.split('/')[-1]

        # build a dictionary of this theme's static HTML templates.
        # For each overridden template, strip off the '/templates/' part of the
        # theme filename then use that name as the key, and the location in the
        # theme directory as the value. This allows the quick lookup of
        # theme path for any file overridden by a theme template
        template_overrides = {}
        for theme_file in discovered_files['external_templates']:
            # Example:
            #   external_templates_dict[
            #       'framework/widgets/help-panel/help-panel.html'
            #   ] = 'themes/material/templates/framework/widgets/\
            #        help-panel/help-panel.html'
            (templates_part, override_path) = theme_file.split('/templates/')
            template_overrides[override_path] = 'themes/' +\
                                                theme_name + theme_file

        discovered_files['template_overrides'] = template_overrides

        # Save all of the discovered file info for this theme in our
        # 'theme_files' object using the theme name as the key
        theme_static_files[theme_name] = discovered_files

    # Add the theme file info to the horizon config for use by template tags
    HORIZON_CONFIG['theme_static_files'] = theme_static_files


from logging import getLogger

import httpx

from ddns_clienter_core.runtimes.config import TaskConfig

from .abs import DDNSProviderAbs, DDNSProviderException

logger = getLogger(__name__)

_update_api_url = "https://dynv6.com/api/update"
_rest_api_url = "https://dynv6.com/api/v2"

async def _call_update_api(
    domain: str,
    token: str,
    ipv4_address: str | None,
    ipv6_address: str | None,
    real_update: bool,
) -> (bool, str):
    # https://dynv6.com/docs/apis
    params = {
        "zone": domain,
        "token": token,
    }
    if ipv4_address:
        params.update({"ipv4": ipv4_address})
    if ipv6_address:
        params.update({"ipv6": ipv6_address})

    logger.debug(params)
    if not real_update:
        return True, ""

    try:
        async with httpx.AsyncClient() as client:
            r = await client.get(_update_api_url, params=params)
        logger.debug(f"{r.status_code} {r.content}")
    except (httpx.HTTPError, httpx.StreamError) as e:
        return False, str(e)

    if r.status_code == 200:
        return True, r.text
    else:
        return False, r.text

class CallRestApi:
    zone_id: int | None = None

    def __init__(
        self,
        config_task: TaskConfig,
        ipv4_address: str,
        ipv6_address: str,
        real_update: bool,
    ):
        self._c_task = config_task
        self.config_host, self.config_domain = config_task.domain.split(".", maxsplit=1)
        self.ipv4_address = ipv4_address
        self.ipv6_address = ipv6_address
        self.real_update = real_update

        self.headers = httpx.Headers()
        self.headers["Accept"] = "application/json"
        self.headers["Authorization"] = f"Bearer {self._c_task.provider_auth}"

    async def _call_rest_api_get(self, url) -> httpx.Response:
        async with httpx.AsyncClient() as client:
            r = await client.get(url, headers=self.headers)
        logger.debug(f"{r.status_code} {r.content}")

        if r.status_code != 200:
            raise DDNSProviderException(r)

        return r

    async def _call_rest_api_add_record(
        self, host: str, record_type: str, ip_address: str
    ) -> httpx.Response:
        j = {"name": host, "type": record_type, "data": ip_address}
        async with httpx.AsyncClient() as client:
            r = await client.post(
                f"{_rest_api_url}/zones/{self.zone_id}/records",
                headers=self.headers,
                json=j,
            )
        logger.debug(f"{r.status_code} {r.content}")

        if r.status_code != 200:
            raise DDNSProviderException(r)

        return r

    async def _call_rest_api_update_record(
        self, record_id: str, record_type: str, ip_address: str
    ) -> httpx.Response:
        j = {"type": record_type, "data": ip_address}
        async with httpx.AsyncClient() as client:
            r = await client.patch(
                f"{_rest_api_url}/zones/{self.zone_id}/records/{record_id}",
                headers=self.headers,
                json=j,
            )

        logger.debug(f"{r.status_code} {r.content}")

        if r.status_code != 200:
            raise DDNSProviderException(r)

        return r

    async def process(self) -> (bool, str):
        # https://dynv6.github.io/api-spec

        # get zone id
        r = await self._call_rest_api_get(f"{_rest_api_url}/zones")

        for item in r.json():
            if item.get("name") == self.config_domain:
                self.zone_id = item.get("id")
                continue

        if self.zone_id is None:
            raise DDNSProviderException(f"Can not match zone id:{r}")

        # get record id
        r = await self._call_rest_api_get(
            f"{_rest_api_url}/zones/{self.zone_id}/records"
        )

        ipv4_record_id = None
        ipv6_record_id = None
        for item in r.json():
            if item.get("name") != self.config_host:
                continue

            record_type = item.get("type")
            if record_type == "A":
                ipv4_record_id = item.get("id")
            elif record_type == "AAAA":
                ipv6_record_id = item.get("id")

        if self.ipv4_address:
            if ipv4_record_id is None:
                # add a new record
                await self._call_rest_api_add_record(
                    host=self.config_host,
                    record_type="A",
                    ip_address=self.ipv4_address,
                )
            else:
                # update a record
                await self._call_rest_api_update_record(
                    record_id=ipv4_record_id,
                    record_type="A",
                    ip_address=self.ipv4_address,
                )

        if self.ipv6_address:
            if ipv6_record_id is None:
                # add a new record
                await self._call_rest_api_add_record(
                    host=self.config_host,
                    record_type="AAAA",
                    ip_address=self.ipv6_address,
                )
            else:
                # update a record
                await self._call_rest_api_update_record(
                    record_id=ipv6_record_id,
                    record_type="AAAA",
                    ip_address=self.ipv6_address,
                )

        if 200 <= r.status_code <= 299:
            update_success = True
        else:
            update_success = False
        return update_success, f"{r.status_code} {r.text}"

class DDNSProviderDynv6(DDNSProviderAbs):
    name = "dynv6"

    async def _update_to_provider(self) -> None:
        logger.debug("update in Dynv6 UPDATE API")
        self.update_success, self.update_message = await _call_update_api(
            domain=self.task_config.domain,
            token=self.task_config.provider_auth,
            ipv4_address=self.address_info.ipv4_address_str,
            ipv6_address=self.address_info.ipv6_address_str_with_prefix,
            real_update=self.real_update,
        )

class DDNSProviderDynv6REST(DDNSProviderAbs):
    name = "dynv6.rest"

    async def _update_to_provider(self) -> None:
        logger.debug("update in Dynv6 REST API")
        call_rest_api = CallRestApi(
            config_task=self.task_config,
            ipv4_address=self.address_info.ipv4_address_str,
            ipv6_address=self.address_info.ipv6_address_str,  # REST API 似乎不支持 /xx 这种方式定义 prefix
            real_update=self.real_update,
        )

        self.update_success, self.update_message = call_rest_api.process()


"""
8. Pipeline

As part of a data processing pipeline, complete the implementation of the pipeline method:

* The method should accept a variable number of functions,
 and it should return a new function that accepts one
 parameter arg.

* The returned function should call the first function in the
 pipeline with the parameter arg, and call the second
 function with the result of the first function.

* The returned function should continue calling each function
 in the pipeline in order, following the same pattern, and
 return the value from the last function.

For example, Pipeline.pipeline(lambda x: x * 3, lambda x: x + 1,
lambda x: x / 2) then calling the returned function with 3 should
return 5.0.

Time : 66 min
Tests: 2 pass / 1 fail
  Example case: Correct answer
  Various functions: File "pipeline.py", line 11, in helper: TypeError
  Various data types: Correct answer

* Subject - Closure, Decorator(core concept)

* Learning
    1. passing func to *args (tuple)

    2. solving the UnBoundError

"""

# class Pipeline:
#     @staticmethod
#     def pipeline(*funcs):
#         funcs_list = list(funcs)
#
#         def helper(arg):
#             # Step 1
#             # print('hi')
#             # return funcs[0](arg)
#
#             # Step 2
#             result = funcs_list[0](arg)
#             if len(funcs_list) > 1:
#                 funcs_list[0:1] = []
#                 return helper(result)
#             else:
#                 return result
#         return helper

class Pipeline:
    @staticmethod
    def pipeline(*funcs):
        i = 0

        def helper(arg):
            nonlocal i
            result = funcs[i](arg)
            i += 1
            if i < len(funcs):
                return helper(result)
            else:
                return result
        return helper

fun = Pipeline.pipeline(lambda x: x * 3, lambda x: x + 1, lambda x: x / 2)
# fun = Pipeline.pipeline(lambda x: x * 3)
print(fun(3))  # should print 5.0

"""
181111 Review

Time : 29 min
Tests: 3 pass / 0 fail
  Example case: Correct answer
  Various functions: Correct answer
  Various data types: Correct answer
"""

# class Pipeline:
#     @staticmethod
#     def pipeline(*funcs):
#         def helper(arg, *func_list):
#             if not func_list:
#                 arg = funcs[0](arg)
#                 func_list = funcs
#             else:
#                 func_list = func_list[0]
#                 arg = func_list[0](arg)
#
#             if len(func_list) == 1:
#                 return arg
#             return helper(arg, func_list[1:])
#         return helper
#
#
# fun = Pipeline.pipeline(lambda x: x * 3, lambda x: x + 1, lambda x: x / 2)
# print(fun(3))  # should print 5.0
#

"""
181129 Review

Time : 60 min
Tests: 3 pass / 0 fail
  Example case: Correct answer
  Various functions: Correct answer
  Various data types: Correct answer
"""

# 1) Various functions: "pipeline.py", line 11, in helper: IndexError

class Pipeline:
    @staticmethod
    def pipeline(*funcs):
        def helper(arg, *funcs2):

            if not funcs2:
                ret = funcs[0](arg)

                # This made an exception(error) above
                return helper(ret, funcs[1:])

                # hot_fix
                # funcs2 = funcs

            else:
                funcs2 = funcs2[0]
                ret = funcs2[0](arg)

            if len(funcs2) == 1:
                return ret

            return helper(ret, funcs2[1:])

        return helper

# 2) UnboundLocalError: local variable 'funcs' referenced before assignment
# class Pipeline:
#     @staticmethod
#     def pipeline(*funcs):
#
#         def helper(arg, *args):
#
#             ret = funcs[0](arg)
#             funcs = funcs[1:]
#
#             return helper(ret)
#         return helper

# 3) Tests: 3 pass / 0 fail
class Pipeline:
    @staticmethod
    def pipeline(*funcs):
        def helper(arg, *args):

            if not args:
                funcs2 = funcs
            else:
                funcs2 = args[0]

            ret = funcs2[0](arg)

            if len(funcs2) == 1:
                return ret

            return helper(ret, funcs2[1:])
        return helper

fun = Pipeline.pipeline(lambda x: x / 2)
print(fun(3))  # should print 5.0


import math
import operator

def c14_floordiv(a, b):
    if a < 0:
        return -(-a//b)
    else:
        return a//b

ops = [operator.add, operator.sub, operator.mul, c14_floordiv]

def calc(A, op_count):
    if len(A) == 1:
        return [A[0], A[0]]

    # (최대, 최소)
    ret = [-math.inf, math.inf]

    for i in range(4):
        if op_count[i] > 0:
            oprand1 = A.pop()
            oprand2 = A.pop()
            A.append(ops[i](oprand1, oprand2))

            op_count[i] = op_count[i] - 1
            term_max, term_min = calc(A, op_count)
            op_count[i] = op_count[i] + 1

            if ret[0] < term_max:
                ret[0] = term_max
            if ret[1] > term_min:
                ret[1] = term_min

            A.pop()
            A.append(oprand2)
            A.append(oprand1)

    return ret

N = int(input())
A = list(map(int, input().split()))
A.reverse()
op_count = list(map(int, input().split()))

ret = "\n".join(map(str, calc(A, op_count)))
print(ret)


import re
import csv
import requests
from bs4 import BeautifulSoup
from random import choice

COUNTER = 0

def get_proxy():
    html = requests.get('https://free-proxy-list.net/').text
    soup = BeautifulSoup(html, 'lxml')
    trs = soup.find('table', id='proxylisttable').find_all('tr')[50:100]
    proxies = []
    for tr in trs:
        tds = tr.find_all('td')
        ip = tds[0].text.strip()
        port = tds[1].text.strip()
        schema = 'https' if 'yes' in tds[6].text.strip() else 'http'
        proxy = {'schema': schema, 'address': ip + ':' + port}
        proxies.append(proxy)
    return choice(proxies)

def get_html(url):
    p = get_proxy()
    proxy = { p['schema']: p['address']  }
    r = requests.get(url)#, proxies=proxy)
    return r.text if r.ok else print(r.status_code)

def get_categories(url):
  soup = BeautifulSoup(get_html(url), 'lxml')

  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  categories = soup.find('ul', id='menu-list').find_all('a')
  for category in categories[:-1]:
    cat_name = category.text
    cat_link = category.get('href') + '?limit=10000'
    get_products(cat_link)
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

def get_products(url, *args, **kwargs):
  soup = BeautifulSoup(get_html(url), 'lxml')

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  products = soup.find_all('div' ,class_="product-layout")
  for i in products:
    product_link = i.find('div', class_="product-name-modules").a.get('href')
    get_product(product_link)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

def get_product(url, *args, **kwargs):
  soup = BeautifulSoup(get_html(url), 'lxml')

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  panel = soup.find('div', class_='panel panel-default panel-body')
  divs = panel.find_all('div')
  quicks = {}
  for div in divs:
    if div.get('class') and div.get('class')[0].split('-')[0] == 'quick':
      text = div.text.split(':')
      quicks.update({text[0].strip():text[1].strip()})
  articule = quicks.get('Артикул', '')
  name = panel.h1.text
  price_raw = panel.find('ul', class_='list-unstyled')
  try: price_new = price_raw.find('span', class_="price-new").text
  except: price_new = ''
  try: price_old = price_raw.find('span', class_="price-old").text
  except: price_old = ''
  try: action = price_raw.find('span', class_='you-save').text.split(' ')[-1].strip('()')
  except: action = ''
  try: price = price_raw.find('span', class_='price').text
  except: price = ''
  price = price_new or price
  img = []
  main_img = soup.find('a', class_='thumbnail img-responsive card-product').img.get('src')
  img.append(main_img)
  additional_imgs = soup.find_all('a', class_='img-thumbnail thumbnail')
  for i in additional_imgs:
    img.append(i.get('href'))
  manufacturer = quicks.get('Производитель', '')
  country = quicks.get('Страна', '')
  avaliable = quicks.get('Наличие', '')
  category = soup.find('ul', class_='breadcrumb').find_all('li')[1].a.text
  desc = soup.find('div', id='tab-description').text.strip()
  sizes_name = 'Размеры'
  sizes_measurment = 'см'
  sizes = []
  for radio in soup.find_all('div', class_='radio'):
    sizes.append(''.join(radio.text.replace(' ', '').split()))
  # sizes = set(sizes)
  # print(sizes)
  if sizes == []:
    sizes = quicks.get('Размеры', '')
  print(sizes)
  weight = quicks.get('Вес', '')
  extends = quicks.get('Расширение', '')
  material = quicks.get('Материал', '')
  table = soup.find('table', class_='table table-bordered')
  gender = ''
  colour = ''
  wheels = ''
  beauty = 'Нет'
  hand = 'Нет'
  try:
    text = table.text.split()
    if text.index('Кол-во'):
      wheels = text[text.index('Кол-во')+2]
    if text.index('Цвет'):
      colour = text[text.index('Цвет')+1]
      print(colour)
    beauty = 'Да' if 'Бьюти-кейс' in table.text else 'Нет'
    hand = 'Да' if 'Ручная кладь' in table.text else 'Нет'
    gender = ''
  except: pass
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

  data = {
    # основные поля
    'articule':articule,
    'name':name,
    'searches':'',
    'desc':desc,
    'type':'r',
    'price':price.replace('р.',''),
    'price_from':'',
    'currency': 'RUB',
    'measurment_unit':"шт",
    'minimum':'', 'wholesale':'', 'minimums_wholesale':'', 'amount':'',
    'img':[i for i in img],
    'avaliable':'+',#avaliable,
    'action':action, 'action_from':'', 'action_to':'', 'label':'',
    'manufacturer':manufacturer,
    'country':country,
    'HTML_header':'', 'HTML_description':'', 'HTML_keywords':'',
    'gifts':'', 'group_number':'', 'group_name':'', 'subsection_address':'',
    'delivery_possibility':'', 'delivery_terms':'', 'packing':'', 'personal_notes':'',
    'product_link':url,
    'GTIN':'', 'MPN':'',
    'product_id':articule,
    'product_unique_id':'', 'subsection_id':'',
    'group_id':category,
    'species_group_id':'',

    'sizes_name': sizes_name,           # Название_Характеристики
    "sizes_measurment":sizes_measurment,# Измерение_Характеристики
    'sizes':sizes,                      # Значение_Характеристики

    'weight_name': 'Вес',
    "weight_measurment":'кг',
    'weight':weight,

    'extends_name': "Расширение",
    "extends_measurment":"",
    'extends':extends,

    'material_name': "Материал",
    "material_measurment":"",
    'material':material,

    # 'gender_name':'Пол',
    # 'gender_measurment':'',
    # 'gender':gender,

    'wheels_name':"Кол-во колес",
    'wheels_measurment':'',
    'wheels':wheels,

    'colour_name':'Цвет',
    'colour_measurment':'',
    'colour':colour,

    'beauty_name': 'Бьюти-кейс',
    'beauty_measurment': '',
    'beauty': beauty,

    'hand_name': 'Ручная кладь',
    'hand_measurment': '',
    'hand': hand,

  }
  global COUNTER; COUNTER += 1; print(COUNTER);
  print(name)
  print(url)
  write_csv(data)

def write_csv(data):
  with open('raw_blezer.csv', 'a') as f:
      # order = [
      #   'name', 'price', 'desc',
      #   'cat', 'subcat', 'link',
      #   'img_name', 'img_link'
      # ]
      order = list(data.keys())
      writer = csv.DictWriter(f, fieldnames=order)
      writer.writerow(data)

def edit_fields():
  raw_2 = open('raw_blezer2.csv', 'r')
  edited_raw_2 = open('edited_raw_blezer.csv', 'w')
  # for line in f:
  #   print(line)
  c = raw_2.read()
  c = c.replace("['","'")
  c = c.replace("']","'")
  c = c.replace('Чемоданы на колесиках', "9980")
  c = c.replace('Пластиковые чемоданы', "9981")
  c = c.replace('Дорожные саквояжи', "9982")
  c = c.replace('Детские чемоданы', "9983")
  c = c.replace('Детские игрушки', "9984")
  c = c.replace('Сумки на колесиках', "9985")
  c = c.replace('Чемоданы кейс-пилот', "9986")
  c = c.replace('Хозяйственные сумки тележки', "9987")
  c = c.replace('Рюкзаки', "9988")
  c = c.replace('Чехлы для чемоданов', "9989")
  c = c.replace('Детское постельное белье', "9990")
  c = c.replace('Постельное белье', "9991")
  c = c.replace('Сумки для ноутбука', "9992")
  c = c.replace('Комплекты чемоданов', "9993")
  c = c.replace('Мешки для обуви', "9994")
  c = c.replace('Рюкзаки школьные', "9995")
  c = c.replace('Уцененный товар', "9996")
  edited_raw_2.write(c)
  edited_raw_2.close()
  raw_2.close()

def cats():
  url2 = 'https://www.blezer.ru/chemodany_na_kolesikax/'+ '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/plastikovii_chemodan/' + '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/index.php?route=product/category&path=79' + '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/detskie_chemodani/' + '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/detskie_igrushki/' + '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/symki_na_kolesikah/' + '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/index.php?route=product/category&path=162' + '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/hozyaistvenie_symki/' + '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/portfel/' + '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/chekhly-dlya-chemodanov/' + '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/detskoe-postelnoe-belie/' + '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/postelnoe-belio/' + '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/index.php?route=product/category&path=157' + '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/index.php?route=product/category&path=159' + '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/meshki_dlya_obuvi/' + '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/shkolnye_ryukzaki/' + '?limit=10000'
  get_products(url2)
  url2 = 'https://www.blezer.ru/discounted/' + '?limit=10000'
  get_products(url2)

def solo():
  # url3 = 'https://www.blezer.ru/index.php?route=product/product&path=162&product_id=3351'
  # url3 = 'https://www.blezer.ru/index.php?route=product/product&path=67&product_id=1749'
  # url3 = 'https://www.blezer.ru/plastikovii_chemodan/1203.html'
  # url3 = 'https://www.blezer.ru/index.php?route=product/product&path=79&product_id=673'
  # url3 = 'https://www.blezer.ru/index.php?route=product/product&path=79&product_id=678'
  url3 = 'https://www.blezer.ru/index.php?route=product/product&path=63&product_id=2949'
  get_product(url3)

def main():
  get_categories('https://www.blezer.ru/')

if __name__ == '__main__':
  # main()
  # cats()
  # solo()
  edit_fields()