import zipfile
import csv
import io
import datetime
from collections import defaultdict, namedtuple

from ilgtfs import StopTime, RouteStory, RouteStoryStop, ExtendedGTFS
import geo

def progenum(iterable, freq):
    i = 0
    for i, r in enumerate(iterable):
        yield r
        if i % freq == 0:
            print("  ", i, datetime.datetime.now())
    print('Total number of iterations: %d' % i)

# Trip stories are a list of stops with arrival and departure time as offset from the beginning of the trip
# Trip stories are build from stop times, but:
#   you can see which trips have the same story
#   the trip stories file is much smaller than the stop times file
# trip_to_trip_story  is in fact a 1-to-1 table to trip (could have added the fields to trips.txt)
def build_route_stories(gtfs: ExtendedGTFS):
    trip_id_to_stop_times_csv_records = defaultdict(lambda: [])
    trip_id_to_route_story_id = {}
    trip_id_to_start_time = {}
    route_stories = {}

    def read_trip_id_to_stop_times():
        """Returns dictionary from trip_id to a list of csv records"""
        with zipfile.ZipFile(gtfs.filename) as z:
            with z.open('stop_times.txt') as f:
                reader = csv.DictReader(io.TextIOWrapper(f, 'utf8'))
                print("Reading stop_times file")
                for record in progenum(reader, 500000):
                    trip_id_to_stop_times_csv_records[record['trip_id']].append(record)
                print("Total number of trips in stop times file %d " % len(trip_id_to_stop_times_csv_records))

    def find_missing_trips():
        missing = [trip_id for trip_id in gtfs.trips if trip_id not in trip_id_to_stop_times_csv_records]
        if len(missing) > 0:
            print("%s trips have no route story" % len(missing))
            print("trips with no route stories are: %s" % missing)

    def sort_and_verify_csv_records():
        print("Sorting and verifying csv records")
        bad_trip_sequences = set()
        for trip_id, csv_records in progenum(trip_id_to_stop_times_csv_records.items(), 10000):
            csv_records.sort(key=lambda r: int(r['stop_sequence']))
            if csv_records[0]['stop_sequence'] != '1' or int(csv_records[-1]['stop_sequence']) != len(csv_records):
                bad_trip_sequences.add(trip_id)
        if len(bad_trip_sequences) > 0:
            print("There are %d trips with bad sequences of stops in route story" % len(bad_trip_sequences))
            for trip_id in bad_trip_sequences:
                print("  Trip %s, sequence %s" % (trip_id, trip_id_to_stop_times_csv_records[trip_id]))
                del (trip_id_to_stop_times_csv_records[trip_id])

    def build():
        route_story_to_id = {}
        print("Building route stories")
        for trip_id, csv_records in progenum(trip_id_to_stop_times_csv_records.items(), 10000):
            # get the formatted start time from the first record; we will print it to the trips file
            trip_id_to_start_time[trip_id] = csv_records[0]['arrival_time']
            # convert to ilgtfs.StopTime objects
            gtfs_stop_times = [StopTime.from_csv(record) for record in csv_records]
            # get the start time in seconds since the start of the day
            start_time = gtfs_stop_times[0].arrival_time
            # convert the StopTime object to RouteStoryStop object; use a tuple because it's hashable
            route_story_tuple = tuple(RouteStoryStop(record.arrival_time - start_time,
                                                     record.departure_time - start_time,
                                                     record.stop_id,
                                                     record.pickup_type,
                                                     record.drop_off_type) for record in gtfs_stop_times)
            # is it a new trip story? if yes, allocate an id and write to the trip stories file
            if route_story_tuple not in route_story_to_id:
                route_story_id = len(route_story_to_id) + 1
                route_story_to_id[route_story_tuple] = route_story_id
            trip_id_to_route_story_id[trip_id] = route_story_to_id[route_story_tuple]

        # convert the route_story_tuples to RouteStory objects
        route_stories.update({route_story_id: RouteStory.from_tuple(route_story_id, route_story_tuple)
                              for route_story_tuple, route_story_id in route_story_to_id.items()})
        # add services to route_stories
        for trip_id, route_story_id in trip_id_to_route_story_id.items():
            route_stories[route_story_id].services.add(gtfs.trips[trip_id].service)

        print("Total number of route stories %d" % len(route_stories))
        print("Total number of route story stops%d" % sum(len(story.stops) for story in route_stories.values()))

    def export_route_story_stops():
        print("Exporting route story stops")
        with open(gtfs.at_path(gtfs.route_story_stops_files), 'w') as f:
            f.write("route_story_id,arrival_offset,departure_offset,stop_id,pickup_type,drop_off_type\n")
            for route_story_id, route_story in route_stories.items():
                for stop in route_story.stops:
                    f.write(','.join(str(x) for x in [route_story_id,
                                                      stop.arrival_offset,
                                                      stop.departure_offset,
                                                      stop.stop_id,
                                                      stop.pickup_type,
                                                      stop.drop_off_type]) + '\n')

    def export_route_story_services():
        print("Exporting route story services")
        with open(gtfs.at_path(gtfs.route_story_services_filename), 'w') as f:
            f.write("route_story_id,service_id\n")
            for route_story_id, route_story in route_stories.items():
                for service in route_story.services:
                    f.write('%s,%s\n' % (route_story_id, service.service_id))
        print("Route story services export done.")

    def export_full_trips():
        print("exporting %d full trips" % len(gtfs.trips))
        with open(gtfs.full_trips_filename(), 'w') as f2:
            fields = ["route_id", "service_id", "trip_id", "direction_id", "shape_id",
                      "start_time", "route_story"]
            writer = csv.DictWriter(f2, fieldnames=fields, lineterminator='\n')
            writer.writeheader()
            for trip in gtfs.trips.values():
                writer.writerow({
                    "route_id": trip.route.route_id,
                    "service_id": trip.service.service_id,
                    "trip_id": trip.trip_id,
                    "direction_id": trip.direction_id,
                    "shape_id": trip.shape_id,
                    "start_time": trip_id_to_start_time[trip.trip_id],
                    "route_story": str(trip_id_to_route_story_id[trip.trip_id])
                    if trip.trip_id in trip_id_to_route_story_id else ''
                })
        print("Trips export done.")

    gtfs.load_basic_routes()
    gtfs.load_basic_trips()
    assert gtfs.trips is not None
    read_trip_id_to_stop_times()
    sort_and_verify_csv_records()  # sort the route stories by stop sequence, and make sure they are consistent
    find_missing_trips()  # this would just print the ids of trips without route story
    build()
    export_route_story_stops()
    export_route_story_services()
    export_full_trips()
    print("Done.")

def extend_stops(gtfs):
    """Adds nearest train station, train station distance and lines numbers"""
    if gtfs.trips is None:
        gtfs.load_trips()

    if gtfs.stops is None:
        gtfs.load_basic_stops()

    def find_train_stations():
        print("Finding train stations")
        train_trips = (trip for trip in gtfs.trips.values() if trip.route.route_type == 2)
        train_trip_story_ids = set(trip.trip_story_id for trip in train_trips)
        train_station_stops = set()
        for trip_story_id in train_trip_story_ids:
            for trip_story_stop in gtfs.trip_stories[trip_story_id]:
                train_station_stops.add(trip_story_stop.stop_id)
        print("%d train stations found" % len(train_station_stops))
        return train_station_stops

    def find_distance_from_train_station(train_stations):
        train_stations_stops = (stop for stop in gtfs.stops.values() if stop.stop_id in train_stations)
        train_station_points = [(stop.stop_id, geo.GeoPoint(stop.stop_lat, stop.stop_lon))
                                for stop in train_stations_stops]

        print("finding distance from train stations")
        result = {}
        for stop in gtfs.stops.values():
            if stop.stop_id in train_stations:
                result[stop.stop_id] = (0, stop.stop_id)
            else:
                stop_point = geo.GeoPoint(stop.stop_lat, stop.stop_lon)
                min_distance, nearest_station = None, None
                for train_station, train_station_point in train_station_points:
                    distance = train_station_point.distance_to(stop_point)
                    if min_distance is None or distance < min_distance:
                        nearest_station = train_station
                        min_distance = distance
                result[stop.stop_id] = (min_distance, nearest_station)
        return result

    def find_stop_routes():
        print("Finding routes for stops")
        result = defaultdict(lambda: set())
        for trip in gtfs.trips.values():
            for trip_story_stop in trip.trip_story:
                result[trip_story_stop.stop_id].add(trip.route)
        return result

    def export_full_stops(train_station_distance, stop_routes):
        with open(gtfs.full_stops_filename(), 'w', encoding='utf8') as outf:
            outf.write('stop_id,stop_code,stop_name,stop_desc,stop_lat,stop_lon,location_type,parent_station,zone_id,' +
                       'nearest_train_station,train_station_distance,routes_here\n')
            for stop in gtfs.stops.values():
                line = ','.join([
                    str(stop.stop_id),
                    stop.stop_code,
                    stop.stop_name,
                    stop.stop_desc,
                    str(stop.stop_lat),
                    str(stop.stop_lon),
                    stop.location_type,
                    stop.parent_station,
                    stop.zone_id,
                    str(train_station_distance[stop.stop_id][1]),
                    str(int(train_station_distance[stop.stop_id][0])),
                    ' '.join(route.line_number for route in stop_routes[stop.stop_id])
                ])
                outf.write(line + '\n')

    export_full_stops(find_distance_from_train_station(find_train_stations()), find_stop_routes())

def extend_routes(gtfs: ExtendedGTFS):
    print("Extending routes")
    gtfs.load_basic_routes()
    gtfs.load_trips()

    def find_route_trip_stories():
        result = defaultdict(lambda: set())
        for trip in gtfs.trips.values():
            result[trip.route].add(trip.route_story)
        print("Trip stories found for %d routes" % len(result))
        return result

    def export(route_stories):
        fields = ["route_id", "agency_id", "route_short_name", "route_long_name", "route_desc", "route_type",
                  "trip_stories_number", "route_stories"]
        with open(gtfs.at_path(ExtendedGTFS.full_routes_filename), 'w', encoding='utf8') as f:
            f.write(','.join(fields) + '\n')
            for route in gtfs.routes.values():
                values = [route.route_id, route.agency_id, route.line_number, route.route_long_name, route.route_desc,
                          route.route_type,
                          len(route_stories[route]),
                          ' '.join(str(story.route_story_id) for story in route_stories[route])]
                str_values = [str(v) for v in values]
                f.write(','.join(str_values) + '\n')

    export(find_route_trip_stories())

# There's a file called kavrazif_lines that contains the list of "official" kavrazif routes
# we want to find the gtfs routes that match those lines
def find_kavrazif_routes(gtfs: ExtendedGTFS, max_distance_from_train_station=500):
    print("stating find_kavrazif_routes")
    gtfs.load_route_stories()
    gtfs.load_routes()
    gtfs.load_stops()

    # a single record in the input file
    KavRazif = namedtuple('KavRazif', 'id line_number station_id')
    # a single record in the output file
    Result = namedtuple('Result', 'route,route_story,route_story_stop,kavrazif_record')

    def stop_object(trip_story_stop):
        return gtfs.stops[trip_story_stop.stop_id]

    def load_kavrazif_records():
        # we will need to convert the stop_codes to stop_ids
        # note that it's not really a one-to-one mapping. In central bus stations, there are several stops
        # (with different stop id) and the same stop id. But we are only really interested in train stations,
        # so we don't care about that
        stop_codes = {stop.stop_code: stop.stop_id for stop in gtfs.stops.values()}
        with open('data/kavrazif_lines.txt', encoding='utf8') as f:
            return [KavRazif(record['kavrazif_id'],
                             record['line_number'].strip(),
                             stop_codes[record['stop_code']])
                    for record in csv.DictReader(f)]

    def log_unmatched_kavrazif():
        found = set(r.kavrazif_record for r in routes)
        missing_records = [record for record in kavrazif_records if record not in found]
        if len(missing_records) > 0:
            print("  %d kavrazif records weren't found, missing records: %s" %
                  (len(missing_records), missing_records))

    def routes_story_stops_near_stations(route_story):
        stops_by_nearest_station_id = defaultdict(lambda: [])
        for stop in route_story.stops:
            if stop_object(stop).train_station_distance < max_distance_from_train_station:
                nearest_station = stop_object(stop).nearest_train_station_id
                stops_by_nearest_station_id[nearest_station].append(stop)
        station_to_nearest_trip_story_stop = []
        for station_id in stops_by_nearest_station_id:
            nearest_stop = min(stops_by_nearest_station_id[station_id],
                               key=lambda s: stop_object(s).train_station_distance)
            station_to_nearest_trip_story_stop.append((nearest_stop, station_id))
        return station_to_nearest_trip_story_stop

    def load_route_id_and_station_id():
        result = []
        # line numbers
        line_numbers = set(record.line_number for record in kavrazif_records)
        # routes with the correct line number
        line_number_matching = [route for route in gtfs.routes.values() if route.line_number in line_numbers]
        print("  there are %d routes with a line number match" % len(line_number_matching))
        for route in line_number_matching:
            # find train stations that have route with this name nearby as a kavrazif route
            possible_train_stations = {record.station_id: record for record in kavrazif_records
                                       if record.line_number == route.line_number}
            for route_story_id in route.route_story_ids:
                route_story = gtfs.route_stories[route_story_id]
                for route_story_stop, station_id in routes_story_stops_near_stations(route_story):
                    if station_id in possible_train_stations:
                        r = Result(route, route_story, route_story_stop, possible_train_stations[station_id])
                        result.append(r)
        print("  found %d route_id and train_station pairs" % len(result))
        return result

    def export(data):
        fields = ['route_id', 'route_desc', 'agency_id', 'agency_name', 'route_short_name', 'route_long_name',
                  'route_type', 'kavrazif_id', 'train_station_id', 'train_station_name', 'stop_sequence',
                  'stop_sequence_from_end', 'route_story_id']

        with open(gtfs.at_path('kavrazif_routes.txt'), 'w', encoding='utf8') as f:
            writer = csv.DictWriter(f, fieldnames=fields, lineterminator='\n')
            writer.writeheader()
            for r in data:      # r: Result
                station = gtfs.stops[stop_object(r.route_story_stop).nearest_train_station_id]
                sequence_from_end = len(r.route_story.stops) - r.route_story_stop.stop_sequence + 1
                record = {
                    'route_id': r.route.route_id,
                    'route_desc': r.route.route_desc,
                    'agency_id': r.route.agency.agency_id,
                    'agency_name': r.route.agency.agency_name,
                    'route_short_name': r.route.line_number,
                    'route_long_name': r.route.route_long_name,
                    'route_type': r.route.route_type,
                    'kavrazif_id': r.kavrazif_record.id,
                    'train_station_id': r.kavrazif_record.station_id,
                    'train_station_name': station.stop_name,
                    'stop_sequence': r.route_story_stop.stop_sequence,
                    'stop_sequence_from_end': sequence_from_end,
                    'route_story_id': r.route_story.route_story_id
                }
                writer.writerow(record)

    kavrazif_records = load_kavrazif_records()
    routes = load_route_id_and_station_id()
    log_unmatched_kavrazif()
    export(routes)

if __name__ == '__main__':
    find_kavrazif_routes(ExtendedGTFS('data/gtfs/gtfs_2016_05_25/'))


import sys
import ingescape as igs

def multiply_callback(iop_type, iop_name, value_type, value, my_data):
    igs.info(f"From service, multiply {value} by 2 : {value * 2}")
    igs.output_set_int("out", value * 2)

def multiply_service_callback(sender_agent_name, sender_agent_uuid, service_name, argument_list, token, my_data):
    igs.info(f"From input, multiply {argument_list[0]} by {argument_list[1]} : {argument_list[0]*argument_list[1]}")
    igs.service_call(sender_agent_uuid, "result", (argument_list[0]*argument_list[1]), "")

if __name__ == "__main__":
    if len(sys.argv) != 4:
        print("usage: python3 ./main.py agent_name network_device port")
        list_devices = igs.net_devices_list()
        print("Use one of these devices :")
        for device in list_devices:
            print(f"    {device}")
        exit(1)

    igs.input_create("in", igs.INTEGER_T, None)
    igs.observe_input("in", multiply_callback, None)
    igs.output_create("out", igs.INTEGER_T, None)

    igs.service_init("multiply", multiply_service_callback, None)
    igs.service_arg_add("multiply", "a", igs.INTEGER_T)
    igs.service_arg_add("multiply", "b", igs.INTEGER_T)

    igs.agent_set_name(sys.argv[1])
    igs.set_command_line(sys.executable + " " + " ".join(sys.argv))

    igs.start_with_device(sys.argv[2], int(sys.argv[3]))

    # simple main loop used to wait for user to stop the agent.
    input('')

    igs.stop()


import argparse
from pathlib import Path
from typing import Callable, Union
import pandas as pd
import os
import warnings

import sys
from examples.speech_to_text.data_utils import load_df_from_tsv, save_df_to_tsv
from asr.asr_inference import asr_inference
from filtering_utils import find_noisy_examples_zhhao, mustc_utterance_cleaner

DATASETS = ["MUSTC", "LIBRISPEECH"]
TRAIN_SPLITS = {
    "MUSTC": "train.tsv",
    "LIBRISPEECH": "train-all.tsv"}
CLEANER_FUNC = {
    "MUSTC": mustc_utterance_cleaner,
    "LIBRISPEECH": None,}
MODEL_NAME = "/home/zhhao/ssl_model/wav2vec_large_960h_lv60_self"

def filter(df: pd.DataFrame, tsv_path: Union[Path, str], dataset_name: str,
utterance_cleaner: Callable, asr_batch_size: int, asr_wer_threshold: float, max_example_number: int) -> pd.DataFrame:
    # text cleaning
    if dataset_name == 'MUSTC':
        df["src_text"] = df.apply(lambda x: utterance_cleaner(x["src_text"]), axis = 1)

    # removal of empty examples after cleaning
    empty_examples_bool = df.tgt_text == ""
    df = df.loc[~empty_examples_bool]
    print(f"removed {empty_examples_bool.sum()} empty examples. remaining: {len(df)}")

    # removal of noisy examples (based on ASR system predictions)
    asr_predictions_path = tsv_path.parent / f"{tsv_path.stem}_wer_results.json"
    if os.path.exists(asr_predictions_path):
        print("Already generate inference reults, skip this stage")
    else:
        print("Starting ASR inference with Wav2Vev_2.0 ...")
        asr_inference(tsv_path, asr_batch_size, dataset_name, MODEL_NAME)
    examples_bool = find_noisy_examples_zhhao(df, asr_predictions_path, asr_wer_threshold, max_example_number)
    df = df.loc[examples_bool]
    print(f"preserve {examples_bool.sum()} examples")

    return df

def main():

    parser = argparse.ArgumentParser()
    parser.add_argument("--dataset_name", type = str, required = True, choices = DATASETS)
    parser.add_argument("--tsv_root", type = str, required = True,
        help = "Path for the directory containing the TSV files for this DATASET.")
    parser.add_argument("--asr_batch_size", type = int, default = 24,
        help = "Batch size to be used during the ASR inference with Wav2Vec.")
    parser.add_argument("--asr_wer_threshold", type = float, default = .5,
        help = "Word-Error-Rate above which an example is considered noisy.")
    parser.add_argument("--max_example_number", type = int, default = 50000,
        help = "Preserved max example number.")
    args = parser.parse_args()

    tsv_root = Path(args.tsv_root)
    file_name = TRAIN_SPLITS[args.dataset_name]

    utterance_cleaner = CLEANER_FUNC[args.dataset_name]

    tsv_path = tsv_root / file_name
    df_split = load_df_from_tsv(tsv_path)

    print(f"Running filtering script for {file_name} of {args.dataset_name} from file {tsv_path}")
    df_split_filtered = filter(df_split, tsv_path, args.dataset_name, utterance_cleaner,
    args.asr_batch_size, args.asr_wer_threshold, args.max_example_number)

    new_tsv_path = tsv_root / Path(tsv_path.stem + "_filtered.tsv")
    save_df_to_tsv(df_split_filtered, new_tsv_path)
    print(f"Saved filtered TSV for: {file_name} of {args.dataset_name} at: {new_tsv_path}")

if __name__ == "__main__":
    main()


import locale

from django import forms

from django.utils.dates import WEEKDAYS, MONTHS
from django.utils.translation import ugettext_lazy as _

# from fairqueue import settings
from django.conf import settings
from django.utils import formats

from .models import Resource, Calendar, WorkingTime, DaysOff

class SearchRscsForm(forms.Form):
    ORDER_BY = [('asc', _('asc.')),
               ('des', _('desc.')),
               ('no', _('no'))]

    rsc_name = forms.CharField(label= _('Name'),max_length=200, required=False,
                               widget=forms.TextInput(attrs={'autofocus': '',
                                                             'placeholder': _('Resource name')}))
    ord_name = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='asc')
    rsc_desc = forms.CharField(label= _('Description'), max_length=200, required=False,
                               widget=forms.TextInput(attrs={'placeholder': _('Resource description')}))
    ord_desc = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')
    cal_name = forms.CharField(label= _('Calendar'), max_length=200, required=False,
                               widget=forms.TextInput(attrs={'placeholder': _('Calendar name')}))
    ord_cal_name = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')

class ResourceForm(forms.ModelForm):
    class Meta:
        model = Resource
        # fields = ['name', 'description', 'text_title', 'calendar']
        fields = '__all__'
        widgets = {
            'name': forms.TextInput(attrs={'autofocus': '', 'placeholder': _('Resource name')}),
            'description': forms.TextInput(attrs={'placeholder': _('Resource description')}),
            'text_title': forms.TextInput(attrs={'placeholder': _('Resource title')}),
        }

class SearchCalsForm(forms.Form):
    ORDER_BY = [('asc', _('asc.')),
               ('des', _('desc.')),
               ('no', _('no'))]

    cal_owner = forms.CharField(label= _('Owner'),max_length=200, required=False,
                               widget=forms.TextInput(attrs={'autofocus': '',
                                                             'placeholder': _('Calendar owner')}))
    ord_owner = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')
    cal_name = forms.CharField(label= _('Name'), max_length=200, required=False,
                               widget=forms.TextInput(attrs={'placeholder': _('Calendar name')}))
    ord_name = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='asc')
    cal_desc = forms.CharField(label= _('Description'), max_length=200, required=False,
                               widget=forms.TextInput(attrs={'placeholder': _('Calendar description')}))
    ord_desc = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')

    cal_year = forms.DecimalField(label= _('Year'), max_digits=4, decimal_places=0, required=False,
                               widget=forms.NumberInput(attrs={'placeholder': _('Year')}))
    ord_year = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')

    # TODO es podria fer un filtre per tots els camps
    # cal_ini_day = forms.DateField (label= _('First day'), required=False,
    #                            widget=forms.TextInput(attrs={'placeholder': _('Calendar first day')}))
    # ord_ini_day = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')
    # cal_end_day = forms.DateField (label= _('Last day'), required=False,
    #                            widget=forms.TextInput(attrs={'placeholder': _('Calendar last day')}),
    #                            help_text="Please use the following formaat: YYYY-MM-DD.")
    # ord_end_day = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')
    #
    # cal_template = forms.BooleanField(label= _('Template'), required=False,
    #                                   help_text="Can the calendar be used as a template for others calendars?")
    # ord_template = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')
    #
    # cal_prev = forms.CharField(label= _('Previous calendar'), max_length=200, required=False,
    #                            widget=forms.TextInput(attrs={'placeholder': _('Previous calendar name')}))
    # ord_prev = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')
    # cal_next = forms.CharField(label= _('Next calendar'), max_length=200, required=False,
    #                            widget=forms.TextInput(attrs={'placeholder': _('Next calendar name')}))
    # ord_next = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')
    #
    # cal_open = forms.BooleanField(label= _('Open'), required=False,
    #                                   help_text="Is the calendar open to be used?")
    # ord_open = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')

class CalendarForm(forms.ModelForm):
    class Meta:
        model = Calendar
        fields = '__all__'
        widgets = {
            'owner': forms.TextInput(attrs={'autofocus': '', 'placeholder': _('Calendar owner name')}),
            'name': forms.TextInput(attrs={'placeholder': _('Calendar name')}),
            'description': forms.TextInput(attrs={'placeholder': _('Calendar description')}),
            'year': forms.NumberInput(attrs={'placeholder': _('Year')}),
            'ini_day': forms.DateInput(attrs={'placeholder': _('Calendar first day')}),
            'end_day': forms.DateInput(attrs={'placeholder': _('Calendar last day')}),
            # 'template': forms.CheckboxInput(),
            #'next': forms.TextInput(attrs={'placeholder': _('Next calendar name')}),
            #'prev': forms.TextInput(attrs={'placeholder': _('Previous calendar name')}),
            # 'open': forms.CheckboxInput(),
        }

class SearchWTsForm(forms.Form):
    ORDER_BY = [('asc', _('asc.')),
               ('des', _('desc.')),
               ('no', _('no'))]
    sched = [('','--------')] + WorkingTime.TYPE_OF_SCHEDULE

    wt_name = forms.CharField(label= _('Name'), max_length=200, required=False,
                              widget=forms.TextInput(attrs={'placeholder': _('Working time name')}))
    ord_name = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='asc')
    wt_desc = forms.CharField(label= _('Description'), max_length=200, required=False,
                               widget=forms.TextInput(attrs={'placeholder': _('Working time description')}))
    ord_desc = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')

    wt_ini_hour = forms.CharField(label= _('Initial hour'), max_length=5, required=False,
                               widget=forms.TextInput(attrs={'placeholder': _('Working time initial hour hh:mm')}))
    ord_ini_hour = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')

    wt_end_hour = forms.CharField(label= _('Final hour'), max_length=5, required=False,
                               widget=forms.TextInput(attrs={'placeholder': _('Working time ending hour hh:mm')}))
    ord_end_hour = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')

    wt_type = forms.CharField(label= _('Type'), max_length=2, required=False,
                              widget=forms.Select(choices=sched))
    ord_type = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')

class WorkingTimeForm(forms.ModelForm):
    class Meta:
        model = WorkingTime
        fields = '__all__'
        widgets = {
            'name': forms.TextInput(attrs={'placeholder': _('Working time name')}),
            'description': forms.TextInput(attrs={'placeholder': _('Working time description')}),
            'ini_hour': forms.TextInput(attrs={'placeholder': _('WT initial hour hh:mm')}),
            'end_hour': forms.TextInput(attrs={'placeholder': _('WT final hour hh:mm')}),
            'type': forms.RadioSelect(),
        }

class SearchDOsForm(forms.Form):
    ORDER_BY = [('asc', _('asc.')),
               ('des', _('desc.')),
               ('no', _('no'))]
    typeday = [('', '--------')] + DaysOff.TYPE_OF_DAY_CHOICES

    do_name = forms.CharField(label= _('Name'), max_length=200, required=False,
                              widget=forms.TextInput(attrs={'placeholder': _('Working time name')}))
    ord_name = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='asc')
    do_desc = forms.CharField(label= _('Description'), max_length=200, required=False,
                               widget=forms.TextInput(attrs={'placeholder': _('Working time description')}))
    ord_desc = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')

    do_type = forms.CharField(label= _('Day off type'), max_length=5, required=False,
                               widget=forms.Select(choices=typeday))
    ord_type = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')

    do_fromday_ini = forms.DateField(label= _('From day (from)'), required=False,
                                    widget=forms.DateInput(attrs={'type': 'date'}))
    do_fromday_end = forms.DateField(label= _('From day (to)'), required=False,
                                    widget=forms.DateInput(attrs={'type': 'date'}))
    ord_fromday = forms.ChoiceField(label='', choices=ORDER_BY, widget=forms.RadioSelect, initial='no')

    # name = models.CharField( _('Days off name'), max_length=200)
    # description = models.CharField( _('Days off description'), max_length=200, blank=True)
    # type = models.CharField(max_length=2, choices=TYPE_OF_DAY_CHOICES, default=DAY)
    # day = models.DateField()
    # end_day = models.DateField()
    # week_day = models.DecimalField(max_digits=1, decimal_places=0, validators=[MinValueValidator(0), MaxValueValidator(6)])
    # month_day = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(31)])
    # month = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(12)])
    # from_day = models.DateField()
    # to_day = models.DateField()

class DaysOffForm(forms.ModelForm):
    class Meta:
        # django.utils.dates.WEEKDAYS and MONTHS int are not iterables
        model = DaysOff
        fields = '__all__'
        localized_fields = ( 'day', 'end_day', 'from_day', 'to_day',)
        widgets = {
            'name': forms.TextInput(attrs={'placeholder': _('Days off name')}),
            'description': forms.TextInput(attrs={'placeholder': _('Days off description')}),
            #'type': forms.Select(choices=DaysOff.TYPE_OF_DAY_CHOICES),
            #'day': forms.SelectDateWidget(),
            'day': forms.DateInput(attrs={'placeholder': formats.get_format_lazy("SHORT_DATE_FORMAT")}),
            'end_day': forms.DateInput(attrs={'placeholder': formats.get_format_lazy("SHORT_DATE_FORMAT")}),
            'week_day': forms.Select(choices=DaysOff.WEEKDAY_CHOICES), # Monday='MO' ...
            'month': forms.Select(choices=DaysOff.MONTH_CHOICES), # January='JAN' ...
            'from_day': forms.DateInput(attrs={'placeholder': formats.get_format_lazy("SHORT_DATE_FORMAT")}),
            #'to_day': forms.DateInput(attrs={'placeholder': formats.dateformat}),
            'to_day': forms.DateInput(attrs={'placeholder': formats.get_format_lazy("SHORT_DATE_FORMAT")}),
            #'to_day': forms.DateInput(attrs={'placeholder': locale.D_FMT}),

        }


import tkinter as tk
from tkinter import *
from PIL import ImageTk
from pygame import mixer
from logic import morse_logic

class Application(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.grid()
        self.master.title("Grid Manager")
        self.pause_state = 0

        import tkinter as Tk
        import tkinter.ttk as ttk
        import tkinter.font as font
        # tkFont.BOLD == 'bold'
        font.nametofont('TkDefaultFont').configure(size=12) # tiny

        for r in range(6): self.master.rowconfigure(r, weight=1)
        for c in range(6): self.master.columnconfigure(c, weight=1)

        Frame1 = self.make_frame(0, 0, 3, 2)
        Frame2 = self.make_frame(3, 0, 3, 1)
        Frame3 = self.make_frame(0, 2, 3, 4)
        Frame4 = self.make_frame(3, 2, 3, 4)
        Frame5 = self.make_frame(3, 1, 3, 1)

        self.make_button(Frame1, "icons/play.png", 0)
        self.make_button(Frame2, "icons/stop.png", 1)
        self.make_button(Frame5, "icons/pause.png", 2)

        self.input = tk.LabelFrame(Frame3, text=" Input text ")
        self.textvar = tk.StringVar()
        self.textbox = tk.Text(self.input, height=4, width=50, font=("TkDefaultFont", 14), wrap='word', undo=True)
        self.textbox.pack(expand=1, fill="both", padx=5, pady=5)
        self.input.pack(expand=1, fill="both", padx=5, pady=5)

        button2 = tk.Button(self.input, text="Generate morse code", command=lambda: self.generate_morse())
        button2.pack(side=tk.LEFT, expand=1, fill="both", padx=5, pady=5)

        self.output = tk.LabelFrame(master, text=" Morse code ")
        self.status_message = tk.StringVar()
        self.status_message.set('\n Your Morse code will be displayed here \n')

        self.textwidget = tk.Label(self.output, textvariable=self.status_message, wraplength=590)
        self.textwidget.configure(relief='flat', state="normal")
        self.textwidget.pack(expand=1, fill="both", padx=5, pady=5)
        self.output.grid(row = 3, column = 2, rowspan = 3, columnspan = 4, sticky = W+E+N+S)

    def make_frame(self, r, c, rs, cs):
        frame = tk.Frame()
        frame.grid(row = r, column = c, rowspan = rs, columnspan = cs, sticky = W+E+N+S)
        return frame

    def make_button(self, Frame, img_name, i):
        b = tk.Button(Frame)
        image = ImageTk.PhotoImage(file=img_name)
        if i==0: b.config(image=image, command=lambda: self.play())
        elif i==1: b.config(image=image, command=lambda: self.stop())
        else: b.config(image=image, command=lambda: self.pause())
        b.image = image
        b.pack(side="top", fill="both", expand=True)

    def play(self):
        print("play")
        if self.pause_state == 0:
            mixer.init()
            mixer.music.load('file.mp3')
            mixer.music.play()
        else:
            mixer.music.unpause()

    def stop(self):
        print("stop")
        mixer.music.stop()
        self.pause_state = 0

    def pause(self):
        print("pause")
        mixer.music.pause()
        self.pause_state = 1

    def generate_morse(self):
        print("morse")
        self.morse_coder = morse_logic()
        msg = self.textbox.get("1.0", tk.END)
        morse_code = self.morse_coder.process(msg)
        self.status_message.set(morse_code)


class Solution:
    def findMinFibonacciNumbers(self, k: int) -> int:
        fib = [1,1]

        while fib[-1]<=k:
            fib.append(fib[-1]+fib[-2])

        ans,l = 0,len(fib)-1

        while k>0:
            if fib[l]<=k:
                k-=fib[l]
                ans+=1
            l-=1

        return ans


import string
import re

class NotAStringError(Exception):

    def __init__(self):
        super().__init__(f'you entered, it is not a single letter. Please try again.')

class InvalidInputCharError(Exception):
    def __init__(self, *args: str):
        super().__init__(f'You can only pass one letter: ')

class AlphabetIterator:
    def __init__(self, letter: str):
        self._letter = letter
        self._lower_list = list(string.ascii_lowercase)
        self._upper_list = list(string.ascii_uppercase)
        self._end = 25

        if len(self._letter) > 1:
            raise InvalidInputCharError

        if self._letter not in self._lower_list and self._letter not in self._upper_list:
            raise NotAStringError

    def get_letter(self):
        return self._letter

    def get_lower_list(self):
        return self._lower_list

    def get_upper_list(self):
        return self._upper_list

    def __iter__(self):
        if self._letter in self._lower_list:
            self._counter = self._lower_list.index(self._letter)
        else:
            self._counter = self._upper_list.index(self._letter)
        return self

    def __next__(self):
        if self._counter > self._end:
            raise StopIteration()
        if self._letter in self._lower_list:
            letter_list = self._lower_list
        elif self._letter in self._upper_list:
            letter_list = self._upper_list
        letter_to_return = letter_list[self._counter]
        self._counter += 1
        return letter_to_return

if __name__ == '__main__':
    n = AlphabetIterator('h')

    for i in n:
        print(i)


from types import NoneType
import discord
from discord.ui import Button, View
from discord.ext import commands
from discord.ext.commands import errors
import asyncio
from database import db_insert
import datetime
import pytz
from config import TOKEN

intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix='!', intents=intents)
client = discord.Client(intents=intents)

# Comandos
@bot.command()
async def start(ctx, study_time=50, rest_time=10, microfone=1):
    if str(ctx.message.channel) == 'pomodoro-bot':
        try:
            channel = ctx.author.voice.channel
            # Voice Channel
            vc = await channel.connect()

            # Mientras estemos conectados al canal que se repita el bucle de estudio/descanso
            while len(channel.members) > 1 and bot.voice_clients != None: # el lio del problema que me dijo gg estÃ¡ en lo de bot.voice_clients pero no acabo de entenderlo
                countdown = study_time
                # Se reproduce el sonido de comienzo
                """ vc.play(discord.FFmpegOpusAudio(
                        source='/home/ubuntu/pomodoro/src/study.mp3')
                        ) """
                # Se mutea a los miembros
                if microfone == 1:
                    for i in channel.members:
                        if i == bot.user:
                            continue
                        await i.edit(mute = True)

                # Se envÃa el mensaje de comienzo
                embed = discord.Embed(title='SesiÃ³n de estudio de {} minutos'.format(
                    study_time), description='Quedan {} minutos'.format(countdown), color=0x2A033A)
                msg = await ctx.send(embed=embed)

                # Se espera el timpo de estudio
                i = 0
                j = 0
                while i < int(study_time)*60:
                    # print(i)
                    await asyncio.sleep(1)
                    i = i + 1
                    j = j + 1
                    if j == 60:
                        countdown = countdown - 1
                        j = 0
                        await msg.edit(
                            embed=discord.Embed(
                                title='SesiÃ³n de estudio de {} minutos'.format(
                                    study_time),
                                description='Quedan {} minutos'.format(
                                    countdown),
                                color=0x2A033A)
                        )

                    # print(countdown)

                    if len(channel.members) == 1 or bot.voice_clients == None:
                        break

                if len(channel.members) == 1 or bot.voice_clients == None:
                    break

                # Se desmutea a los miembros
                if microfone == 1:
                    for i in channel.members:
                        if i == bot.user:
                            continue
                        await i.edit(mute=False)

                # Mensaje de botones de descanso
                button1 = Button(style=discord.ButtonStyle.grey,
                                 emoji="ðŸ¥µ", custom_id='1')
                button2 = Button(style=discord.ButtonStyle.grey,
                                 emoji="ðŸ˜°", custom_id='2')
                button3 = Button(style=discord.ButtonStyle.grey,
                                 emoji="ðŸ˜�", custom_id='3')
                button4 = Button(style=discord.ButtonStyle.grey,
                                 emoji="ðŸ™‚", custom_id='4')
                button5 = Button(style=discord.ButtonStyle.grey,
                                 emoji="ðŸ˜€", custom_id='5')

                # Interacciones con el mensaje
                async def button_callback(interaction):
                    db_insert(datetime.datetime.now(pytz.timezone('Europe/Madrid')),
                              interaction.user,
                              interaction.data['custom_id'])
                    try:
                        await interaction.response.send_message("Recibido, {}!".format(interaction.user))
                    except:
                        await ctx.send("Oops! Algo no fue bien, pulsa de nuevo")

                button1.callback = button_callback
                button2.callback = button_callback
                button3.callback = button_callback
                button4.callback = button_callback
                button5.callback = button_callback

                view = View()
                view.add_item(button1)
                view.add_item(button2)
                view.add_item(button3)
                view.add_item(button4)
                view.add_item(button5)

                # Se envÃa el mensaje de descanso
                countdown = rest_time
                embed = discord.Embed(title='Descanso de {} minutos'.format(rest_time),
                                      description='Quedan {} minutos \n\n Â¿QuÃ© tal fue la sesiÃ³n de estudio? Puedes indicar aquÃ tu nivel de cansancio a travÃ©s de los emojis.'.format(
                                          countdown),
                                      color=0x6D3588)
                embed.add_field(name='Para consultar tus estadÃsticas,',
                                value='[haz click aquÃ](https://pomodorobot.infinityfreeapp.com/)',
                                inline=True)

                msg = await ctx.send(embed=embed, view=view)
                # Se reproduce el sonido de descanso
                """ vc.play(discord.FFmpegOpusAudio(
                        source='/home/ubuntu/pomodoro/src/rest.mp3')
                        ) """
                # Se espera el timpo de descanso

                i = 0
                j = 0
                while i < int(rest_time)*60:
                    await asyncio.sleep(1)
                    i = i + 1
                    j = j + 1
                    quinceleft = int(rest_time)*60 - 15
                    if i == quinceleft:
                        """ vc.play(discord.FFmpegOpusAudio(
                        source='/home/ubuntu/pomodoro/src/quinceleft.mp3')
                        ) """
                    if j == 60:
                        countdown = countdown - 1
                        j = 0
                        await msg.edit(embed=discord.Embed(title='Descanso de {} minutos'.format(rest_time),
                                                           description='Quedan {} minutos \n\n Â¿QuÃ© tal fue la sesiÃ³n de estudio? Puedes indicar aquÃ tu nivel de cansancio a travÃ©s de los emojis.'.format(
                                                           countdown),
                                                           color=0x6D3588).add_field(name='Para consultar tus estadÃsticas,', value='[haz click aquÃ](https://pomodorobot.infinityfreeapp.com/)',inline=True))
                    if len(channel.members) == 1 or bot.voice_clients == None:
                        break

            # Cuando se vaya todo el mundo del canal, el Bot se desconecta
            await ctx.voice_client.disconnect()

        # Captura de excepciones
        except AttributeError as e:
            if str(e) == '\'NoneType\' object has no attribute \'disconnect\'':
                pass
            else:
                await ctx.message.channel.send("Ha ocurrido un error ({}). Asegurate de estar conectado a un canal de voz".format(str(e)))

        except errors.MissingRequiredArgument:
            print("Faltan atributos")
    else:
        await ctx.message.channel.send('Los comandos se escriben en el canal de texto "pomodoro-bot"')

@bot.command()
async def end(ctx):
    if str(ctx.message.channel) == 'pomodoro-bot':
        if ctx.voice_client != None:
            # desmutea antes de salirse
            channel = ctx.author.voice.channel
            for i in channel.members:
                if i == bot.user:
                    continue
                await i.edit(mute=False)
            await ctx.voice_client.disconnect()
        else:
            await ctx.message.channel.send(
                'No estÃ¡s conectado a ningun canal de voz!!')
    else:
        await ctx.message.channel.send(
            'Los comandos se escriben en el canal de texto "pomodoro-bot"')

@bot.command()
async def program(ctx, start_time, study_time=50, rest_time=10):
    if str(ctx.message.channel) == 'pomodoro-bot':
        st = start_time.split(':')
        # await ctx.send('Su pomodoro empezarÃ¡ a las {}'.format(start_time)) # aqui va el embed
        hour = datetime.datetime.now(pytz.timezone('Europe/Madrid')).hour
        minute = datetime.datetime.now(
                pytz.timezone('Europe/Madrid')).minute
        h1 = datetime.timedelta(hours = int(st[0]), minutes = int(st[1]))
        h2 = datetime.timedelta(hours = hour, minutes = minute)
        time_left = h1 - h2
        time_left = str(time_left)[:4]
        embed = discord.Embed(title=' Su sesiÃ³n de estudio empezarÃ¡ a las {}'.format(
                    start_time), description='Quedan {} para que empiece su sesiÃ³n de estudio'.format(time_left), color=0xBEADB8)
        msg = await ctx.send(embed=embed)
        while True:  # bucle que compruebe el tiempo cada segundo

            await asyncio.sleep(1)
            hour = datetime.datetime.now(pytz.timezone('Europe/Madrid')).hour
            minute = datetime.datetime.now(
                pytz.timezone('Europe/Madrid')).minute
            int(st[0])
            h2 = datetime.timedelta(hours = hour, minutes = minute)
            time_left = h1 - h2
            time_left = str(time_left)[:4]
            await msg.edit(
                            embed=discord.Embed(
                                title=' Su sesiÃ³n de estudio empezarÃ¡ a las {}'.format(
                    start_time),
                                description='Queda {} para que empiece su sesiÃ³n de estudio'.format(time_left),
                                color=0xBEADB8))

            if int(st[0]) == int(hour) and int(st[1]) == int(minute):
                await ctx.invoke(bot.get_command('start'), int(study_time), int(rest_time))
                break
    else:
        await ctx.message.channel.send(
            'Los comandos se escriben en el canal de texto "pomodoro-bot"')

bot.remove_command('help')
@bot.command()
async def help(ctx):
    embed = discord.Embed(title='Ayuda',
                          description='Si necesitas ayuda, aquÃ va una lista con los comandos disponibles, que tendrÃ¡s que escribir en el canal pomodoro-bot.',
                          color=0x6D3588)
    embed.add_field(name="Iniciar sesiÃ³n", value="```!start <study_time> <rest_time>``` \n ***Ejemplo*** ```!start 25 5```  Se iniciarÃ¡ una sesiÃ³n de 25 minutos de estudio y 5 de descanso. \nPor defecto, el uso del comando !start sin argumentos iniciarÃ¡ una sesiÃ³n de 50 minutos de estudio y 10 de descanso)", inline=False)
    embed.add_field(name="Finalizar sesiÃ³n",
                    value="```!end``` Al escribir este comando, el bot abandona la sala y termina la sesiÃ³n", inline=False)
    embed.add_field(name="Programar una sesiÃ³n", value="```!program <date> <study_time> <rest_time>``` \n ***Ejemplo*** ```!program 16:00 25 5``` Se iniciarÃ¡ una sesiÃ³n de pomodoros de 25 minutos de estudio y 5 de descanso a las 16:00. \nRecuerda que a la hora que comience la sesiÃ³n, debes estar en un canal de voz.", inline=False)
    embed.add_field(name="Desmutear", value="```!unmute``` \n Se desactiva la opciÃ³n \"Silenciar en servidor\".", inline=False)

    msg = await ctx.send(embed=embed)

@bot.command()
async def unmute(ctx):
    await ctx.author.edit(mute=False)

# ------------------- #
#       Eventos       #
# ------------------- #

@bot.event
async def on_ready():
    print(
        'We have logged in as {0.user}'.format(bot)
    )  # creaciÃ³n de un canal para comandos la primera vez que se inicia el bot en un canal

    guild_name = bot.guilds[0]
    text_channel = guild_name.text_channels

    for i in range(0, len(text_channel)):
        var = 0

        if 'pomodoro-bot' == str(text_channel[i]):
            var = var + 1
            break

    if var == 0:
        await guild_name.create_text_channel('pomodoro-bot')

@bot.event
async def on_guild_join(guild):

    text_channel = guild.text_channels

    for i in range(0, len(text_channel)):
        var = 0

        if 'pomodoro-bot' == str(text_channel[i]):
            var = var + 1
            break

    if var == 0:
        pomodoro_channel = await guild.create_text_channel('pomodoro-bot')

        embed = discord.Embed(title='Hola ðŸ‘‹!',
                              description='Soy un sencillo Bot que te acompaÃ±arÃ¡ en tus sesiones de estudio y sacarÃ¡ de ti el mÃ¡ximo rendimiento.\n'
                              'Para aprender a usarme escribe en este mismo canal el comando: ```!help``` ',
                              color=0x6D3588)
        await pomodoro_channel.send(embed=embed)

# EjecuciÃ³n
bot.run(TOKEN)


# Databricks notebook source
import adal # Active Directory Authentication Library
# use an existing keyvault to get the authentication credentials ("secrets")
keyvault = "devsandbox-kv1"

# get the secrets from the vault
tenant = dbutils.secrets.get(scope = keyvault, key = "TenantID")
login_url = "https://login.microsoftonline.com"
authority_url = (login_url + '/' + tenant)

context = adal.AuthenticationContext(authority_url, timeout=None)

# get an authentication token
access_token = context.acquire_token_with_client_credentials(
    "https://database.windows.net/",
    dbutils.secrets.get(scope = keyvault, key = "DataBricksClientID"),
    dbutils.secrets.get(scope = keyvault, key = "DataBricksSecret"))

# connect to the serverless pool using jdbc
jdbcHostname = "dev-sandbox-syn-ondemand.sql.azuresynapse.net"
jdbcDatabase = "testingdb"
jdbcPort = 1433

jdbcUrl = "jdbc:sqlserver://{0}:{1}".format(jdbcHostname, jdbcPort)

connectionProperties = {
    "accessToken": access_token.get('accessToken'),
    "database": jdbcDatabase,
    "trustServerCertificate" : "false",
    "encrypt" : "true",
    "driver" : "com.microsoft.sqlserver.jdbc.SQLServerDriver",
    "hostNameInCertificate" : "*.database.windows.net" }

# send the query to the severless pool
pushdown_query = """(
    SELECT * FROM testingdb.dbo.Wildfirestest
    ) t"""

# COMMAND ----------

# fill the dataframe with the results of the query
df = spark.read.jdbc(url=jdbcUrl, table=pushdown_query, properties=connectionProperties)
display(df)
someRecords = df.where(df.TOTAL_HA.cast("int") > 1000000)
display(someRecords)

# COMMAND ----------

# someRecords = df.select('Year', 'Total_HA').where('TOTAL_HA' > '1,000,000')
df = df.where(df.TOTAL_HA.cast("int") > 100000)
display(df)

# COMMAND ----------

# import org.apache.spark.sql.functions.lit
# import org.apache.spark.sql.functions._

df = Seq(
  (2, true),
  (6, true),
  (5, false)
).toDF("num", "is_even_hardcoded")
display(df)
# def isEven(inputColName: String, outputColName: String)(df: DataFrame) = {
#   df.withColumn(outputColName, col(inputColName) % 2 === lit(0))
# }
# df.transform(isEven("num", "is_even")).show()

# COMMAND ----------


from rdkit import Chem

class Substructure:
    """
    Class to store substructures.
    """

    def __init__(self, SMARTS):
        """
        Parameters
        ----------
        SMARTS: str
            SMARTS corresponding to substructure.

        Attributes
        ----------
        Mol: rdkit.Chem.rdchem.Mol
        SMARTS: str
        MatchingCompounds: list[str]
            Contextual list of compound tokens which contain this substructure.
        ReactionParticipations: list[str]
            List of reaction tokens for which the substructure is a reactant.
        ProducingReactions: list[str]
            List of reaction tokens of which the substructure is a product.
        """

        self.verify_input(SMARTS)

        self.Mol = Chem.MolFromSmarts(SMARTS)

        if Chem.MolToSmarts(self.Mol) is None:
            self.SMARTS = SMARTS
        else:
            self.SMARTS = Chem.MolToSmarts(self.Mol)

        self.MatchingCompounds = []
        self.ReactionParticipations = []
        self.ProducingReactions = []

    def verify_input(self, SMARTS):
        """
        Check that the input arguments are of the correct type.

        Parameters
        ----------
        SMARTS: str
            SMARTS corresponding to substructure.

        """

        assert isinstance(
            SMARTS, str
        ), """class Substructure:
            argument should be a SMARTS string."""


from torchvision.transforms.functional import normalize
import torch.nn as nn
import numpy as np

class Denormalize:
    def __init__(self, mean, std):
        mean = np.array(mean)
        std = np.array(std)
        self._mean = -mean/std
        self._std = 1/std

    def __call__(self, tensor):
        if isinstance(tensor, np.ndarray):
            return (tensor - self._mean.reshape(-1, 1, 1)) / self._std.reshape(-1, 1, 1)
        return normalize(tensor, self._mean, self._std)


from __future__ import unicode_literals

from django.db import models

from ems.models.judge import Judge
from ems.models.level import LevelClass, LevelInstance

class ParameterClass(models.Model):
	'''
	Development Notes:
	Same as the Parameter model.
	'''
	name = models.CharField(max_length = 100)

	level = models.ForeignKey(LevelClass, related_name = "parameters", on_delete = models.CASCADE)

	max_value = models.IntegerField(default = 0)

	#instances : ParameterInstance

	def __str__(self):
		return self.name

class ParameterInstance(models.Model):
	'''
	Development Notes:
	Same as Score to some extent.
	Does not have score_card and comments, instead has value and comment.
	Also does not have total score, instead there is a score field in levelinstance.
	'''
	parameterclass = models.ForeignKey(ParameterClass, related_name = "instances", on_delete = models.CASCADE)

	level = models.ForeignKey(LevelInstance, related_name = "parameters", on_delete = models.CASCADE)

	judge = models.ForeignKey(Judge, related_name = "parameter_instances", on_delete = models.CASCADE)
	value = models.IntegerField(default = 0)
	comment = models.CharField(max_length = 500, default = '', blank = True)

	def __str__(self):
		ret_string = "Level : {}".format(self.parameterclass.level.name) + \
			" - Parameter : {}".format(self.parameterclass.name) + \
			" - Participant : {}".format(self.level.participant.username)

		return ret_string


import codecs
import math
import os
import sys

import qrcode

import zookeeper

as_string = {32: " ", 220: "▄", 223: "▀", 219: "█"}

SCROLL_WARNING = """
WARNING: Scrolls only display 15 lines at a time. Your QR code requires {}
lines (plus 2 for a border). Scanning may difficult if not impossible in this
format.
"""

def main():
    characters = {
        (0, 0): 32,
        (0, 255): 220,
        (255, 0): 223,
        (255, 255): 219,
    }

    if len(sys.argv) != 2:
        url = "https://museumofzzt.com/file/z/zzt.zip"
    else:
        url = sys.argv[1]
    img = qrcode.make(url, box_size=1, border=0)

    board = zookeeper.Board(populate=True, title="QR2BRD", message="Generated with QR2ZZT")
    board.stats[0].x = 60
    board.stats[0].y = 25

    # Fill the board
    for x in range(0, 1500):
        board.elements[x] = zookeeper.Element(21, 15)

    player = zookeeper.Element(4, 31)
    board.elements[1499] = player
    empty = zookeeper.Element(0, 0)
    board.elements[689] = empty

    # Draw the QR code
    h_offset = (60 - img.width) // 2
    v_offset = ((25 - (img.height // 2)) // 2) * 60
    element_idx = h_offset + v_offset

    as_text = "$" + ("█"*(img.width + 2)) + "\n"
    for y in range(0, img.height, 2):
        as_text += "$█"
        for x in range(0, img.width):
            upper_pixel = img.getpixel((x, y))
            if y + 1 == img.height:
                lower_pixel = 255
            else:
                lower_pixel = img.getpixel((x, y+1))

            pair = (upper_pixel, lower_pixel)

            # Having to do both of these is a Zookeeper issue.
            text = zookeeper.Element(53, characters[pair])
            text.character = characters[pair]
            as_text += as_string[text.character]

            board.elements[element_idx] = text
            element_idx += 1

        # Move to the left edge again
        element_idx += 60 - img.width
        as_text += "█\n"

    board.export("output")
    print("Exported.")

    # Save the QR code
    if math.ceil(img.height / 2) > 13:
        print(SCROLL_WARNING.format(math.ceil(img.height / 2)))

    as_text += "$" + ("█"*(img.width + 2)) + "\n"
    as_text += "$" + url + "\n"
    with codecs.open("output.txt", "w", "cp437") as fh:
        fh.write(as_text)
    return True

if __name__ == "__main__":
    main()


from flask import flash, request
from mysqlconnection import connectToMySQL

class Survey():
    def __init__(self,data):
        self.id = data['id']
        self.name = data['name']
        self.location = data['location']
        self.language = data['language']
        self.comment = data['comment']
        self.created_at = data['created_at']
        self.updated_at = data['updated_at']

    @classmethod
    def create_survey(cls, data):
        query = "INSERT INTO students (name, location, language, comment) VALUES (%(name)s, %(location)s, %(language)s, %(comment)s);"
        new_survey = connectToMySQL('dojo_survey_schema').query_db(query, data)
        return new_survey

    @staticmethod
    def validate_survey(survey):
        is_valid = True
        if len(survey['name']) < 3:
            flash("Name must be at least 3 characters.")
            is_valid = False
        if len(survey['location']) < 3:
            flash("Location must be at least 3 characters.")
            is_valid = False
        if len(survey['language']) < 3:
            flash("Language must be at least 3 characters.")
            is_valid = False
        if len(survey['comment']) < 1:
            flash("A comment is required.")
            is_valid = False
        return is_valid


import json
from functools import wraps

from pgadmin.browser.server_groups.servers import databases
from flask import render_template, request, jsonify
from flask_babel import gettext
from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, \
    make_response as ajax_response, internal_server_error, gone
from pgadmin.utils.driver import get_driver
from pgadmin.browser.server_groups.servers.databases.extensions.utils \
    import get_extension_details
from config import PG_DEFAULT_DRIVER
from pgadmin.tools.schema_diff.node_registry import SchemaDiffRegistry
from pgadmin.tools.schema_diff.compare import SchemaDiffObjectCompare

class ExtensionModule(CollectionNodeModule):
    """
    class ExtensionModule():

        A collection Node which inherits CollectionNodeModule
        class and define methods to get child nodes, to load its own
        javascript file.
    """
    _NODE_TYPE = "extension"
    _COLLECTION_LABEL = gettext("Extensions")

    def __init__(self, *args, **kwargs):
        """
        Initialising the base class
        """
        super().__init__(*args, **kwargs)

    def get_nodes(self, gid, sid, did):
        """
        Generate the collection node
        """
        if self.has_nodes(sid, did,
                          base_template_path=ExtensionView.EXT_TEMPLATE_PATH):
            yield self.generate_browser_collection_node(did)

    @property
    def node_inode(self):
        """
        If a node have child return True otherwise False
        """
        return False

    @property
    def script_load(self):
        """
        Load the module script for extension, when any of the database nodes
        are initialized.
        """
        return databases.DatabaseModule.node_type

    @property
    def module_use_template_javascript(self):
        """
        Returns whether Jinja2 template is used for generating the javascript
        module.
        """
        return False

# Create blueprint of extension module
blueprint = ExtensionModule(__name__)

class ExtensionView(PGChildNodeView, SchemaDiffObjectCompare):
    """
    This is a class for extension nodes which inherits the
    properties and methods from NodeView class and define
    various methods to list, create, update and delete extension.

    Variables:
    ---------
    * node_type - tells which type of node it is
    * parent_ids - id with its type and name of parent nodes
    * ids - id with type and name of extension module being used.
    * operations - function routes mappings defined.
    """
    EXT_TEMPLATE_PATH = 'extensions/sql'
    node_type = blueprint.node_type

    parent_ids = [
        {'type': 'int', 'id': 'gid'},
        {'type': 'int', 'id': 'sid'},
        {'type': 'int', 'id': 'did'}
    ]
    ids = [
        {'type': 'int', 'id': 'eid'}
    ]

    operations = dict({
        'obj': [
            {'get': 'properties', 'delete': 'delete', 'put': 'update'},
            {'get': 'list', 'post': 'create', 'delete': 'delete'}
        ],
        'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
        'nodes': [{'get': 'node'}, {'get': 'nodes'}],
        'sql': [{'get': 'sql'}],
        'msql': [{'get': 'msql'}, {'get': 'msql'}],
        'stats': [{'get': 'statistics'}],
        'dependency': [{'get': 'dependencies'}],
        'dependent': [{'get': 'dependents'}],
        'avails': [{}, {'get': 'avails'}],
        'schemas': [{}, {'get': 'schemas'}],
        'children': [{'get': 'children'}]
    })

    keys_to_ignore = ['oid', 'oid-2', 'owner']

    def check_precondition(f):
        """
        This function will behave as a decorator which will checks
        database connection before running view, it will also attaches
        manager,conn & template_path properties to self
        """

        @wraps(f)
        def wrap(*args, **kwargs):
            # Here args[0] will hold self & kwargs will hold gid,sid,did
            self = args[0]
            self.manager = get_driver(
                PG_DEFAULT_DRIVER
            ).connection_manager(kwargs['sid'])
            self.conn = self.manager.connection(did=kwargs['did'])
            self.template_path = self.EXT_TEMPLATE_PATH

            self.datistemplate = False
            if (
                self.manager.db_info is not None and
                kwargs['did'] in self.manager.db_info and
                'datistemplate' in self.manager.db_info[kwargs['did']]
            ):
                self.datistemplate = self.manager.db_info[
                    kwargs['did']]['datistemplate']

            return f(*args, **kwargs)

        return wrap

    @check_precondition
    def list(self, gid, sid, did):
        """
        Fetches all extensions properties and render into properties tab
        """
        SQL = render_template("/".join([self.template_path,
                                        self._PROPERTIES_SQL]),
                              conn=self.conn)
        status, res = self.conn.execute_dict(SQL)

        if not status:
            return internal_server_error(errormsg=res)
        return ajax_response(
            response=res['rows'],
            status=200
        )

    @check_precondition
    def nodes(self, gid, sid, did):
        """
        Lists all extensions under the Extensions Collection node
        """
        res = []
        SQL = render_template("/".join([self.template_path,
                                        self._PROPERTIES_SQL]),
                              conn=self.conn)
        status, rset = self.conn.execute_2darray(SQL)
        if not status:
            return internal_server_error(errormsg=rset)

        for row in rset['rows']:
            res.append(
                self.blueprint.generate_browser_node(
                    row['oid'],
                    did,
                    row['name'],
                    'icon-extension',
                    description=row['comment']
                ))

        return make_json_response(
            data=res,
            status=200
        )

    @check_precondition
    def node(self, gid, sid, did, eid):
        """
        This function will fetch the properties of extension
        """
        SQL = render_template("/".join([self.template_path,
                                        self._PROPERTIES_SQL]),
                              eid=eid, conn=self.conn)
        status, rset = self.conn.execute_2darray(SQL)
        if not status:
            return internal_server_error(errormsg=rset)

        for row in rset['rows']:
            return make_json_response(
                data=self.blueprint.generate_browser_node(
                    row['oid'],
                    did,
                    row['name'],
                    'icon-extension'
                ),
                status=200
            )

        return gone(gettext("Could not find the specified extension."))

    @check_precondition
    def properties(self, gid, sid, did, eid):
        """
        Fetch the properties of a single extension and render in properties tab
        """
        status, res = self._fetch_properties(did, eid)
        if not status:
            return res

        return ajax_response(
            response=res,
            status=200
        )

    def _fetch_properties(self, did, eid):
        """
        This function fetch the properties of the extension.
        :param did:
        :param eid:
        :return:
        """
        SQL = render_template("/".join(
            [self.template_path, self._PROPERTIES_SQL]), eid=eid,
            conn=self.conn)
        status, res = self.conn.execute_dict(SQL)
        if not status:
            return False, internal_server_error(errormsg=res)

        if len(res['rows']) == 0:
            return False, gone(
                gettext("Could not find the extension information.")
            )

        res['rows'][0]['is_sys_obj'] = (
            res['rows'][0]['oid'] <= self._DATABASE_LAST_SYSTEM_OID or
            self.datistemplate)

        return True, res['rows'][0]

    @check_precondition
    def create(self, gid, sid, did):
        """
        Create a new extension object
        """
        required_args = [
            'name'
        ]

        data = request.form if request.form else json.loads(
            request.data
        )

        for arg in required_args:
            if arg not in data:
                return make_json_response(
                    status=410,
                    success=0,
                    errormsg=gettext(
                        "Could not find the required parameter ({})."
                    ).format(arg)
                )

        status, res = self.conn.execute_dict(
            render_template(
                "/".join([self.template_path, self._CREATE_SQL]),
                data=data
            )
        )

        if not status:
            return internal_server_error(errormsg=res)

        status, res = get_extension_details(
            self.conn, data['name'],
            "/".join([self.template_path, self._PROPERTIES_SQL]))
        if not status:
            return internal_server_error(errormsg=res)

        return jsonify(
            node=self.blueprint.generate_browser_node(
                res['oid'],
                did,
                res['name'],
                'icon-extension'
            )
        )

    @check_precondition
    def update(self, gid, sid, did, eid):
        """
        This function will update an extension object
        """
        data = request.form if request.form else json.loads(
            request.data
        )

        try:
            SQL, name = self.getSQL(gid, sid, data, did, eid)
            # Most probably this is due to error
            if not isinstance(SQL, str):
                return SQL
            SQL = SQL.strip('\n').strip(' ')
            status, res = self.conn.execute_dict(SQL)
            if not status:
                return internal_server_error(errormsg=res)

            other_node_info = {}
            if 'comment' in data:
                other_node_info['description'] = data['comment']

            return jsonify(
                node=self.blueprint.generate_browser_node(
                    eid,
                    did,
                    name,
                    icon="icon-%s" % self.node_type,
                    **other_node_info
                )
            )
        except Exception as e:
            return internal_server_error(errormsg=str(e))

    @check_precondition
    def delete(self, gid, sid, did, eid=None, only_sql=False):
        """
        This function will drop/drop cascade a extension object
        """

        if eid is None:
            data = request.form if request.form else json.loads(
                request.data
            )
        else:
            data = {'ids': [eid]}

        cascade = self._check_cascade_operation()

        try:
            for eid in data['ids']:
                # check if extension with eid exists
                SQL = render_template("/".join(
                    [self.template_path, self._DELETE_SQL]), eid=eid)
                status, name = self.conn.execute_scalar(SQL)
                if not status:
                    return internal_server_error(errormsg=name)

                if name is None:
                    return make_json_response(
                        status=410,
                        success=0,
                        errormsg=gettext(
                            'Error: Object not found.'
                        ),
                        info=gettext(
                            'The specified extension could not be found.\n'
                        )
                    )

                # drop extension
                SQL = render_template("/".join(
                    [self.template_path, self._DELETE_SQL]
                ), name=name, cascade=cascade)

                # Used for schema diff tool
                if only_sql:
                    return SQL

                status, res = self.conn.execute_scalar(SQL)
                if not status:
                    return internal_server_error(errormsg=res)

            return make_json_response(
                success=1,
                info=gettext("Extension dropped")
            )
        except Exception as e:
            return internal_server_error(errormsg=str(e))

    @check_precondition
    def msql(self, gid, sid, did, eid=None):
        """
        This function returns modified SQL
        """
        data = {}
        for k, v in request.args.items():
            try:
                data[k] = json.loads(v)
            except ValueError:
                data[k] = v

        try:
            SQL, name = self.getSQL(gid, sid, data, did, eid)
            # Most probably this is due to error
            if not isinstance(SQL, str):
                return SQL
            SQL = SQL.strip('\n').strip(' ')
            if SQL == '':
                SQL = "--modified SQL"

            return make_json_response(
                data=SQL,
                status=200
            )
        except Exception as e:
            return internal_server_error(errormsg=str(e))

    def getSQL(self, gid, sid, data, did, eid=None):
        """
        This function will generate sql from model data
        """
        required_args = [
            'name'
        ]

        if eid is not None:
            SQL = render_template("/".join(
                [self.template_path, self._PROPERTIES_SQL]
            ), eid=eid, conn=self.conn)
            status, res = self.conn.execute_dict(SQL)
            if not status:
                return internal_server_error(errormsg=res)

            if len(res['rows']) == 0:
                return gone(
                    gettext("Could not find the extension information.")
                )

            old_data = res['rows'][0]
            for arg in required_args:
                if arg not in data:
                    data[arg] = old_data[arg]
            SQL = render_template("/".join(
                [self.template_path, self._UPDATE_SQL]
            ), data=data, o_data=old_data)
            return SQL, data['name'] if 'name' in data else old_data['name']
        else:
            SQL = render_template("/".join(
                [self.template_path, self._CREATE_SQL]
            ), data=data)
            return SQL, data['name']

    @check_precondition
    def avails(self, gid, sid, did):
        """
        This function with fetch all the available extensions
        """
        SQL = render_template("/".join([self.template_path, 'extensions.sql']))
        status, rset = self.conn.execute_dict(SQL)
        if not status:
            return internal_server_error(errormsg=rset)
        return make_json_response(
            data=rset['rows'],
            status=200
        )

    @check_precondition
    def schemas(self, gid, sid, did):
        """
        This function with fetch all the schemas
        """
        SQL = render_template("/".join([self.template_path, 'schemas.sql']))
        status, rset = self.conn.execute_dict(SQL)
        if not status:
            return internal_server_error(errormsg=rset)
        return make_json_response(
            data=rset['rows'],
            status=200
        )

    @check_precondition
    def sql(self, gid, sid, did, eid, json_resp=True):
        """
        This function will generate sql for the sql panel
        """
        SQL = render_template("/".join(
            [self.template_path, self._PROPERTIES_SQL]
        ), eid=eid, conn=self.conn)
        status, res = self.conn.execute_dict(SQL)
        if not status:
            return internal_server_error(errormsg=res)
        if len(res['rows']) == 0:
            return gone(
                gettext("Could not find the extension on the server.")
            )

        result = res['rows'][0]

        SQL = render_template("/".join(
            [self.template_path, self._CREATE_SQL]
        ),
            data=result,
            conn=self.conn,
            display_comments=True,
            add_not_exists_clause=True
        )

        if not json_resp:
            return SQL

        return ajax_response(response=SQL)

    @check_precondition
    def dependents(self, gid, sid, did, eid):
        """
        This function gets the dependents and returns an ajax response
        for the extension node.

        Args:
            gid: Server Group ID
            sid: Server ID
            did: Database ID
            eid: Extension ID
        """
        dependents_result = self.get_dependents(self.conn, eid)
        return ajax_response(
            response=dependents_result,
            status=200
        )

    @check_precondition
    def dependencies(self, gid, sid, did, eid):
        """
        This function gets the dependencies and returns an ajax response
        for the extension node.

        Args:
            gid: Server Group ID
            sid: Server ID
            did: Database ID
            lid: Extension ID
        """
        dependencies_result = self.get_dependencies(self.conn, eid)
        return ajax_response(
            response=dependencies_result,
            status=200
        )

    @check_precondition
    def fetch_objects_to_compare(self, sid, did):
        """
        This function will fetch the list of all the extensions for
        specified database id.

        :param sid: Server Id
        :param did: Database Id
        :return:
        """
        res = dict()

        sql = render_template("/".join([self.template_path,
                                        self._PROPERTIES_SQL]),
                              conn=self.conn)
        status, rset = self.conn.execute_2darray(sql)
        if not status:
            return internal_server_error(errormsg=rset)

        for row in rset['rows']:
            status, data = self._fetch_properties(did, row['oid'])
            if status:
                res[row['name']] = data

        return res

    def get_sql_from_diff(self, **kwargs):
        """
        This function is used to get the DDL/DML statements.
        :param kwargs
        :return:
        """
        gid = kwargs.get('gid')
        sid = kwargs.get('sid')
        did = kwargs.get('did')
        oid = kwargs.get('oid')
        data = kwargs.get('data', None)
        drop_sql = kwargs.get('drop_sql', False)

        if data:
            sql, name = self.getSQL(gid=gid, sid=sid, did=did, data=data,
                                    eid=oid)
        else:
            if drop_sql:
                sql = self.delete(gid=gid, sid=sid, did=did,
                                  eid=oid, only_sql=True)
            else:
                sql = self.sql(gid=gid, sid=sid, did=did, eid=oid,
                               json_resp=False)
        return sql

SchemaDiffRegistry(blueprint.node_type, ExtensionView, 'Database')
# Register and add ExtensionView as blueprint
ExtensionView.register_node_view(blueprint)


from ipywidgets import widgets
from IPython.display import display
from ipywidgets import HBox, Label, Dropdown, Button, Checkbox, HTML, Layout
from nltk.tree import ParentedTree

single = "Wählen Sie die eine korrekte Antwort aus: "
multiple = "Markieren Sie alle passenden Antworten: "
offen = "Geben Sie die korrekte Antwort ein: "
selection = single
luecke = "Vervollständigen Sie den Lückentext: "
baum = "Erstellen Sie die den korrekten Baum durch das Füllen der Lücken: "
syntaxbaum = "Erstellen Sie die den korrekten Syntaxbaum durch das Füllen der Lücken: "
klammerausdruck = "Fügen Sie die fehlenden Klammern ein. Der entsprechende Syntaxbaum ist als Hilfestellung im zugehörigen PDF zu finden."

def aufgabe(aufg):
    for a in aufg:
        #  print(" ")
         [display(x) for x in a]

class PictureChoice(widgets.VBox):
    def __init__(self, text, correct, *wrong, inst=single):
        choices = list(wrong)
        choices.append(correct)
        choices.sort()
        pic_num = []
        for i, pic in enumerate(choices, 1):
            pic_num.append((pic, i))

        def on_button_clicked(b):
            choice = b.description
            b.style.button_color = 'lightgreen' if choice == self.correct else 'red'

            if self.answered:
                return
            self.answered = True

            # textbox.layout.border = "2px solid lightgreen" if choice == self.correct else "2px solid red"

        textbox = widgets.HTML(value='
{}
'.format(text), layout=widgets.Layout(justify_content="center"))
        instbox = widgets.HTML(value='{}'.format(inst), layout=widgets.Layout(justify_content="center"))
        imagebox = []
        for (p, n) in pic_num:
            file = open(p, "rb")
            image = file.read()
            pic = widgets.Image(value=image, format='png', width=300, height=200)
            if p == correct:
                 self.correct = str(n)

            but = widgets.Button(description=str(n), layout=widgets.Layout(width="250px"))
            but.on_click(on_button_clicked)

            picbox = widgets.VBox(children=[pic, but])
            imagebox.append(picbox)

        allpng = []
        while not imagebox == []:
             if len(imagebox) > 2:
                 allpng.append(widgets.HBox(children=[imagebox[0], imagebox[1]]))
                 imagebox.pop(0)
                 imagebox.pop(0)
             else:
                 allpng.append(widgets.HBox(children=imagebox))
                 break

        super().__init__(children=[textbox, instbox]+allpng)
        self.answered = False

class Anleitung(widgets.VBox):
    def __init__(self, text):
        textbox = widgets.HTML(value='{}'.format(text), layout=widgets.Layout(justify_content="center"))
        super().__init__(children=[textbox])

class SingleChoice(widgets.VBox):
    def __init__(self, text, correctChoice, *wrongChoices, sonst=False, inst=single):
        choices = list(wrongChoices)
        choices.append(correctChoice)
        choices.sort()
        buttons = [widgets.Button(description=choice, layout=widgets.Layout(width="250px")) for choice in choices]
        if sonst:
            buttons.append(
                widgets.Button(
                    description="Keine der anderen Möglichkeiten",
                    layout=widgets.Layout(width="250px")
                )
            )

        def on_button_clicked(b):
            choice = b.description
            if b.style.button_color == 'lightgreen' or b.style.button_color == 'red':
                b.style.button_color = None
            else:
                b.style.button_color = 'lightgreen' if choice == self.correct else 'red'

            if self.answered:
                #b.style.button_color = None
                #self.answered = False
                return
            self.answered = True

            # textbox.layout.border = "2px solid lightgreen" if choice == self.correct else "2px solid red"

        for button in buttons:
            button.on_click(on_button_clicked)

        allbox = []
        while not buttons == []:
            if len(buttons) > 2:
                allbox.append(widgets.HBox(children=[buttons[0], buttons[1]]))
                buttons.pop(0)
                buttons.pop(0)
            else:
                allbox.append(widgets.HBox(children=buttons))
                break

        textbox = widgets.HTML(value='
{}
'.format(text), layout=widgets.Layout(justify_content="center"))
        instbox = widgets.HTML(value='{}'.format(inst), layout=widgets.Layout(justify_content="center"))
        super().__init__(children=[textbox, instbox]+allbox)
        self.correct = correctChoice
        self.answered = False

class OpenQuestion(widgets.VBox):
    def __init__(self, text, solution, *other_correct_choices, is_correct_fun=None, inst=None):
        self.correct_choices = list(other_correct_choices)
        self.correct_choices.append(solution)
        self.is_correct_fun = is_correct_fun

        textbox = widgets.HTML(value='
{}
'.format(text))
        instbox = widgets.HTML(value='{}'.format(inst))
        answer_input = widgets.Text()
        submit_button = widgets.Button(description="OK")
        give_up_button = widgets.Button(description="Lösung zeigen")
        button_box = widgets.HBox(children=[submit_button, give_up_button])

        super().__init__(children=[textbox,instbox, answer_input, button_box])
        self.answered = False

        def on_ok_button_clicked(b):
            if self.answered:
                return

            given_answer = answer_input.value
            answer_input.layout.border = '2px solid lightgreen' if self.is_correct(given_answer) else '2px solid red'

        submit_button.on_click(on_ok_button_clicked)

        def on_show_solution_button_clicked(b):
            answer_input.value = solution
            answer_input.layout.border = '2px solid lightgreen'
            answer_input.disabled = True

        give_up_button.on_click(on_show_solution_button_clicked)

    def is_correct(self, answer):
        if answer in self.correct_choices:
            return True
        if self.is_correct_fun is not None:
            return self.is_correct_fun(answer)
        return False

class SelectionList(widgets.VBox):

    def __init__(self, text, correct, *wrong, sonst=False, inst=selection):
        self.selection = ""

        self.richtig = correct

        def makeAnswers(correct, wrong):
            allAnsw = ["Keine der Alternativen"] if sonst else []
            allAnsw.extend(wrong)
            allAnsw.append(correct)
            allAnsw.sort()
            return allAnsw

        allAnsw = makeAnswers(correct, list(wrong))
        self.selection=allAnsw[0]

        textbox = widgets.HTML(value='
{}
'.format(text))
        instbox = widgets.HTML(value='{}'.format(inst), layout=widgets.Layout(justify_content="center"))

        answer = widgets.Dropdown(options = allAnsw, value= allAnsw[0], description="Antwort:", layout={'width': '500px'})
        button = widgets.Button(description="Korrekt?",layout=widgets.Layout(width="250px"))
        super().__init__(children=[textbox, instbox, answer, button])

        def on_change_drop(change):
            if change['type'] == 'change' and change['name']=='value':
                    self.selection = change['new']

            button.style.button_color = None

        answer.observe(on_change_drop)

        def on_button_clicked(b):
                if  self.selection == self.richtig:
                    b.style.button_color = 'lightgreen'
                else:
                    b.style.button_color = 'red'

        button.on_click(on_button_clicked)

class Lueckentext(widgets.VBox):
    def __init__(self, text, to_replace, tree=False, inst=luecke):
        # to_replace ist dictionary mit 'word':'alternative list'
        instbox = widgets.HTML(value='{}'.format(inst), layout=widgets.Layout(justify_content="center"))

        repl = to_replace
        textlist = text.split(" ")
        self.richtig = text
        zusammen =  []
        self.selection = []
        self.wid_list = []

        def on_change_drop(change):
            if change['type'] == 'change' and change['name']=='value':
                    index = self.wid_list.index(change.owner)
                    self.selection[index] = change['new']
            button.style.button_color = None

        for word in textlist:
            try:
                choice = repl[word]
                if not word in choice:
                    choice.append(word)
                choice.sort()
                choice.append(" ")
                zw = ' '.join(zusammen)
                self.wid_list.append(widgets.HTML(value='
{}
'.format(zw), width='auto'))
                self.selection.append(zw)
                zusammen = []
                dropdown =widgets.Dropdown(options = choice, value=choice[len(choice)-1], layout=widgets.Layout(width="150px"))
                self.wid_list.append(dropdown)
                dropdown.observe(on_change_drop)
                self.selection.append(" ")

            except KeyError:
                zusammen.append(word)

        zw = ' '.join(zusammen)
        self.wid_list.append(widgets.HTML(value='
{}
'.format(zw)))
        self.selection.append(zw)

        box_layout = widgets.Layout(display='inline-flex', flex_flow='row wrap', align_items='stretch',flex='flex-grow', justify_content='flex-start', align_content="stretch")
        box = widgets.Box(children=self.wid_list, layout=box_layout)

        button = widgets.Button(description="Korrekt?",layout=widgets.Layout(width="250px"))

        super().__init__(children=[instbox,box,button])

        def on_button_clicked(b):
                sel = ' '.join(self.selection)
                if  sel == self.richtig:
                    b.style.button_color = 'lightgreen'
                    # if tree:
                    #     out=""
                    #     for elem in self.richtig:
                    #         out = out + elem

                    #     t = ParentedTree.fromstring(out)
                    #     display(t)
                else:
                    b.style.button_color = 'red'

        button.on_click(on_button_clicked)

class MultipleChoice(widgets.VBox):
    def __init__(self, text, correct, wrong, sonst=False, inst=multiple):
        self.chosenList = []
        if sonst == True:
            allAnsw = ["Keine der Alternativen"] + correct + wrong
        else:
            allAnsw = correct + wrong
        allAnsw.sort()
        self.myCor = correct
        self.myCor.sort()

        aufgabenstellung = HTML(value='
{}
'.format(text))
        instbox = widgets.HTML(value='{}'.format(inst), layout=widgets.Layout(justify_content="center"))

        button = Button(description="Korrekt?",layout=widgets.Layout(width="250px"))

        def on_change_check(change):
            if change['type'] == 'change' and change['name']=='value':
                if change['new'] == True:
                    box = change['owner']
                    d = box.description
                    self.chosenList.append(d)
                else:
                    box = change['owner']
                    if box.description in self.chosenList:
                        self.chosenList.remove(box.description)
            button.style.button_color = None

        cb = []
        style = {'description_width': 'initial'}
        for answer in allAnsw:
            cb.append(Checkbox(value=False, description=answer, disabled=False, style=style, layout=Layout(width="600px")))
            cb[-1].observe(on_change_check)

        box = widgets.VBox(children=cb)

        super().__init__(children=[aufgabenstellung, instbox, box, button])

        def on_button_clicked(button):
            self.chosenList.sort()
            if self.chosenList == self.myCor:
                button.style.button_color = 'lightgreen'
            else:
                button.style.button_color = 'red'

        button.on_click(on_button_clicked)

class OpenTextfield(widgets.VBox):
    def __init__(self, text, initial, correct, inst=None, klammer=False):

        textfield = widgets.Textarea(value=initial, placeholder='Type something', description='', disabled=False, layout=Layout(width='500px'))
        # textfield.observe(on)
        textbox = widgets.HTML(value='
{}
'.format(text))
        instbox = widgets.HTML(value='{}'.format(inst))

        submit_button = widgets.Button(description="Korrekt?", layout=widgets.Layout(width="350px"))
        give_up_button = widgets.Button(description="Lösung zeigen", layout=widgets.Layout(width="150px"))
        button_box = widgets.HBox(children=[submit_button, give_up_button])

        super().__init__(children=[textbox, instbox, textfield, button_box])

        def on_ok_button_clicked(button):
            given_answer = textfield.value
            ans = given_answer.split()
            answer = ''.join(ans)
            corr = correct.split()
            newc = ''.join(corr)

            if answer == newc:
                button.style.button_color = 'lightgreen'
                button.description = "Richtig!"

            else:
                button.style.button_color = 'red'

                if klammer:
                    more = True
                    stack = []
                    not_open = 0
                    for i,c in enumerate(given_answer):
                        if c == '[':
                            stack.append(i)
                        elif c == ']' and stack:
                            stack.pop()
                        elif c == ']':
                            not_open += 1
                        elif c in ['(',')','{','}']:
                            button.description="Falsche Klammern!"
                            more = False
                            break

                    if stack and more:
                        more = False
                        button.description =str(len(stack))+" Klammern schließen!"

                    if not_open and more:
                        more = False
                        button.description = str(not_open)+" Klammern öffnen!"

                    if more:
                        button.description = "Noch eine Übereinstimmung mit Synatxbaum erreicht!"

        def on_show_solution_button_clicked(button):
            textfield.value = correct
            textfield.disabled = True
            submit_button.disabled = True
            give_up_button.disabled = True

        submit_button.on_click(on_ok_button_clicked)
        give_up_button.on_click(on_show_solution_button_clicked)


#-*- encoding: utf-8 -*-

from __future__ import print_function
from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import division

import numpy as np
from itertools import permutations

n_cases = int(input())

for ctr in range(n_cases):
    n = int(input())
    imat = [tuple(input().split()) for _ in range(n)]

    mat = np.zeros((n, 2), dtype=np.int32)
    mapping = dict()
    n_uniq = 0
    for i in range(n):
        if imat[i][0] not in mapping:
            mapping[imat[i][0]] = n_uniq
            n_uniq += 1
        mat[i][0] = mapping[imat[i][0]]
        if imat[i][1] not in mapping:
            mapping[imat[i][1]] = n_uniq
            n_uniq += 1
        mat[i][1] = mapping[imat[i][1]]

    most_fake = 0
    for mask in range(1 << n):
        n_fake = 0
        fake = np.zeros(n, dtype=np.int8)
        for idx in range(n):
            if (mask >> idx) & 1:
                fake[idx] = 1
                n_fake += 1

        firsts = np.zeros(n_uniq, dtype=np.int8)
        seconds = np.zeros(n_uniq, dtype=np.int8)
        ok = True
        for i in range(n):
            if not fake[i]:
                firsts[mat[i][0]] = 1
                seconds[mat[i][1]] = 1
        for i in range(n):
            if not firsts[mat[i][0]] or not seconds[mat[i][1]]:
                ok = False
                break
        if ok:
            most_fake = max(n_fake, most_fake)

    print('Case #%d: %d' % (ctr+1, most_fake))


def check_sudoku(row, column, number, grid):
	for i in range(9):
		if grid[row][i] == number:
			return False
		if grid[i][column] == number:
			return False

	row = row - row%3
	column = column - column%3

	for i in range(row, row+3):
		for j in range(column, column+3):
			if grid[i][j] == number:
				return False
	return True

def find_next_empty_square(grid):
	for i in range(9):
		for j in range(9):
			if grid[i][j] == 0:
				return (i, j)

	return (-1, -1)

def solve_sudoku(grid):
	row, column = find_next_empty_square(grid)

	if (row, column) == (-1, -1):
		printSolution(grid)
		return

	for i in range(1, 10):
		if check_sudoku(row, column, i, grid):
			grid[row][column] = i
			if solve_sudoku(grid):
				return True
			grid[row][column] = 0

	return False

def printSolution(grid):
	for row in grid:
		print(*row)

grid = [[0, 0, 4, 7, 0, 6, 3, 0, 0],
		[0, 9, 0, 0, 0, 0, 0, 0, 0],
		[0, 0, 5, 0, 0, 1, 2, 8, 0],
		[0, 0, 0, 8, 0, 7, 0, 6, 3],
		[0, 0, 0, 0, 0, 0, 0, 0, 0],
		[5, 6, 0, 3, 0, 2, 0, 0, 0],
		[0, 3, 7, 1, 0, 0, 5, 0, 0],
		[0, 0, 0, 0, 0, 0, 0, 1, 0],
		[0, 0, 9, 6, 0, 8, 7, 0, 0],
		]

solve_sudoku(grid)


# Import the pandas library for reading CSV files
import pandas

# Read the 'nato_phonetic_alphabet.csv' file into a DataFrame called 'database'
database = pandas.read_csv('nato_phonetic_alphabet.csv')

# Create a dictionary called 'database_dict' where the keys are letters and the values are codes,
# using a dictionary comprehension to iterate through the rows of the 'database' DataFrame
database_dict = {row.letter: row.code for (index, row) in database.iterrows()}

# Define a function called 'generator'
def generator():
    # Get user input and convert it to uppercase to ensure consistency
    user_input = input('Enter Your Name: ').upper()

    try:
        # Use list comprehension to look up the codes for each letter in the user's input
        result = [database_dict[n] for n in user_input]
    except KeyError:
        # If a letter is not found in the 'database_dict', handle the KeyError and print an error message
        print('Sorry, only letters in the alphabet please.')
        # Call the 'generator' function recursively to prompt the user for input again
        generator()
    else:
        # If there are no exceptions, print the result (list of codes)
         print("Your Military Name ðŸ«¡ðŸª– :\n", " ".join(result))

# Call the 'generator' function to start the process
generator()