def foo(a, b, **kwargs):
    legal_args = ['width', 'height', 'color', 'spec']
    for key in kwargs:
        if key not in legal_args:
            print('{} is invalid arguments'.format(key))
            return

    width = kwargs.get('width', 1)
    height = kwargs.get('width', 1)
    color = kwargs.get('color', 'red')
    spec = kwargs.get('spec', 'default')

    print(f'a = {a}, b = {b}, width = {width}, height =  {height}, color = {color}, spec = {spec}')

foo(10, 20)
foo(10, 20, color = 'blue', spec = 'x12')
foo(10, 20, height = 10, color = 'red')


import numpy as np
import xi_2D

class jack_knife:
    def __init__(self, Box, DIM, L_Box, **kwargs):
        self.Box = Box
        self.DIM = DIM
        self.L_Box = L_Box
        if 'ndim' in kwargs:
            self.ndim = int(kwargs.get('ndim'))
        else:
            self.ndim = 2

    @staticmethod
    def jack_usage():
        return 'jack_knife(box, DIM, L_Box)'

    @staticmethod
    def make_subfields_usage():
        return 'provide subfields =  #subfields/DIM'

    def make_subfields(self, **kwargs):
        try:
            #make a new instance
            subfields_per_dim = float(kwargs.get('subfields_per_dim'))
            if self.DIM % subfields_per_dim != 0:
                print('We are here')
                raise SyntaxError('subfields/DIM must not have a remainder')
            self.subfields_per_dim = int(subfields_per_dim)
            print('we have made' , subfields_per_dim, self.subfields_per_dim )
        except:
            raise SyntaxError(self.make_subfields_usage())

        #now we know how many times we can cut up each dimension
        #if the array is 2D then there will be subfields_per_dim**2 subfields
        self.pixels_per_subset = int(self.DIM/self.subfields_per_dim)
        Box_subsets = np.zeros((int(self.subfields_per_dim), int(self.subfields_per_dim), int(self.pixels_per_subset), int(self.pixels_per_subset)))
        for i in range(self.subfields_per_dim):
            for j in range(self.subfields_per_dim):
                Box_subsets[i][j] = self.Box[i * self.DIM/self.subfields_per_dim: (i + 1) * self.DIM/self.subfields_per_dim, j * self.DIM/self.subfields_per_dim : (j + 1) * self.DIM/self.subfields_per_dim]

        #lets just make this subset a box an official attribute
        self.Box_subsets = Box_subsets
        return Box_subsets

    def compute_xi(self,  **kwargs):

        if 'n_bins' in kwargs:
            n_bins = kwargs.get('n_bins')
        else:
            n_bins = 100

        if 'bins' in kwargs:
            acfbins = kwargs.get('bins')
        else:
            acfbins = np.linspace(0.5, self.L_Box, n_bins)

        if 'Box' in kwargs:
            compute_this_box = kwargs.get('Box')
        else:
            compute_this_box = self.Box

        if 'return_extras' in kwargs:
            return_extras = kwargs.get('return_extras')
        else:
            return_extras = False

        xi, xi_bins , binn_counter, countbox = xi_2D.ps_k(1.5, 20, temperature = compute_this_box, mode = 'custom', bins = acfbins)

        if return_extras == True:
            return xi, xi_bins , binn_counter, countbox
        else:
            return xi

    def compute_jackknife_stat(self, **kwargs):
        #make sure whether the user made the subfields first
        try:
            subfields = self.Box_subsets
        except:
            return 'Run make_subfields method first'

        #sort through user changeable definitions (bins)
        if 'nbins' in kwargs:
            nbins = kwargs.get('nbins')
        else:
            nbins = 50

        if 'bins' in kwargs:
            acfbins = kwargs.get('bins')
            #how does acfbins know about the subfields DIM and L_box????
            acfbins = xi_2D.create_k_boundaries(0.008, 1.3 , mode = 'custom', bins = acfbins)[1]
        else:
            print('bins will go from 0.5 to ' + str(self.L_Box/self.subfields_per_dim) +' in ' + str(nbins) + ' steps' )
            acfbins = np.linspace(0.5, self.L_Box/self.subfields_per_dim, nbins)
            acfbins = xi_2D.create_k_boundaries(0.008, 1.3 , mode = 'custom', bins = acfbins)[1]

        #make sure the last two dimensions are the actual max length of the subfield boxes
        xi_subfields = np.zeros((subfields.shape[0], subfields.shape[1] , len(acfbins)))
        xi_bar = np.zeros((len(acfbins)))

        #compute the  correlation fuction for each of the subfields
        for i in range(subfields.shape[0]):
            for j in range(subfields.shape[1]):
                xi, xi_bins , binn_counter, countbox = xi_2D.ps_k(1.5, 20, temperature = subfields[i][j], mode = 'custom', bins = acfbins)
                xi_subfields[i][j] = xi
                xi_bar += xi

        #find the average at each bin
        xi_bar = np.true_divide(xi_bar, subfields.shape[0]*subfields.shape[1])

        #do the correlation matrix
        C_ave = np.zeros(( len(acfbins) , len(acfbins)))
        for sx in range(subfields.shape[0]):
            for sy in range(subfields.shape[1]):
                #print('Doing subfield' , sx, sy)
                #print('the ACF here is', xi_subfields[sx][sy])
                C = np.zeros(( len(acfbins) , len(acfbins)))
                for i in range(len(acfbins)):
                    for j in range(len(acfbins)):
                        #for each subfield, compute the covariance matrix
                        C[i][j] = (xi_subfields[sx][sy][i] - xi_bar[i])*(xi_subfields[sx][sy][j]- xi_bar[j])
                C_ave += C
        C_ave = np.true_divide((subfields.shape[0]*subfields.shape[1] - 1) * C_ave , (subfields.shape[0]*subfields.shape[1] - 1 ) )

        #normalization for 'correlation matrix'
        r = np.zeros_like(C_ave)
        for i in range(C_ave.shape[0]):
            for j in range(C_ave.shape[1]):
                r[i][j] = np.true_divide(C_ave[i][j],  np.sqrt(C_ave[i][i]*C_ave[j][j]) )

        return r


n, k = map(int, input().split())
mod = 10**9 + 7

def comb(n, k):
    return fact[n] // (fact[k] * fact[n-k])

i = 1
fact = [1]
while i < n+1:
    fact.append(i * fact[-1])
    i += 1

j = 1
while j < k+1:
    print((comb(n-k+1, j) * comb(k-1, j-1)) % mod)
    j += 1


from django.shortcuts import render
from django.core.exceptions import ObjectDoesNotExist
from rest_framework import status
from rest_framework.decorators import api_view, renderer_classes
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from api.models import DiningHall, Swipe, Bid, User, Account
from api.serializers import SwipeSerializer, BidSerializer
import json
import datetime
import re
import pytz
import os
from pytz import timezone
from twilio.rest import Client

twilio_account_sid = os.environ.get("twilio_account_sid", None)
twilio_auth_token = os.environ.get("twilio_auth_token", None)

@api_view(['POST'])
@renderer_classes([JSONRenderer])
# TODO: Test location filtering
def get_best_pairing(request):
    """
    Finds all bids that match the specified swipe criteria and pairs them.

    Args:
        hall_id (string): The dining hall identifier.
        time_intervals (Datatime, optional): The desired time intervals. Defaults to None.
        desired_price (Float, optional): The desired price. Defaults to None.
        pair_type:
    Returns:
        Bid/Swipe: The paired Bid or Swipe depending on which endpoint originated the request.
    """
    data = request.data
    if 'hall_id' not in data:
        return Response({'STATUS': '1', 'REASON': 'MISSING REQUIRED HALL_ID ARGUMENT'}, status=status.HTTP_400_BAD_REQUEST)
    time_intervals = None
    if 'time_intervals' in data:
        time_intervals = []
        for interval in data['time_intervals']:
            interval_obj = {}
            for k, v in dict(interval).items():
                interval_obj[k] = datetime.datetime.strptime(v, "%H:%M").time()
            time_intervals.append(interval_obj)
    else:
        now = datetime.datetime.now()
        time_intervals = [{'start': (now - datetime.timedelta(minutes=90)).time(),
                            'end': (now + datetime.timedelta(minutes=90)).time()}]
    desired_price = data.get('desired_price', None)
    try:
        pair_type = request.resolver_match.url_name
        overlap = None
        candidates = None
        paired = None
        best_found = None
        serializer = None
        name = None
        requester_location = None
        paired_location = None
        # Get the potential bids or swipes by filtering to only unsold ones at the given location, filtered in order of highest/lowest price respectively.
        if pair_type == 'get_bid':
            candidates = Bid.objects.filter(status=0, hall_id=data['hall_id']).order_by('-bid_price', 'bid_id')
        else:
            candidates = Swipe.objects.filter(status=0, hall_id=data['hall_id']).order_by('price', 'swipe_id')
        if 'user_id' in data:
            requester_location = Account.objects.get(user_id=data['user_id']).cur_loc # Go ahead and get the requester's location, it's okay if it's None because the distance function will handle it
            if pair_type == 'get_bid':
                candidates = candidates.exclude(buyer__user_id=data['user_id'])
            else:
                candidates = candidates.exclude(seller__user_id=data['user_id'])
        for candidate in candidates:
            if paired is not None and ((pair_type == 'get_bid' and float(paired.bid_price) > float(candidate.bid_price)) or (pair_type == 'get_swipe' and float(paired.price) < float(candidate.price))): # If on a second iteration or more, check to see if this next candidate is worse than the current best
                break # If the next potential candidate is a worse value (either lower bid price or higher swipe price), we don't care about checking location or even the interval overlaps
            # If a desired price has been specified and the highest priced bid is less than what the seller wants, we'll just create the Swipe object w/o tying the bid to it
            if desired_price is not None and ((pair_type == 'get_bid' and float(desired_price) > float(candidate.bid_price)) or (pair_type == 'get_swipe' and float(desired_price) < float(candidate.price))):
                return Response({}, status=status.HTTP_200_OK)
            for potential_hours in candidate.visibility:
                for desired_hours in time_intervals:
                    overlap_start = max(desired_hours['start'], potential_hours['start'].time())
                    overlap_end = min(desired_hours['end'], potential_hours['end'].time())
                    if overlap_start <= overlap_end: # A potential candidate, intervals line up
                        candidate_location = None
                        if requester_location is not None: # Assuming the requester has a current location tied to their account
                            candidate_user_id = candidate.buyer_id if pair_type == 'get_bid' else candidate.seller_id
                            try:
                                candidate_location = Account.objects.get(user_id=candidate_user_id).cur_loc
                            except Account.DoesNotExist:
                                candidate_location = None # It really isn't a problem if they don't have a location paired, we'll just return the max float for distance so subsequent iterations of identically priced bids/swipes will prefer those with locations
                        if paired is None or Location.distance(requester_location, candidate_location) < Location.distance(requester_location, paired_location): # Either first iteration or this candidate is closer
                            paired = candidate
                            paired_location = candidate_location # Only used if requester_location is set, since we'll only run one iteration if it's None
                            overlap = {'start': overlap_start.strftime("%H:%M"), 'end': overlap_end.strftime("%H:%M")}
            if paired is not None and requester_location is None:
                break
        if pair_type == 'get_bid':
            serializer = BidSerializer(paired)
            name = paired.buyer.name if paired is not None else name
        else:
            serializer = SwipeSerializer(paired)
            name = paired.seller.name if paired is not None else name
        return Response(dict(name=name, overlap=overlap, **serializer.data), status=status.HTTP_200_OK)
    except ObjectDoesNotExist: # Generic Django exception for if either no bids or swipes exist meeting the hall/status criteria
        return Response({}, status=status.HTTP_200_OK)

@api_view(['POST'])
@renderer_classes([JSONRenderer])
def create_and_pair(request):
    data = request.data
    if 'user_id' not in data:
        return Response({'STATUS': '1', 'REASON': 'MISSING REQUIRED USER_ID ARGUMENT FOR ORIGINATING USER'}, status=status.HTTP_400_BAD_REQUEST)
    if 'hall_id' not in data:
        return Response({'STATUS': '1', 'REASON': 'MISSING REQUIRED HALL_ID ARGUMENT FOR BID/SWIPE'}, status=status.HTTP_400_BAD_REQUEST)
    try:
        pair_type = request.resolver_match.url_name # Different endpoints call the same view, so we need to differentiate between them
        paired = None
        paired_serializer = None
        paired_phone = None
        serializer = None
        creator_phone = Account.objects.get(user_id=data['user_id']).phone
        serial_data = {'seller': data['user_id'], 'hall_id': data['hall_id'], 'price': data.get('desired_price', None), 'visibility': data.get('time_intervals', None)}
        if pair_type == 'sell_swipe' and 'bid_id' in data:
            paired = Bid.objects.get(bid_id=data['bid_id'])
        elif pair_type == 'buy_swipe' and 'swipe_id' in data:
            paired = Swipe.objects.get(swipe_id=data['swipe_id'])
        if paired is not None:
            if paired.status != '0':
                return Response({'STATUS': '1', 'REASON': 'BID/SWIPE FOUND BUT HAS ALREADY BEEN SOLD, CAN\'T SELL IT AGAIN'}, status=status.HTTP_400_BAD_REQUEST)
            if data.get('desired_time', None) is None:
                return Response({'STATUS': '1', 'REASON': 'ELIGIBLE PAIRING, BUT NO SPECIFIC TIME FOR TRANSACTION GIVEN'}, status=status.HTTP_400_BAD_REQUEST)
            serial_data['status'] = '1'
            if pair_type == 'sell_swipe':
                serial_data['price'] = paired.bid_price
                paired_phone = Account.objects.get(user_id=paired.buyer_id).phone
            else:
                serial_data['price'] = paired.price
                serial_data['swipe'] = paired.swipe_id
                serial_data['desired_time'] = data['desired_time']
                paired_phone = Account.objects.get(user_id=paired.seller_id).phone
        else:
            if serial_data['visibility'] is None:
                return Response({'STATUS': '1', 'REASON': 'NO ELIGIBLE PAIRING, BUT NO DESIRED TIME RANGE TO CREATE STANDALONE OBJECT'}, status=status.HTTP_400_BAD_REQUEST)
            if serial_data['price'] is None:
                return Response({'STATUS': '1', 'REASON': 'NO ELIGIBLE PAIRING, BUT NO DESIRED PRICE TO CREATE STANDALONE OBJECT'}, status=status.HTTP_400_BAD_REQUEST)
        if pair_type == 'sell_swipe':
            serializer = SwipeSerializer(data=serial_data)
        else:
            serial_data['buyer'] = serial_data.pop('seller')
            serial_data['bid_price'] = serial_data.pop('price')
            serializer = BidSerializer(data=serial_data)
        if serializer.is_valid():
            saved = serializer.save()
            if paired is not None:
                if pair_type == 'sell_swipe':
                    paired_serializer = BidSerializer(paired, data={'status': '1', 'swipe': saved.swipe_id, 'desired_time': data['desired_time']}, partial=True)
                else:
                    paired_serializer = SwipeSerializer(paired, data={'status': '1'}, partial=True)
                if paired_serializer.is_valid():
                    paired = paired_serializer.save()
                else:
                    return Response({'STATUS': '1', 'REASON': 'PAIRED OBJECT SERIALIZER ERROR', 'ERRORS': {**paired_serializer.errors}}, status=status.HTTP_400_BAD_REQUEST)
            # Send confirmation texts to buyer and seller, respectively
            if twilio_account_sid is not None and twilio_auth_token is not None:
                twilio_client = Client(twilio_account_sid, twilio_auth_token)
                creator_phone = re.sub('[^0-9]+', '', creator_phone) # Strip out any non-numeric characters
                hall_name = saved.hall_id.name # Get the dining hall name for the text
                meeting_time = datetime.datetime.strptime(data['desired_time'], "%H:%M").strftime("%I:%M%p") # And form a 12-hour string
                creator_msg = "This is SwipeX, letting you know that while we haven't found a " + ("seller" if saved.__class__.__name__ == 'Bid' else "buyer") + " for your " + ("bid" if saved.__class__.__name__ == 'Bid' else "swipe sale") + " request at " + hall_name + " at this time, you've been entered into the queue and will be notified when a pairing occurs. Thank you for choosing SwipeX!"
                if paired_phone is not None:
                    paired_phone = re.sub('[^0-9]+', '', paired_phone)
                    paired_phone_formatted = re.sub("(\d)(?=(\d{3})+(?!\d))", r"\1-", "%d" % int(paired_phone[:-1])) + paired_phone[-1] # Add dashes in between phone numbers to send for communication purposes
                    creator_phone_formatted = re.sub("(\d)(?=(\d{3})+(?!\d))", r"\1-", "%d" % int(creator_phone[:-1])) + creator_phone[-1]
                    creator_msg = "This is SwipeX, letting you know that we were able to find and match you with a " + ("buyer for your swipe" if saved.__class__.__name__ == 'Swipe' else "seller for your bid") + " that would like to meet at " + hall_name + " at " + meeting_time + ". You can contact them at " + paired_phone_formatted + " to coordinate more details. Thank you for choosing SwipeX!"
                    paired_msg = "This is SwipeX with an update for you on your existing " + ("bid" if paired.__class__.__name__ == 'Bid' else "swipe sale") + " request. You've been paired with a " + ("seller" if paired.__class__.__name__ == 'Bid' else "buyer") + " that would like to meet at " + hall_name + " at " + meeting_time + ". You can contact them at " + creator_phone_formatted + " to coordinate more details. Thank you for choosing SwipeX!"
                    paired_phone = "+" + ("1" if len(paired_phone) == 10 else "") + paired_phone # Assume 10-digit number is US without the 1 attached, just an easy test for right now
                    twilio_client.messages.create(body=paired_msg, from_='+18563065093', to=paired_phone)
                creator_phone = "+" + ("1" if len(creator_phone) == 10 else "") + creator_phone
                twilio_client.messages.create(body=creator_msg, from_='+18563065093', to=creator_phone)
            if paired is not None:
                return Response({'STATUS': '0', 'REASON': 'SWIPE/BID CREATED, PAIRED WITH COMPLEMENT'}, status=status.HTTP_200_OK)
            return Response({'STATUS': '0', 'REASON': 'SWIPE/BID CREATED, NO ELIGIBLE COMPLEMENT PAIRED'}, status=status.HTTP_200_OK)
        return Response({'STATUS': '1', 'REASON': 'ORIGINATING SERIALIZER ERROR', 'ERRORS': {**serializer.errors}}, status=status.HTTP_400_BAD_REQUEST)
    except ObjectDoesNotExist:
        return Response({'STATUS': '1', 'REASON': 'NO BID/SWIPE EXISTS WITH GIVEN ID'}, status=status.HTTP_400_BAD_REQUEST)

# @param request Has a desired time and we return the swipes available
#                at each dining hall
# TODO: implement location filtering too
# returns a JSON of dining hall names with lowest ask and highest bid
@api_view(['GET'])
@renderer_classes([JSONRenderer])
def get_swipes(request):
    """
    Return swipe data for each dining hall; used to populate main page

    Args:
        request (Request): does't need inputs

    Returns:
        JSON: dining halls with the lowest swipe available and total number of swipes {"Hall": {"nBids": 1, "nSwipes": 1, "times": {"start": 17, "end": 20}, "lowest_ask": 5}}
    """

    halls_list = ["FEAST at Rieber", "De Neve", "Covel", "Bruin Plate"]
    quick_list = ["Bruin Cafe", "Cafe 1919", "Rendezvous", "The Study at Hedrick"]

    hall_data = {"halls":[], "quick":[]}
    halls = DiningHall.objects.all()

    date = datetime.datetime.now(tz=pytz.utc)
    date = date.astimezone(timezone('US/Pacific'))
    cur_time = date.time().hour

    for hall in halls:

        cur_id = hall.hall_id
        cur_name = hall.name

        # see if hall is currently open
        hours = hall.hours
        times = {'start': 0, 'end': 0}
        found = False

        for h in hours:
            start = h['start'].hour
            end   = h['end'].hour

            # Handle midnight being stored as a 0 and Study closing at 2 am
            end_compare = end
            if end == 0 or end == 2:
                end_compare = 24 + end

            if start <= cur_time and cur_time < end_compare:
                times['start'] = start
                times['end']   = end
                found = True
                break

            elif cur_time < start:
                times['start'] = start
                times['end']   = end

        if not found and times['end'] <= cur_time:
            times['start'] = hours[0]["start"].hour
            times['end']   = hours[0]["end"].hour

        # get stats for number of swipes and bids
        swipes = Swipe.objects.filter(status=0, hall_id=cur_id)
        nSwipes  = swipes.count()

        bids = Bid.objects.filter(status=0, hall_id=cur_id)
        nBids = bids.count()

        # lowest ask
        lowest = 0
        sorted_swipes = swipes.order_by('price')
        if len(sorted_swipes) >= 1:
            lowest = sorted_swipes[0].price

        # insert cur_hall into hall_data
        cur_hall = {"hall_id": cur_id, "picture_link": hall.picture, "name": cur_name, "nBids": nBids, "nSwipes": nSwipes, "times": times, "lowest_ask": lowest}
        if cur_name in halls_list:
            hall_data["halls"].append(cur_hall)
        elif cur_name in quick_list:
            hall_data["quick"].append(cur_hall)

    return Response(json.dumps(hall_data), status=status.HTTP_200_OK)

@api_view(['POST'])
@renderer_classes([JSONRenderer])
def get_hall_stats(request):
    """
    Finds swipes and bids for a given hall at a given time.

    Args:
            request (Request): Object that contains the user specified hall_id and time.

    Returns:
            Reponse: HTML response containing the swipe counts, bid counts, lowest ask and highest bid meeting the user
                        specified criteria, or it returns an error HTML response.
    """

    data = request.data
    offerData = {}
    if 'hall_id' not in data:
        return Response({'STATUS': '1', 'REASON': 'MISSING REQUIRED HALL_ID ARGUMENT'}, status=status.HTTP_400_BAD_REQUEST)
    desired_time = data.get('desired_time', None)
    if desired_time is None:
        desired_time = datetime.datetime.now()
    else:
        desired_time = datetime.datetime.strptime(desired_time, "%H:%M")
    swipes = Swipe.objects.filter(hall_id=data['hall_id'], status=0).order_by('price', 'swipe_id')
    swipes_filtered = []
    for swipe in swipes:
        for hours in swipe.visibility:
            if hours['start'].time() <= desired_time.time() and hours['end'].time() >= desired_time.time():
                swipes_filtered.append(swipe)
    bids = Bid.objects.filter(hall_id=data['hall_id'], status=0).order_by('-bid_price', 'bid_id')
    bids_filtered = []
    for bid in bids:
        if bid.desired_time is None or ((desired_time - datetime.timedelta(minutes=45)).time() <= bid.desired_time.time() and (desired_time + datetime.timedelta(minutes=45)).time() >= bid.desired_time.time()):
            bids_filtered.append(bid)
    offerData = {'swipe_count': len(swipes_filtered), 'bid_count': len(bids_filtered), 'lowest_ask': swipes_filtered[0].price if len(
        swipes_filtered) > 0 else None, 'highest_bid': bids_filtered[0].bid_price if len(bids_filtered) > 0 else None}
    return Response(offerData, status=status.HTTP_200_OK)

@api_view(['POST'])
def lowestswipe_highestbid_info(request):
    """
    Get the lowest swipe price and highest bid price in a time interval

    Args:
            hall_id (string): The DiningHall identifier.
            start (int): start of the time interval
            end(int): end of the time interval

    Returns:
            {"low": (string: lowest swipe price),"high" : (string: highest bid price)}
    """
    data = request.data
    if 'hall_id' not in data:
        return Response({'STATUS': '1', 'REASON': 'MISSING REQUIRED hall_id ARGUMENT'}, status=status.HTTP_400_BAD_REQUEST)
    if 'start' not in data:
        return Response({'STATUS': '1', 'REASON': 'MISSING REQUIRED start ARGUMENT'}, status=status.HTTP_400_BAD_REQUEST)
    if 'end' not in data:
        return Response({'STATUS': '1', 'REASON': 'MISSING REQUIRED end ARGUMENT'}, status=status.HTTP_400_BAD_REQUEST)

    info = {}

    swipe_candidates = Swipe.objects.filter(hall_id=data['hall_id'], status=0).order_by('price')
    bid_candidates = Bid.objects.filter(hall_id=data['hall_id'], status=0).order_by('bid_price')

    for i in range(int(data['start']), int(data['end']) + 1):
        info[i] = {}
        for j in range(i+1, int(data['end']) + 1):
            info[i][j] = {}
            info[i][j]["swipe"] = str(int(get_lowest_swipe(swipe_candidates, i, j)))
            info[i][j]["bid"] = str(int(get_highest_bid(bid_candidates, i, j)))

    return Response(json.dumps(info), status=status.HTTP_200_OK)

def get_lowest_swipe(swipe_candidates, start, end):
    """
    Function for getting the lowest swipe in a given time range.

    Args:
        swipe_candidates (list): The swipes
        start (int): The start of the desired time interval
        end (int): The end of the desired time interval

    Returns:
        float: The lowest price out of all swipes
    """
    curr_price = float("inf")
    for swipe in swipe_candidates:
        for hours in swipe.visibility:
            curr_start = str(hours['start']).split(" ")[1].split(":")[0]
            curr_end = str(hours['end']).split(" ")[1].split(":")[0]
            if max(int(curr_start), start) < min(int(curr_end), end):
                curr_price = min(curr_price, float(swipe.price))

    return 0 if curr_price == float("inf") else curr_price

def get_highest_bid(bid_candidates, start, end):
    """
    Function for getting the highest big out of a list of bids in a desired time interval.

    Args:
        bid_candidates (list): The list of bids
        start (int): The start of the desired time interval
        end (int): The end of the desired time interval

    Returns:
        float: The highest bid price.
    """
    curr_price = 0
    for bid in bid_candidates:
        for hours in bid.visibility:
            curr_start = str(hours['start']).split(" ")[1].split(":")[0]
            curr_end = str(hours['end']).split(" ")[1].split(":")[0]
            if max(int(curr_start), start) < min(int(curr_end), end):
                curr_price = max(curr_price, float(bid.bid_price))

    return curr_price


import sys
from pathlib import Path
from parse import Parse
from codewriter import CodeWriter
from cmdtable import CmdTable

def write_vm1(inputfile, in_filename, ctabel, cw):
    par = Parse(inputfile, ctabel)
    cw.setInputname(in_filename)

    while par.hasMoreCommands():
        par.advance()
        ctype = par.cmdType()
        if ctype == "C_ARITHMETIC":
            cw.writeArithmetic(par.arg1())
        elif ctype == "C_PUSH" or ctype == "C_POP":
            cw.writePushPop(ctype, par.arg1(), int(par.arg2()))
        elif ctype == "C_LABEL":
            cw.writeLabel(par.arg1())
        elif ctype == "C_IF":
            cw.writeIf(par.arg1())
        elif ctype == "C_GOTO":
            cw.writeGoto(par.arg1())
        elif ctype == "C_FUNCTION":
            cw.writeFunction(par.arg1(), int(par.arg2()))
        elif ctype == "C_RETURN":
            cw.writeReturn()
        elif ctype == "C_CALL":
            cw.writeCall(par.arg1(), int(par.arg2()))

    #cw.getarith_jump()

def main():
    p=Path(sys.argv[1])
    ctabel = CmdTable()
    out_filename= p.stem
    inputfile_list = {}
    if p.is_file():
        outputfile = str(p.parent / (out_filename + ".asm"))
        inputfile_list[str(p)] = p.stem
    elif p.is_dir():
        outputfile = p / (out_filename + ".asm")
        for pfile in p.glob('*.vm'):
            inputfile_list[str(pfile)] = pfile.stem

    fout = open(outputfile, mode='w')
    cw = CodeWriter(fout, ctabel)
    if p.is_dir():
        cw.writeBoot()

    for inf, infname in inputfile_list.items():
        write_vm1(inf, infname, ctabel, cw)
    fout.close()

    # debug: write line number
    #newfile = p / (out_filename + ".txt")
    #print(newfile)
    #with open(newfile, 'w') as file_linenum:
    #    line_count = 0
    #    with open(outputfile) as file_asm:
    #        for line in file_asm:
    #            if ("//" not in line) and ("(" not in line):
    #                line_count += 1
    #                line = str(line_count) + " " + line
    #            file_linenum.write(line)

if __name__ == "__main__":
    main()


from format import *
import re
import os

def convert_bit_string(data: bytes):
    """ convert string data to bit string """
    res = ''
    flag = True
    for it in data:
        if not flag:
            if it == 0x00:
                res += bin(0xff).replace('0b', '').zfill(8)
            elif 0xd0 <= int(it) <= 0xd7:
                # RST n
                pass
            elif it == 0xff:
                # skip current 0xff
                pass
            else:
                # skip current 0xff
                res += bin(it).replace('0b', '').zfill(8)
            flag = True
            continue
        if it == 0xff:
            flag = False
            continue
        res += bin(it).replace('0b', '').zfill(8)
    return res

def bit_length(data: int):
    length = 0
    while data > 0:
        data >>= 1
        length += 1
    return length

def int2stringbit(data: int, length: int):
    if length == 0:
        return ''
    return bin(data).replace('0b', '').zfill(length)

def string2byte(data: str):
    str_list = re.findall(r'.{8}', data)
    res = []
    for it in str_list:
        value = int(it, 2).to_bytes(1, byteorder='big')
        if value == b'\xff':
            res.append(value)
            res.append(b'\x00')
            continue
        res.append(value)
    return res

def InverseZZ(block):
    zz = IZZ.flatten()
    return block.flatten()[zz].reshape([8, 8])

def ZZEncoder(block):
    zz = ZZ.flatten()
    return block.flatten()[zz].reshape([8, 8])

def GetByteFromFile(full_path: str):
    assert os.path.exists(full_path), 'path not exist!'
    with open(full_path, 'rb') as f:
        content = f.read()
    f.close()
    return content

def GetBitFromFile(full_path: str):
    assert os.path.exists(full_path), 'path not exist!'
    with open(full_path, 'rb') as f:
        content = f.read()
        res = ''
        for it in content:
            res += bin(it).replace('0b', '').zfill(8)
    f.close()
    return res

def dct(X):
    N = X.shape[0]
    A = np.zeros((N, N))

    for i in range(N):
        for j in range(N):
            if i == 0:
                a = np.sqrt(1 / N)
            else:
                a = np.sqrt(2 / N)
            A[i, j] = a * np.cos(np.pi * (j + 0.5) * i / N)
    Y = A.dot(X).dot(A.T)
    return Y

def idct(X):
    N = X.shape[0]
    A = np.zeros((N, N))
    for i in range(N):
        for j in range(N):
            if i == 0:
                a = np.sqrt(1 / N)
            else:
                a = np.sqrt(2 / N)
            A[i, j] = a * np.cos(np.pi * (j + 0.5) * i / N)
    Y = A.T.dot(X).dot(A)
    return Y


import httplib
import socket
import unittest

from minimock import mock, restore, Mock, TraceTracker, assert_same_trace
from webob import Request
from wsgiproxy.exactproxy import proxy_exact_request

def h(**kw):
    """Convenience function for headers"""

    d = {}
    for name, value in kw.items():
        d[name.replace('_', '-')] = str(value)
    return d

def expected_trace_for_request(request):
    return """
Called httplib.HTTPConnection('%(server_name)s:%(server_port)d')
Called httplib.HTTPConnection.request(
    '%(method)s',
    '%(path_qs)s',
    '%(body)s',
    {'Host': '%(host)s', 'Content-Length': %(content_length)s})
Called httplib.HTTPConnection.getresponse()
Called httpresponse.getheader('content-length')
Called httpresponse.read()
Called httplib.HTTPConnection.close()
    """.strip() % dict(
        server_name=request.server_name,
        server_port=request.server_port,
        host=request.host,
        method=request.method,
        path_qs=request.path_qs,
        body=request.body,
        content_length=request.content_length if request.content_length else 0,
        )

class ExactProxyTests(unittest.TestCase):
    def setUp(self):
        """Mock out httplib.HTTPConnection and
        httplib.HTTPSConnection"""

        self.trace_tracker = TraceTracker()
        self.conn = Mock('httplib.HTTPConnection', tracker=self.trace_tracker)
        mock('httplib.HTTPConnection', mock_obj=self.conn)
        mock('httplib.HTTPSConnection', mock_obj=self.conn)
        self.conn.mock_returns = self.conn

    def set_response(self, status, headers, body):
        mock_response = Mock('httpresponse', tracker=self.trace_tracker)
        mock_response.status = int(status.split()[0])
        mock_response.reason = status.split(None, 1)[1]
        mock_response.read.mock_returns = body
        mock_response.getheader.mock_returns_func = headers.get
        mock_response.msg.headers = [
            '%s: %s' % (name, value) for name, value in headers.items()]
        self.conn.getresponse.mock_returns = mock_response

    def set_exception(self, exc):
        self.conn.request.mock_raises = exc

    def test_exception_HTTPBadGateway(self):
        req = Request.blank('http://example.com/testform')

        # -2 socket error should trigger HTTPBadGateway
        self.set_exception(socket.gaierror(-2))

        res = req.get_response(proxy_exact_request)

        self.assertEqual(res.status_code, 502)
        self.assertTrue('502 Bad Gateway' in res.body)

    def test_simple_request_200(self):
        req = Request.blank('http://example.com/testform')
        self.set_response(
            status='200 OK',
            headers=h(content_type='text/html'),
            body='some stuff',
            )

        res = req.get_response(proxy_exact_request)

        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.body, 'some stuff')
        self.assertEqual(res.headers['Content-Type'], 'text/html')
        assert_same_trace(self.trace_tracker, expected_trace_for_request(req))

    def test_simple_request_302(self):
        req = Request.blank('http://example.com/testform')
        self.set_response(
            status='302 Found',
            headers=h(content_type='text/html', set_cookie='foo=bar'),
            body='some content',
            )

        res = req.get_response(proxy_exact_request)

        self.assertEqual(res.status_code, 302)
        self.assertEqual(res.body, 'some content')
        self.assertEqual(res.headers['Content-Type'], 'text/html')
        self.assertEqual(res.headers['Set-Cookie'], 'foo=bar')
        assert_same_trace(self.trace_tracker, expected_trace_for_request(req))

    def test_simple_request_799(self):
        req = Request.blank('http://example.com/testform')
        self.set_response(
            status='799 Silly Response',
            headers=h(x_foobar='blaz'),
            body='blahblah',
            )

        res = req.get_response(proxy_exact_request)

        self.assertEqual(res.status_code, 799)
        self.assertEqual(res.body, 'blahblah')
        self.assertEqual(res.headers['X-Foobar'], 'blaz')
        assert_same_trace(self.trace_tracker, expected_trace_for_request(req))

    def test_post(self):
        req = Request.blank('http://example.com/testform')
        req.method = 'POST'
        req.query_string = 'test=result'
        req.body = 'var=value&var2=value2'
        req.environ['SERVER_NAME'] = 'example.org'
        req.environ['SERVER_PORT'] = '443'
        req.host = 'differenthost.com'
        req.scheme = 'https'
        self.set_response(
            status='200 OK',
            headers=h(content_type='text/html'),
            body='blahblah',
            )

        res = req.get_response(proxy_exact_request)

        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.body, 'blahblah')
        self.assertEqual(res.headers['Content-Type'], 'text/html')
        assert_same_trace(self.trace_tracker, expected_trace_for_request(req))


# -*- coding: utf-8 -*-
from __future__ import division
import os
from time import time

import numpy as np
import pandas as pd
import tensorflow as tf
from joblib import dump, load
from scipy.sparse import csc_matrix, csr_matrix, coo_matrix
from sklearn.model_selection import train_test_split

from Utils import preprocess

data_dir = os.path.join(os.path.split(os.path.realpath(__file__))[0], "..", "input")

trainSet = os.path.join(data_dir, "customeraffinity.train")
scoreSet = os.path.join(data_dir, "customeraffinity.score")

R_SHAPE = (93705, 3561)

# ---- Data as matrices and SparseTensors

def import_matrix(pr_valid=0.1, do_preprocess=False, return_sparse=True):
    data_frame = pd.read_csv(trainSet, header=None)

    if do_preprocess:
        data_frame.iloc[:, -1] = data_frame.iloc[:, -1].apply(preprocess)

    train_items, val_items = train_test_split(data_frame, test_size=pr_valid)

    train_mat = to_matrix(train_items)
    valid_mat = to_matrix(val_items)

    if not return_sparse:
        train_mat = train_mat.toarray()
        valid_mat = valid_mat.toarray()

    return train_mat, valid_mat

def to_matrix(tbl, shape=R_SHAPE):
    user_arr = tbl.iloc[:, 0].values
    item_arr = tbl.iloc[:, 1].values
    data = tbl.iloc[:, -1].values

    matrix = csc_matrix((data, (user_arr, item_arr)), dtype=np.float32)

    return matrix

def import_tensor(pr_valid=0.1, do_preprocess=False):
    tbl = pd.read_csv(trainSet, header=None)

    if do_preprocess:
        tbl.iloc[:, -1] = tbl.iloc[:, -1].apply(preprocess)

    train_items, val_items = train_test_split(tbl, test_size=pr_valid)

    train_mat = to_sparse_tensor(train_items)
    valid_mat = to_sparse_tensor(val_items)

    return train_mat, valid_mat

def to_sparse_tensor(tbl):
    tensor = tf.SparseTensor(list(zip(tbl.iloc[:, 0].values, tbl.iloc[:, 1].values)),
                             tbl.iloc[:, -1].values,
                             list(R_SHAPE))

    return tensor

# ---- Data as sequences of ratings

def dataframe_split(df, test_ratio):
    assert test_ratio > 0, 'Please specify a valid test ratio.'
    length = len(df)
    # Generate indices split
    test_indices = np.random.choice(length, int(test_ratio * length), replace=False)
    train_indices = list(set(range(length)).difference(test_indices))

    test_df = df.iloc[test_indices, :]
    train_df = df.iloc[train_indices, :]

    print("[Split] {} train, {} test ".format(len(train_indices), len(test_indices)))
    return train_df, test_df

def import_sequence(max_items=None, do_preprocess=False, test_ratio=0.1):
    # Read training data
    data_frame = pd.read_csv(trainSet, header=None, nrows=max_items)
    # Preprocess if needed
    if do_preprocess: data_frame.iloc[:, -1].apply(preprocess)

    # Split the table in train-test
    if test_ratio:
        data_frame, data_frame_bis = dataframe_split(data_frame, test_ratio)
    else:
        data_frame_bis = None

    # Create sequence data
    train_seqs = one_more_encoder(data_frame)
    test_seqs = one_more_encoder(data_frame_bis)

    return train_seqs, test_seqs

def one_more_encoder(data_frame):
    """
    Encode a dataframe in a sparse matrix with each row as a sequence having one more entry added compared to the previous row.
    A new set of sequence starts for each group of indices of the first dimension (you can think of them as users).
    On some systems it may be faster to iteratively build the matrix using a lil_matrix; here a csr_matrix is used.
    :param data_frame: dataframe in (i, j, v) form
    :return: compressed sparse row matrix of shape (size(dataframe), dimension of j)
    """
    # matrix = lil_matrix((n_train, 3), dtype=np.float32)
    tot_n_elts = len(data_frame)
    curr_client = 0
    user_hist = []
    row_indices = []  # np.empty(sp_ids_len, dtype=np.int32)
    col_indices = []  # np.empty(sp_ids_len, dtype=np.int32)
    data = []  # np.empty(sp_ids_len, dtype=np.int32)
    seq_len = 0
    user_bias = 0.0

    previous_index = 0

    for t in range(len(data_frame)):
        user, item, rating = data_frame.iloc[t]

        if not seq_len or user == curr_client:
            user_hist.append((item, rating))
            seq_len += 1
            user_bias = ((seq_len - 1) * user_bias + rating) / float(seq_len)
        else:  # new client
            # Save data
            items, ratings = zip(*user_hist)
            new_n_ratings = previous_index + seq_len
            if new_n_ratings > tot_n_elts:  # Extend datastruct (2 * current length)
                row_indices = np.hstack((row_indices, np.empty(tot_n_elts, dtype=np.float32)))
                col_indices = np.hstack((row_indices, np.empty(tot_n_elts, dtype=np.float32)))
                data = np.hstack((row_indices, np.empty(tot_n_elts, dtype=np.float32)))
                tot_n_elts *= 2

            row_indices[previous_index:new_n_ratings] = np.full(seq_len, t, dtype=np.float32)
            col_indices[previous_index:new_n_ratings] = np.array(items)
            data[previous_index:new_n_ratings] = np.array(ratings) - user_bias

            previous_index = new_n_ratings
            """
            data.extend(map(lambda r: r - user_bias, ratings))
            col_indices.extend(items)
            row_indices.extend([i] * len(items))
            """
            # Reset counters
            user_hist = []
            curr_client = user
            user_bias = 0
            seq_len = 0

        if t % 100000 == 0: print("[Import] Processed {} lines".format(t))

    # Construct and return sparse matrix
    matrix = csr_matrix((data[:previous_index], (row_indices[:previous_index], col_indices[:previous_index])),
                        shape=(len(data_frame), R_SHAPE[1]),
                        dtype=np.float32)

    return matrix

def cached_sequence_data(n_train=None, n_test=None, test_ratio=0.1, do_preprocess=False, filename='seq_data',
                         ext='bz2'):
    """
    Either load sequence data from file, or make from scratch using the original dataframe
    :param n_train: Number of training examples (default: None, will take entire dataset)
    :param n_test: Number of test examples (default: None, will take entire dataset)
    :param test_ratio: If the entire dataset is used, specify a split ratio > 0
    :param do_preprocess: Whether to recenter the data around zero or not.
    :param filename: Cache file where data will be read and written.
    :param ext: Extension which indicates the compression used.
    :return: Train and test sparse matrices
    """
    fp = '{}_{}.{}'.format(filename, 'pproc' if do_preprocess else 'raw', ext)
    data_file = os.path.join(data_dir, fp)
    if os.path.exists(data_file):
        t0 = time()
        train_sequences, test_sequences = load(data_file)
        n_train_seq = train_sequences.shape[0]
        n_test_seq = test_sequences.shape[0]

        print("[Loaded] {} train, {} test sequences from cache in {:.3}s".format(n_train_seq, n_test_seq, time() - t0))

        # Randomly sample some items if we loaded too much data
        if n_train and n_train_seq > n_train:
            train_indices = np.random.choice(n_train_seq, n_train, replace=False)
            train_sequences = train_sequences[train_indices]
        elif n_train and n_train_seq < n_train:
            raise ValueError('Archive contains too few train items. Delete {} and re-run.'.format(fp))

        if n_test and n_test_seq > n_test:
            test_indices = np.random.choice(n_test_seq, n_test, replace=False)
            test_sequences = test_sequences[test_indices]
        elif n_test and n_test_seq < n_test:
            raise ValueError('Archive contains too few test items. Delete {} and re-run.'.format(fp))

    else:
        if n_train and n_test:
            max_items = n_train + n_test
            test_ratio = n_test / max_items
        elif not n_test:
            max_items = n_train
            test_ratio = 0
        elif not n_train:
            max_items = n_test
            test_ratio = 1

        t0 = time()
        train_sequences, test_sequences = import_sequence(max_items, do_preprocess, test_ratio)
        dump((train_sequences, test_sequences), data_file)
        print("[Loaded] {} train, {} test sequences in {:.3} s".format(n_train, n_test, time() - t0))

    return train_sequences, test_sequences

def future_generator(X, batch_size, sparse=True, back_to_the_future=False):
    """
    A generator which outputs sequential batches of X indefinitely.
    :param X: sparse matrix for which the generator is made.
    :param batch_size: self-explanatory
    :param sparse: whether to keep the matrix's batch sparse
    :param back_to_the_future: whether to output batches with an offset of one row (to predict a future reconstruction).
    :return: a matrix with batch_size
    """
    total_samples = X.shape[0]
    n_batches = np.ceil(float(total_samples) / batch_size)
    i = 0
    f = 1 if back_to_the_future else 0
    while True:
        if i > n_batches: i = 0

        x_train = X[i * batch_size:min((i + 1) * batch_size, total_samples), :]
        x_test = X[i * batch_size + f:min((i + 1) * batch_size + f, total_samples), :]

        # Eventually extend the target matrix with the last vector of the original matrix
        diff = x_train.shape[0] - x_test.shape[0]
        if diff: x_test = np.vstack((x_test, x_test[-diff:]))

        if sparse:
            yield x_train, x_test
        else:
            yield x_train.toarray(), x_test.toarray()

        i += 1

def get_random_block_from_data(data, batch_size):
    start_index = np.random.randint(0, data.shape[0] - batch_size)
    return data[start_index:(start_index + batch_size), :]

def one_hot_encode(item, rating, input_dim):
    # Equivalent in tensorflow is tf.one_hot
    v = np.zeros(input_dim, dtype=np.float32)
    v[item] = rating
    return v

def sequence_encode(seq):
    usr_grp = seq.groupby(seq.iloc[:, 0], sort=False)
    rows, cols, data = [], [], []
    for i, (user, item_lst) in enumerate(usr_grp):
        n = len(item_lst)
        cols.extend(item_lst.iloc[:, 1].values)
        data.extend(item_lst.iloc[:, 2].values)
        rows.extend([i] * n)

    matrix = csr_matrix((np.array(data), (np.array(rows), np.array(cols))),
                        shape=(len(usr_grp), R_SHAPE[1]),
                        dtype=np.float32)
    return matrix

def validation_sparse_matrix(filename='seq_valid_data', ext='bz2', max_items=None):
    """
    Load the test data frame and make vectors grouped by users.
    :param filename: path to look whether the sequences data was already loaded
    :param ext: extension indicates compression type
    :param max_items: number of test items to retrieve
    :return: original dataframe and sparse matrix w/ shape (n_groups of 1st column, dimension of 2nd column)
    """
    score_dataframe = pd.read_csv(scoreSet, nrows=max_items)

    fp = filename + '.' + ext
    data_file = os.path.join(data_dir, fp)

    try:
        matrix = load(data_file)
    except Exception:
        user_grp = score_dataframe.groupby('new_user', sort=False)
        rows, cols, data = [], [], []
        for i, (user, item_lst) in enumerate(user_grp):
            n = len(item_lst)
            data.extend([preprocess(0)] * n)
            cols.extend(item_lst.new_item.values)
            rows.extend([i] * n)

        matrix = csr_matrix((np.array(data), (np.array(rows), np.array(cols))),
                            shape=(len(user_grp), R_SHAPE[1]),
                            dtype=np.float32)
        dump(matrix, data_file)
    return score_dataframe, matrix

if __name__ == "__main__":
    pass


#-------------------------------------------------------------------------------
# Name:        ToCSV
# Purpose:
#
# Author:      mthornton
#
# Created:     13/08/2019
# Copyright:   (c) mthornton 2019
# Licence:     <your licence>
#-------------------------------------------------------------------------------

def FindField(fc):
    field_list = [
        "NAME", "LABEL", "NOTES", "SEED_MIX", "Range", "PROJECT_NAME", "ORIGINAL_L",
        "WETLAND_TYPE", "Dist_Type", "Lessee", "MINENAME", "Plot_Name", "PitName", "ObjectID"
    ]
    fields = [fld.name.upper() for fld in arcpy.ListFields(fc)] #returns all filenames for current fc
    return next(f for f in field_list if f.upper() in fields)

def createCSV(data, csvname, mode ='ab'):
    with open(csvname, mode) as csvfile:
        csvwriter = csv.writer(csvfile, delimiter=',')
        csvwriter.writerow(data)

import arcpy
import csv
import os

csvname = r"U:\My Documents\ArcGIS\ArcPyOutputFiles\TestFile4.csv"
headers = 'Name', 'Path'
createCSV(headers, csvname, 'wb')

arcpy.env.workspace = r"V:\tools\ArcSDE\Database Connections\5 NMSO ilmnmso3gi1 ilmnmsoclass1 (Type 1) Default.sde"

datasets = arcpy.ListDatasets("*FFO*", "Feature")
datasets = [''] + datasets if datasets is not None else []

for ds in datasets:
    for fc in arcpy.ListFeatureClasses("*FFO*", "Polygon", feature_dataset=ds):

        path = os.path.join( ds, fc)
        pathAsDict = {}
        pathAsDict[path] = os.path.join( ds, fc)

        createCSV(pathAsDict, csvname)

        FldName = FindField(fc)

        with arcpy.da.SearchCursor(fc, [FldName, SHAPE@XY]) as sc:
            for row in sc:
                name = row[0]
                locationX = row[1][0]
                locationY = row[1][1]
                data = name, locationX, locationY
                createCSV(data, csvname)

#sql = "LABEL = 'POTENTIAL AZTEC GILA & BRACK'S CACTUS'"


from datetime import date, timedelta

def date_convert(value):
    value_date = map(int, value.split('-'))
    value_date = date(*value_date)
    return value_date

def time_convert(value):
    minutes = value % 60
    hours = value // 60
    return '{}:{:0>2}'.format(hours, minutes)

if __name__ == '__main__':
    print(time_convert(130))


import os
import unittest

from gtfs_parser.gtfs import GTFS
from gtfs_parser.parse import read_routes, read_stops

FIXTURE_DIR = os.path.join(os.path.dirname(__file__), "fixture")

class TestParser(unittest.TestCase):
    gtfs = GTFS(FIXTURE_DIR)

    def test_read_stops(self):
        stops_features = read_stops(self.gtfs)
        # list of geojson-feature
        self.assertEqual(899, len(stops_features))

        # remove no-route stops
        stops_features_no_noroute = read_stops(self.gtfs, ignore_no_route=True)
        self.assertEqual(896, len(stops_features_no_noroute))

    def test_read_routes(self):
        routes_features = read_routes(self.gtfs)
        self.assertEqual(32, len(routes_features))

        # num of features in routes.geojson depends on not shapes.txt but routes.txt
        routes_features_noshapes = read_routes(self.gtfs, ignore_shapes=True)
        self.assertEqual(32, len(routes_features_noshapes))


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

import xlsxwriter
from pymongo import ReadPreference

from commons.common_utils import str2datetime
from db.models import MemberCheckPointHistory, RaceGameCheckPoint, RedPacketBox, Race, BaseModel
from initialize.export.export_town_information import convert
from motorengine.fields import DateTimeField

class DailyAward(object):
    def __init__(self, daily_code, attend_count, lottery_count, win_count):
        self.daily_code = daily_code
        self.attend_count = attend_count
        self.lottery_count = lottery_count
        self.win_count = win_count
        self.win_rate = '0.00'
        if self.lottery_count:
            self.win_rate = '%.2f' % (win_count / lottery_count)

    def __str__(self):
        return ','.join(['%s:%s' % item for item in self.__dict__.items()])

class StatisticAwardInfo(object):
    def __init__(self, daily_awards):
        self.attend_total_count = 0
        self.lottery_total_count = 0
        self.win_total_count = 0
        self.total_win_rate = '0.00'
        self.daily_awards = daily_awards
        for daily_award in daily_awards:
            self.attend_total_count += daily_award.attend_count
            self.lottery_total_count += daily_award.lottery_count
            self.win_total_count += daily_award.win_count
            if self.lottery_total_count:
                self.total_win_rate = '%.2f' % (self.win_total_count/self.lottery_total_count)

    def __str__(self):
        return ','.join(['%s:%s' % item for item in self.__dict__.items()])

class CheckPointAward(object):
    def __init__(self, check_point: RaceGameCheckPoint, award_static: StatisticAwardInfo):
        self.check_point = check_point
        self.award_static = award_static

    def __str__(self):
        return ','.join(['%s:%s' % item for item in self.__dict__.items()])

def get_date_range(start_date):
    """
    获取活动开始到至今的时间段
    :param start_date:
    :return:
    """
    date_list = []
    end_date = datetime.datetime.now()
    while start_date <= end_date:
        date_str = start_date.strftime("%Y%m%d")
        date_list.append(date_str)
        start_date += datetime.timedelta(days=1)
    return date_list

def statistic_award_of_race(race_cid, daily_codes):
    """
    该活动下每个关卡参与人数、抽奖人数、中奖人数记录
    :param race_cid:
    :return:
    """
    check_point_list = RaceGameCheckPoint.sync_find({"race_cid": race_cid}).to_list(None)
    result = []
    check_point_list.sort(key=lambda checkpoint: checkpoint.index)
    for check_point in check_point_list:
        print("统计", check_point.alias, check_point.cid)
        statistic_award_info = statistic_award_info_of_check_point(check_point.cid, daily_codes)
        result.append(CheckPointAward(check_point, statistic_award_info))
        print(statistic_award_info)
    # check_point_sort = sorted(check_point_list,key=lambda check_point: check_point.index)
    # check_point_alias = [x.alias for x in check_point_sort]
    # export_to_excel(result, check_point_alias)
    return result

def statistic_award_info_of_check_point(check_point_cid: str, daily_codes: list):
    """
    关卡的统计信息
    :param check_point_cid:
    :param daily_codes:
    :return:
    """
    daily_awards = []
    for daily_code in daily_codes:
        daily_award = statistic_daily_award_of_check_point(check_point_cid, daily_code)
        daily_awards.append(daily_award)
    return StatisticAwardInfo(daily_awards)

def statistic_daily_award_of_check_point(check_point_cid: str, daily_code):
    """
    统计每一关每天参与人数、抽奖人数、中奖人数
    :param check_point_cid: 关卡cid
    :return:
    """
    # print("正在统计关卡:", check_point.alias, check_point.cid)
    match = {'check_point_cid': check_point_cid, 'record_flag': 1}
    red_match = {'checkpoint_cid': check_point_cid}
    s_date = str2datetime(daily_code, date_format='%Y%m%d').replace(hour=0, minute=0, second=0)
    e_date = s_date + datetime.timedelta(days=1)
    match['fight_datetime'] = {'$gte': s_date, '$lt': e_date}
    red_match['draw_dt'] = {'$gte': s_date, '$lt': e_date}
    # 参与人数
    attend_member = MemberCheckPointHistory.sync_distinct("member_cid", match)
    attend_count = len(attend_member)
    # 当前关卡的红包
    current_checkpoint_reds = RedPacketBox.sync_find(red_match, read_preference=ReadPreference.PRIMARY).batch_size(2000)
    lottery_count = 0
    win_count = 0
    for current_checkpoint_red in current_checkpoint_reds:
        lottery_count += 1
        if current_checkpoint_red.award_cid:
            win_count += 1
    daily_award = DailyAward(daily_code, attend_count, lottery_count, win_count)
    # print(check_point_cid, daily_award)
    return daily_award

def export_to_excel(race_cid):
    """
    excel导出
    :param race_cid:
    :return:
    """
    race = Race.sync_find_one({"cid": race_cid})
    daily_codes = get_date_range(race.start_datetime)
    race_awards = statistic_award_of_race(race_cid, daily_codes)
    daily_code = format(datetime.datetime.now(),'%Y%m%d')
    workbook = xlsxwriter.Workbook('{}关卡红包情况_{}.xlsx'.format(race.title,daily_code))
    sheet = workbook.add_worksheet(race.title)
    # excel行名
    second_row_num = 4
    sheet.merge_range(0, 0, 1, 0, '关卡名')
    for index, daily_code in enumerate(daily_codes):
        start_col_index = index * second_row_num + 1
        sheet.merge_range(0, start_col_index, 0, start_col_index + second_row_num - 1, daily_code)
        sheet.write_string(1, start_col_index, '参与人次')
        sheet.write_string(1, start_col_index + 1, '抽奖人数')
        sheet.write_string(1, start_col_index + 2, '中奖人数')
        sheet.write_string(1, start_col_index + 3, '中奖率')
        if index == len(daily_codes) - 1:
            total_col_index = start_col_index + 3
            sheet.merge_range(0, total_col_index, 0, total_col_index + second_row_num - 1, "总计")
            sheet.write_string(1, total_col_index, '参与人次')
            sheet.write_string(1, total_col_index + 1, '抽奖人数')
            sheet.write_string(1, total_col_index + 2, '中奖人数')
            sheet.write_string(1, start_col_index + 3, '中奖率')

    for row_index, check_point_award in enumerate(race_awards):
        name = check_point_award.check_point.alias
        daily_awards = check_point_award.award_static.daily_awards
        row_num = row_index + 2
        sheet.write_string(row_num, 0, name)
        if daily_awards and len(daily_awards) > 0:
            for col_index, daily_award in enumerate(daily_awards):
                col_num = col_index * second_row_num + 1
                sheet.write_number(row_num, col_num, daily_award.attend_count)
                sheet.write_number(row_num, col_num + 1, daily_award.lottery_count)
                sheet.write_number(row_num, col_num + 2, daily_award.win_count)
                sheet.write_string(row_num, col_num + 3, daily_award.win_rate)
                if col_index == len(daily_awards) - 1:
                    sheet.write_number(row_num, col_num + 3, check_point_award.award_static.attend_total_count)
                    sheet.write_number(row_num, col_num + 4, check_point_award.award_static.lottery_total_count)
                    sheet.write_number(row_num, col_num + 5, check_point_award.award_static.win_total_count)
                    sheet.write_string(row_num, col_num + 6, check_point_award.award_static.total_win_rate)
    _last_row = len(race_awards) + 2
    _last_col = (len(daily_codes) + 1) * 3
    sheet.write_string(_last_row, 0, '总计')
    for i in range(1, _last_col + 1):
        col_name = convert(i)
        formula = "=SUM({}{}:{}{})".format(col_name, 3, col_name, _last_row)
        sheet.write_formula(_last_row, i, formula)

    workbook.close()

class Test(BaseModel):
    s_date = DateTimeField(default=datetime.datetime.now())
    e_date = DateTimeField(default=datetime.datetime.now())

if __name__ == '__main__':
    # 安徽活动
    # export_to_excel('3040737C97F7C7669B04BC39A660065D')
    # 六安活动
    export_to_excel('CA755167DEA9AA89650D11C10FAA5413')
    # statistic_daily_award_of_check_point("54B20BEDA100A9925E2E86347F42F0D2",'20190520')


# -*- coding: utf-8 -*-
import datetime
import logging

from dateutil.relativedelta import relativedelta
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator
from django.db import models
from django.utils.translation import ugettext_lazy as _
from mptt.models import MPTTModel, TreeForeignKey

from ralph.accounts.models import Team
from ralph.admin.autocomplete import AutocompleteTooltipMixin
from ralph.assets.models.base import BaseObject
from ralph.assets.models.choices import (
    ModelVisualizationLayout,
    ObjectModelType
)
from ralph.lib.custom_fields.models import (
    CustomFieldMeta,
    WithCustomFieldsMixin
)
from ralph.lib.mixins.fields import (
    NullableCharField,
    NullableCharFieldWithAutoStrip
)
from ralph.lib.mixins.models import (
    AdminAbsoluteUrlMixin,
    NamedMixin,
    PriceMixin,
    TimeStampMixin
)
from ralph.lib.permissions import PermByFieldMixin
from ralph.lib.permissions.models import PermissionsBase

logger = logging.getLogger(__name__)

class AssetHolder(
    AdminAbsoluteUrlMixin,
    NamedMixin.NonUnique,
    TimeStampMixin,
    models.Model
):
    pass

class BusinessSegment(AdminAbsoluteUrlMixin, NamedMixin, models.Model):
    pass

class ProfitCenter(AdminAbsoluteUrlMixin, NamedMixin, models.Model):
    description = models.TextField(blank=True)

class Environment(
    AdminAbsoluteUrlMixin, NamedMixin, TimeStampMixin, models.Model
):
    pass

class Service(
    PermByFieldMixin,
    AdminAbsoluteUrlMixin,
    NamedMixin,
    TimeStampMixin,
    models.Model
):
    # Fixme: let's do service catalog replacement from that
    _allow_in_dashboard = True

    active = models.BooleanField(default=True)
    uid = NullableCharField(max_length=40, unique=True, blank=True, null=True)
    profit_center = models.ForeignKey(ProfitCenter, null=True, blank=True)
    business_segment = models.ForeignKey(BusinessSegment, null=True, blank=True)
    cost_center = models.CharField(max_length=100, blank=True)
    environments = models.ManyToManyField(
        'Environment', through='ServiceEnvironment'
    )
    business_owners = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name='services_business_owner',
        blank=True,
    )
    technical_owners = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name='services_technical_owner',
        blank=True,
    )
    support_team = models.ForeignKey(
        Team, null=True, blank=True, related_name='services',
    )

    def __str__(self):
        return '{}'.format(self.name)

    @classmethod
    def get_autocomplete_queryset(cls):
        return cls._default_manager.filter(active=True)

class ServiceEnvironment(
    AdminAbsoluteUrlMixin,
    AutocompleteTooltipMixin,
    BaseObject
):
    _allow_in_dashboard = True
    service = models.ForeignKey(Service)
    environment = models.ForeignKey(Environment)

    autocomplete_tooltip_fields = [
        'service__business_owners',
        'service__technical_owners',
        'service__support_team',
    ]

    def __str__(self):
        return '{} - {}'.format(self.service.name, self.environment.name)

    class Meta:
        unique_together = ('service', 'environment')
        ordering = ('service__name', 'environment__name')

    @property
    def service_name(self):
        return self.service.name

    @property
    def service_uid(self):
        return self.service.uid

    @property
    def environment_name(self):
        return self.environment.name

    @classmethod
    def get_autocomplete_queryset(cls):
        return cls._default_manager.filter(service__active=True)

class ManufacturerKind(AdminAbsoluteUrlMixin, NamedMixin, models.Model):
    pass

class Manufacturer(
    AdminAbsoluteUrlMixin,
    NamedMixin,
    TimeStampMixin,
    models.Model
):
    _allow_in_dashboard = True
    manufacturer_kind = models.ForeignKey(
        ManufacturerKind, verbose_name=_('manufacturer kind'),
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
    )

AssetModelMeta = type('AssetModelMeta', (CustomFieldMeta, PermissionsBase), {})

class AssetModel(
    PermByFieldMixin,
    NamedMixin.NonUnique,
    TimeStampMixin,
    AdminAbsoluteUrlMixin,
    WithCustomFieldsMixin,
    models.Model,
    metaclass=AssetModelMeta
):
    # TODO: should type be determined based on category?
    _allow_in_dashboard = True

    type = models.PositiveIntegerField(
        verbose_name=_('type'), choices=ObjectModelType(),
    )
    manufacturer = models.ForeignKey(
        Manufacturer, on_delete=models.PROTECT, blank=True, null=True
    )
    category = TreeForeignKey(
        'Category', null=True, related_name='models'
    )
    power_consumption = models.PositiveIntegerField(
        verbose_name=_("Power consumption"),
        default=0,
    )
    height_of_device = models.FloatField(
        verbose_name=_("Height of device"),
        default=0,
        validators=[MinValueValidator(0)],
    )
    cores_count = models.PositiveIntegerField(
        verbose_name=_("Cores count"),
        default=0,
    )
    visualization_layout_front = models.PositiveIntegerField(
        verbose_name=_("visualization layout of front side"),
        choices=ModelVisualizationLayout(),
        default=ModelVisualizationLayout().na.id,
        blank=True,
    )
    visualization_layout_back = models.PositiveIntegerField(
        verbose_name=_("visualization layout of back side"),
        choices=ModelVisualizationLayout(),
        default=ModelVisualizationLayout().na.id,
        blank=True,
    )
    # Used in the visualization Data Center as is_blade
    has_parent = models.BooleanField(default=False)

    class Meta:
        verbose_name = _('model')
        verbose_name_plural = _('models')

    def __str__(self):
        if self.category_id:
            return '[{}] {} {}'.format(
                self.category, self.manufacturer, self.name
            )
        else:
            return '{} {}'.format(
                self.manufacturer, self.name
            )

    def _get_layout_class(self, field):
        item = ModelVisualizationLayout.from_id(field)
        return getattr(item, 'css_class', '')

    def get_front_layout_class(self):
        return self._get_layout_class(self.visualization_layout_front)

    def get_back_layout_class(self):
        return self._get_layout_class(self.visualization_layout_back)

class Category(
    AdminAbsoluteUrlMixin,
    MPTTModel,
    NamedMixin.NonUnique,
    TimeStampMixin,
    models.Model
):
    _allow_in_dashboard = True

    code = models.CharField(max_length=4, blank=True, default='')
    parent = TreeForeignKey(
        'self',
        null=True,
        blank=True,
        related_name='children',
        db_index=True
    )
    imei_required = models.BooleanField(default=False)
    allow_deployment = models.BooleanField(default=False)
    show_buyout_date = models.BooleanField(default=False)
    default_depreciation_rate = models.DecimalField(
        blank=True,
        decimal_places=2,
        default=settings.DEFAULT_DEPRECIATION_RATE,
        help_text=_(
            'This value is in percentage.'
            ' For example value: "100" means it depreciates during a year.'
            ' Value: "25" means it depreciates during 4 years, and so on... .'
        ),
        max_digits=5,
    )

    class Meta:
        verbose_name = _('category')
        verbose_name_plural = _('categories')

    class MPTTMeta:
        order_insertion_by = ['name']

    def __str__(self):
        return self.name

    def get_default_depreciation_rate(self, category=None):
        if category is None:
            category = self

        if category.default_depreciation_rate:
            return category.default_depreciation_rate
        elif category.parent:
            return self.get_default_depreciation_rate(category.parent)
        return 0

class AssetLastHostname(models.Model):
    prefix = models.CharField(max_length=30, db_index=True)
    counter = models.PositiveIntegerField(default=1)
    postfix = models.CharField(max_length=30, db_index=True)

    class Meta:
        unique_together = ('prefix', 'postfix')

    def formatted_hostname(self, fill=5):
        return '{prefix}{counter:0{fill}}{postfix}'.format(
            prefix=self.prefix,
            counter=int(self.counter),
            fill=fill,
            postfix=self.postfix,
        )

    @classmethod
    # TODO: select_for_update
    def increment_hostname(cls, prefix, postfix=''):
        obj, created = cls.objects.get_or_create(
            prefix=prefix,
            postfix=postfix,
        )
        if not created:
            # F() avoid race condition problem
            obj.counter = models.F('counter') + 1
            obj.save()
            return cls.objects.get(pk=obj.pk)
        else:
            return obj

    @classmethod
    def get_next_free_hostname(
        cls, prefix, postfix, fill=5, availability_checker=None, _counter=1
    ):
        try:
            last_hostname = cls.objects.get(prefix=prefix, postfix=postfix)
        except cls.DoesNotExist:
            last_hostname = cls(prefix=prefix, postfix=postfix, counter=0)

        last_hostname.counter += _counter
        hostname = last_hostname.formatted_hostname(fill=fill)

        if availability_checker is None or availability_checker(hostname):
            return hostname
        else:
            return cls.get_next_free_hostname(
                prefix, postfix, fill, availability_checker, _counter + 1
            )

    def __str__(self):
        return self.formatted_hostname()

class BudgetInfo(
    AdminAbsoluteUrlMixin,
    NamedMixin,
    TimeStampMixin,
    models.Model
):
    class Meta:
        verbose_name = _('Budget info')
        verbose_name_plural = _('Budgets info')

    def __str__(self):
        return self.name

class Asset(AdminAbsoluteUrlMixin, PriceMixin, BaseObject):
    model = models.ForeignKey(
        AssetModel, related_name='assets', on_delete=models.PROTECT
    )
    # TODO: unify hostname for DCA, VirtualServer, Cluster and CloudHost
    # (use another model?)
    hostname = NullableCharFieldWithAutoStrip(
        blank=True,
        default=None,
        max_length=255,
        null=True,
        verbose_name=_('hostname'),  # TODO: unique
    )
    sn = NullableCharField(
        blank=True,
        max_length=200,
        null=True,
        verbose_name=_('SN'),
        unique=True,
    )
    barcode = NullableCharField(
        blank=True,
        default=None,
        max_length=200,
        null=True,
        unique=True,
        verbose_name=_('barcode')
    )
    niw = NullableCharField(
        blank=True,
        default=None,
        max_length=200,
        null=True,
        verbose_name=_('inventory number'),
    )
    required_support = models.BooleanField(default=False)

    order_no = models.CharField(
        verbose_name=_('order number'),
        blank=True,
        max_length=50,
        null=True,
    )
    invoice_no = models.CharField(
        verbose_name=_('invoice number'),
        blank=True,
        db_index=True,
        max_length=128,
        null=True,
    )
    invoice_date = models.DateField(blank=True, null=True)
    # to discuss: foreign key?
    provider = models.CharField(
        blank=True,
        max_length=100,
        null=True,
    )
    depreciation_rate = models.DecimalField(
        blank=True,
        decimal_places=2,
        default=settings.DEFAULT_DEPRECIATION_RATE,
        help_text=_(
            'This value is in percentage.'
            ' For example value: "100" means it depreciates during a year.'
            ' Value: "25" means it depreciates during 4 years, and so on... .'
        ),
        max_digits=5,
    )
    force_depreciation = models.BooleanField(
        help_text=(
            'Check if you no longer want to bill for this asset'
        ),
        default=False,
    )
    depreciation_end_date = models.DateField(blank=True, null=True)
    buyout_date = models.DateField(blank=True, null=True, db_index=True)
    task_url = models.URLField(
        blank=True,
        help_text=('External workflow system URL'),
        max_length=2048,
        null=True,
    )
    budget_info = models.ForeignKey(
        BudgetInfo,
        blank=True,
        default=None,
        null=True,
        on_delete=models.PROTECT,
    )
    property_of = models.ForeignKey(
        AssetHolder,
        on_delete=models.PROTECT,
        null=True,
        blank=True,
    )
    start_usage = models.DateField(
        blank=True,
        null=True,
        help_text=(
            'Fill it if date of first usage is different then date of creation'
        )
    )

    def __str__(self):
        return self.hostname or ''

    def calculate_buyout_date(self):
        """
        Get buyout date.

        Calculate buyout date:
         invoice_date + buyout months offset by category

        Returns:
            Buyout date
        """
        if (
            not self.model
            or not self.model.category
            or not self.model.category.show_buyout_date
        ):
            return None

        category = self.model.category  # type: Category
        months = settings.ASSET_BUYOUT_CATEGORY_TO_MONTHS.get(
            str(category.pk), None
        )
        if self.invoice_date and months:
            return self.invoice_date + relativedelta(months=months)
        else:
            return None

    def get_depreciation_months(self):
        return int(
            (1 / (self.depreciation_rate / 100) * 12)
            if self.depreciation_rate else 0
        )

    def is_depreciated(self, date=None):
        date = date or datetime.date.today()
        if self.force_depreciation or not self.invoice_date:
            return True
        if self.depreciation_end_date:
            deprecation_date = self.deprecation_end_date
        else:
            deprecation_date = self.invoice_date + relativedelta(
                months=self.get_depreciation_months(),
            )
        return deprecation_date < date

    def get_depreciated_months(self):
        # DEPRECATED
        # BACKWARD_COMPATIBILITY
        return self.get_depreciation_months()

    def is_deprecated(self, date=None):
        # DEPRECATED
        # BACKWARD_COMPATIBILITY
        return self.is_depreciated()

    def _liquidated_at(self, date):
        liquidated_history = self.get_history().filter(
            new_value='liquidated',
            field_name='status',
        ).order_by('-date')[:1]
        return liquidated_history and liquidated_history[0].date.date() <= date

    def clean(self):
        if not self.sn and not self.barcode:
            error_message = [_('SN or BARCODE field is required')]
            raise ValidationError(
                {
                    'sn': error_message,
                    'barcode': error_message
                }
            )

    def save(self, *args, **kwargs):
        # if you save barcode as empty string (instead of None) you could have
        # only one asset with empty barcode (because of `unique` constraint)
        # if you save barcode as None you could have many assets with empty
        # barcode (becasue `unique` constrainst is skipped)
        for unique_field in ['barcode', 'sn']:
            value = getattr(self, unique_field, None)
            if value == '':
                value = None
            setattr(self, unique_field, value)

        if not self.buyout_date:
            self.buyout_date = self.calculate_buyout_date()
        return super(Asset, self).save(*args, **kwargs)


# Copyright (c) Hoshmand. All rights reserved.
#
# https://twitter.com/hoshmandctf
# https://github.com/hoshmandctf

import datetime

def count_sundays_on_first():
    count = 0
    # Iterate over the years in the twentieth century
    for year in range(1901, 2001):
        # Iterate over the months
        for month in range(1, 13):
            # Check if the first day of the month is a Sunday (weekday number 6)
            if datetime.date(year, month, 1).weekday() == 6:
                count += 1

    return count

# Count the number of Sundays that fell on the first of the month
sunday_count = count_sundays_on_first()
print("The number of Sundays that fell on the first of the month during the twentieth century is:", sunday_count)


import logging
import numpy as np
import matplotlib.pyplot as plt
from sktensor import dtensor, cp_als

# Set logging to DEBUG to see CP-ALS information
logging.basicConfig(level=logging.DEBUG)

# Load Matlab data and convert it to dense tensor format
# mat = loadmat('/Users/monty/Julia/dNTF.py/brod.mat')

X = np.zeros((2, 10, 5))
X[:,0:2,0]=1
X[:,2:4,1]=1
X[:,4:6,2]=1
X[:,6:8,3]=1
X[:,8:10,4]=1

T = dtensor(X)

# Decompose tensor using CP-ALS
P, fit, itr, exectimes = cp_als(T, 5)

T_est = np.einsum('az,bz,cz->abc', P.U[0], P.U[1], P.U[2])

plt.imshow(T_est[:,:,0]);
plt.colorbar()
plt.show()


import os
import pprint
import re
import subprocess
import sys
import unittest
from unittest.util import three_way_cmp

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
import time

DEBUG = 'PRODUCTION' not in os.environ

SRC_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PORT = '5501'

class SimpleTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print('DEBUG = {}'.format(DEBUG), file=sys.stderr)
        cls.server = subprocess.Popen(
            ['python3', '-m', 'http.server', PORT], cwd=SRC_PATH, stderr=subprocess.DEVNULL)

        desired_capabilities = dict(
            {'loggingPrefs': {'browser': 'ALL'}}, **DesiredCapabilities.CHROME)

        if DEBUG:
            cls.driver = webdriver.Chrome(
                executable_path="D:\ChromeDriver\chromedriver.exe", desired_capabilities=desired_capabilities)
        else:
            cls.driver = webdriver.Remote(
                command_executor='http://localhost:4444/wd/hub',
                desired_capabilities=desired_capabilities
            )

        cls.driver.implicitly_wait(1)
        cls.driver.get('http://127.0.0.1:' + PORT + '/index.html')

    def test_position_logo(self):
        container = self.driver.find_element_by_class_name('logo')
        position = str(container.value_of_css_property(
            'position')).replace(' ', '')
        result = ["absolute"]
        self.assertIn(position, result)

    def test_top_logo(self):
        container = self.driver.find_element_by_class_name('logo')
        top = str(container.value_of_css_property(
            'top')).replace(' ', '')
        result = ["170px"]
        self.assertIn(top, result)

    def test_position_tag(self):
        tags = self.driver.find_elements_by_class_name('tag')
        result = ["absolute"]
        for tag in tags:
            value = str(tag.value_of_css_property(
                'position')).replace(' ', '')
            self.assertIn(value, result)

    def test_padding_left_tag(self):
        tags = self.driver.find_elements_by_class_name('tag')
        result = ["30px"]
        for tag in tags:
            top = str(tag.value_of_css_property(
                'padding-left')).replace(' ', '')
            self.assertIn(top, result)

    def test_font_size_tag(self):
        tags = self.driver.find_elements_by_class_name('tag')
        result = ["108px"]
        for tag in tags:
            top = str(tag.value_of_css_property(
                'font-size')).replace(' ', '')
            self.assertIn(top, result)

    def test_font_weight_tag(self):
        tags = self.driver.find_elements_by_class_name('tag')
        result = ["700"]
        for tag in tags:
            value = str(tag.value_of_css_property(
                'font-weight')).replace(' ', '')
            self.assertIn(value, result)

    def test_letter_spacing_tag(self):
        tags = self.driver.find_elements_by_class_name('tag')
        result = ["-7px"]
        for tag in tags:
            value = str(tag.value_of_css_property(
                'letter-spacing')).replace(' ', '')
            self.assertIn(value, result)

    def test_transform_tag_1(self):
        tag = self.driver.find_element_by_css_selector(".tag:nth-child(1)")
        result = ["rotate(-90deg)", "rotate(270deg)",
                  "matrix(6.12323e-17,-1,1,6.12323e-17,0,0)"]
        value = str(tag.value_of_css_property(
            'transform')).replace(' ', '')
        self.assertIn(value, result)

    def test_transform_tag_2(self):
        tag = self.driver.find_element_by_css_selector(".tag:nth-child(2)")
        result = ["rotate(-18deg)", "rotate(342deg)",
                  "matrix(0.951057,-0.309017,0.309017,0.951057,0,0)"]
        value = str(tag.value_of_css_property(
            'transform')).replace(' ', '')
        self.assertIn(value, result)

    def test_transform_tag_3(self):
        tag = self.driver.find_element_by_css_selector(".tag:nth-child(3)")
        result = ["rotate(54deg)", "rotate(306deg)",
                  "matrix(0.587785,0.809017,-0.809017,0.587785,0,0)"]
        value = str(tag.value_of_css_property(
            'transform')).replace(' ', '')
        self.assertIn(value, result)

    def test_transform_tag_4(self):
        tag = self.driver.find_element_by_css_selector(".tag:nth-child(4)")
        result = ["rotate(126deg)", "rotate(-234deg)",
                  "matrix(-0.587785,0.809017,-0.809017,-0.587785,0,0)"]
        value = str(tag.value_of_css_property(
            'transform')).replace(' ', '')
        self.assertIn(value, result)

    def test_transform_tag_5(self):
        tag = self.driver.find_element_by_css_selector(".tag:nth-child(5)")
        result = ["rotate(198deg)", "rotate(-162deg)",
                  "matrix(-0.951057,-0.309017,0.309017,-0.951057,0,0)"]
        value = str(tag.value_of_css_property(
            'transform')).replace(' ', '')
        self.assertIn(value, result)

    @classmethod
    def tearDownClass(cls):
        console_logs = []
        for log_item in cls.driver.get_log('browser'):
            if log_item.get('source') == 'network' and 'favicon.ico - Failed to load' in log_item.get('message'):
                continue
            console_logs.append(log_item)
        if console_logs:
            print('\n--------------------\nBROWSER CONSOLE LOG:\n-----',
                  file=sys.stderr)
            for log_item in console_logs[:10]:
                log_item['message'] = log_item['message'][:200]
                print(pprint.pformat(log_item), '-----',
                      sep='\n', file=sys.stderr)
                cls.server.kill()
                cls.driver.close()

if __name__ == '__main__':
    unittest.main()


import textwrap
import unittest

from trac.mimeview.patch import PatchRenderer
from trac.test import EnvironmentStub, MockRequest, makeSuite
from trac.web.api import RequestDone
from trac.wiki.web_api import WikiRenderer

class WikiRendererTestCase(unittest.TestCase):

    def setUp(self):
        self.env = EnvironmentStub()
        self.mod = WikiRenderer(self.env)

    def test_load_stylesheet(self):
        text = textwrap.dedent("""\
            {{{#!text/x-diff
            --- a/file.txt  2014-11-13 01:16:06 +0000
            +++ b/file.txt  2014-11-13 01:16:06 +0000
            @@ -1 +1 @@
            -old line
            +new line
            }}}
            """)
        req = MockRequest(self.env, method='POST', path_info='/wiki_render',
                          args={'id': 'WikiStart', 'text': text})

        self.assertTrue(self.mod.match_request(req))
        try:
            self.mod.process_request(req)
            self.fail('RequestDone not raised')
        except RequestDone:
            output = req.response_sent.getvalue()
            self.assertIn(b'
', output)
            self.assertIn(b'<table class="trac-diff inline"', output)
            self.assertIn(b'jQuery.loadStyleSheet("'
                          b'/trac.cgi/chrome/common/css/diff.css"', output)

def test_suite():
    return makeSuite(WikiRendererTestCase)

if __name__ == '__main__':
    unittest.main(defaultTest='test_suite')


import data
import views
import embeds

from discord import Color, Embed, Intents
from discord.ext import commands

import config

intents = Intents.default()
intents.message_content = True
bot = commands.Bot(intents=intents, command_prefix=config.command_prefix)

def get_query_lang(query):
    lang = 'kr'
    for l in config.langs:
        tag = 'lang=%s' % l
        if tag in query:
            query, lang = query.replace(tag, '').strip(), l
    return query, lang

@bot.event
async def on_ready():
    print('Logged in as:', bot.user.name, bot.user.id)

# direct bot commands
@bot.command()
async def skills(ctx, *query):
    query, lang = get_query_lang(' '.join(query or []))
    char = data.get(query, lang=lang)
    if char:
        await ctx.send(embed=embeds.char_embed(char, lang), view=views.CharView(char, lang))
    else:
        await ctx.send('Character not found!')

@bot.command()
async def search(ctx, *query):
    query, lang = get_query_lang(' '.join(query or []))
    found = data.search(query, lang=lang)
    if len(found) > 0:
        await ctx.send(embed=embeds.list_embed(query, found, 1, lang=lang), view=views.PaginationView())
    else:
        await ctx.send('No matches found!')

@bot.command()
async def buff(ctx, *query):
    query, lang = get_query_lang(' '.join(query or []))
    buff = data.buff(query, lang=lang)
    if buff:
        await ctx.send(embed=embeds.buff_embed(buff, lang))
    else:
        await ctx.send('Buff not found!')

@bot.command()
async def buffs(ctx, *query):
    query, lang = get_query_lang(' '.join(query or []))
    found = data.buffs(query, lang=lang)
    if len(found) > 0:
        await ctx.send(embed=embeds.buffs_embed(query, found, 1, lang=lang), view=views.PaginationView())
    else:
        await ctx.send('No matches found!')

@bot.command()
async def raw(ctx, *query):
    query, lang = get_query_lang(' '.join(query or []))
    selected_skills, ignited = [], False

    for skill in config.skills:
        tag = 'skill=%s' % skill
        if tag in query:
            selected_skills.append(skill)
            query = query.replace(tag, '').strip()
    if 'ignite' in query or 'ignited' in query:
        ignited = True
        query = query.replace('ignite', '').strip().replace('ignited', '').strip()

    char = data.get(query, lang=lang)
    if char:
        just_char = dict((key, val) for key, val in char.items() if key != 'skills' and key != 'skills_ignited')
        await ctx.author.send('```\n%s\n```' % data.char_raw(just_char))

        for skill in selected_skills:
            just_skill = char['skills' if not ignited else 'skills_ignited']
            just_skill = just_skill[skill] if skill in just_skill else {}
            just_skill['ignited'] = ignited

            await ctx.author.send('```\n%s\n```' % data.char_raw({skill: dict((key, val if key != 'text' else val.split('\\')) for key, val in just_skill.items())}))
    else:
        await ctx.author.send('Character not found!')

@bot.command()
async def dump(ctx, *query):
    query, lang = get_query_lang(' '.join(query or []))
    dump = data.dump(query, lang=lang)
    if dump:
        await ctx.author.send('```\n%s\n```' % data.char_raw(dump))
    else:
        await ctx.author.send('Dump data not found!')

@bot.command()
async def ping(ctx):
    await ctx.send('pong')

bot.run(token=config.token)


"""
Problem:
--------

  You want to write a function that accepts any number of input arguments.

Solution:
---------

  To write a function that accepts any number of positional arguments, use a
* argument. For example:
"""

def avg(first, *rest):
    return (first + sum(rest)/ (1 + len(rest)))

"""
  In this example, rest is a tuple of all the extra positional arguments passed.
The code treats it as a sequence in performing subsequent calculations.
"""

"""
  To accept any number of keyword arguments, use an argument that starts with
**. For example:
"""

import html

def make_element(name, value, **attrs):
    keyvals = [' %s="%s"' % item for item in attrs.items()]
    attr_str = "".join(keyvals)
    element = '<{name}{attrs}> <{value}></{name}>'.format(
        name=name,
        attrs=attr_str,
        value=html.escape(value))

    return element

"""
  With this function, all of the posistional arguments are placed into a
tuple args, and all of the keyword arguments are placed into a dictionary
kwargs
"""

def anyargs(*args, **kwargs):
    print(args)
    print(kwargs)

if __name__ == "__main__":
    print(avg(1,2))
    print(avg(1,2,3,4))
    test = make_element("item", "Albatross", size="6", quantity=6)
    print(test)
    anyargs(1,2,3,4,3,4, test=True, name="Marcus", age=26)


from turtle import Turtle

class Scoreboard(Turtle):
    def __init__(self):
        super().__init__()
        self.color("white")
        self.penup()
        self.hideturtle()
        self.score = 0
        self.update_score()

    def update_score(self):
        self.clear()
        self.goto(300, 260)
        self.write(f"Score : {self.score}", align="center", font=("Courier", 20, "normal"))

    def add_score(self, i):
        self.score += i
        self.update_score()

    def flash_gameover_screen(self, win):
        self.goto(0, 0)
        if win:
            self.color("SeaGreen1")
            self.write(f"You Completed the Game !\nYour score : {self.score}", align="center", font=("Courier", 30, "normal"))
        else:
            self.color("red1")
            self.write(f"You Lost !\nYour score : {self.score}", align="center", font=("Courier", 50, "normal"))


import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QPushButton, QTextEdit, QVBoxLayout, QLabel
from PyQt5.QtCore import QProcess
from datetime import datetime
import os

class CommandApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        # create widgets
        self.cmd_label = QLabel("Add Command:")
        self.command_line = QLineEdit()
        self.run_button = QPushButton("Run")
        self.output_box = QTextEdit()
        self.path_label = QLabel("Folder path:")
        self.path_line = QLineEdit()

        # layout widgets
        layout = QVBoxLayout()
        layout.addWidget(self.cmd_label)
        layout.addWidget(self.command_line)
        layout.addWidget(self.path_label)
        layout.addWidget(self.path_line)
        layout.addWidget(self.run_button)
        layout.addWidget(self.output_box)
        self.setLayout(layout)

        # connect signals and slots
        self.run_button.clicked.connect(self.run_command)
        self.show()

    def run_command(self):
        # get the command and the folder path from the line edits
        command = self.command_line.text()
        folder_path = self.path_line.text()
        if command and folder_path:
            # create a QProcess object
            self.process = QProcess()
            # connect the signals for output and error
            self.process.readyReadStandardOutput.connect(self.read_output)
            self.process.readyReadStandardError.connect(self.read_error)
            # start the process with the given command
            self.process.start(command)
            # create a file name with the command and the current date and time
            file_name = f"{command.replace(' ', '_')}_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.txt"
            # open the file in append mode
            self.file = open(os.path.join(folder_path, file_name), "a")

    def read_output(self):
        # read the standard output from the process
        output = self.process.readAllStandardOutput().data().decode()
        # append the output to the text box and the file
        self.output_box.append(output)
        self.file.write(output)

    def read_error(self):
        # read the standard error from the process
        error = self.process.readAllStandardError().data().decode()
        # append the error to the text box and the file
        self.output_box.append(error)
        self.file.write(error)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = CommandApp()
    sys.exit(app.exec_())