# -*- coding: utf-8 -*-
"""
Created on Mon Jul  3 08:08:17 2017

@author: ivyONS
"""
IVY_AUTHORISATION = ''###please enter yours credentials

DEFAULT_CONFIG =  {
    "subBuildingName":{
        "pafSubBuildingNameBoost":1.5,
        "lpiSaoTextBoost":1.5,
        "lpiSaoStartNumberBoost":1.0,
        "lpiSaoStartSuffixBoost":1.0,
        "lpiSaoPaoStartSuffixBoost": 0.5
    },
    "subBuildingRange": {
        "lpiSaoStartNumberBoost":1.0,
        "lpiSaoStartSuffixBoost":1.0,
        "lpiSaoEndNumberBoost":1.0,
        "lpiSaoEndSuffixBoost":1.0,
        "lpiSaoStartEndBoost":0.1
    },
    "buildingName":{
        "lpiPaoStartSuffixBoost":3.5,
        "pafBuildingNameBoost":2.5,
        "lpiPaoTextBoost":2.5,
        "lpiPaoStartNumberBoost":2.5,
        "lpiSaoPaoStartSuffixBoost": 0.5
    },
    "buildingNumber":{
        "pafBuildingNumberBoost":3.0,
        "lpiPaoStartNumberBoost":3.5,
        "lpiPaoEndNumberBoost":0.1
    },
    "buildingRange":{
        "lpiPaoStartNumberBoost":2.0,
        "lpiPaoStartSuffixBoost":2.0,
        "lpiPaoEndNumberBoost":2.0,
        "lpiPaoEndSuffixBoost":2.0,
        "pafBuildingNumberBoost":0.1,
        "lpiPaoStartEndBoost":0.1
    },
    "streetName":{
        "pafThoroughfareBoost":2.0,
        "pafWelshThoroughfareBoost":2.0,
        "pafDependentThoroughfareBoost":0.5,
        "pafWelshDependentThoroughfareBoost":0.5,
        "lpiStreetDescriptorBoost":2.0
    },
    "townName":{
        "pafPostTownBoost":1.0,
        "pafWelshPostTownBoost":1.0,
        "lpiTownNameBoost":1.0,
        "pafDependentLocalityBoost":0.5,
        "pafWelshDependentLocalityBoost":0.5,
        "lpiLocalityBoost":0.5,
        "pafDoubleDependentLocalityBoost":0.2,
        "pafWelshDoubleDependentLocalityBoost":0.2
    },
    "postcode":{
        "pafPostcodeBoost":1.0,
        "lpiPostcodeLocatorBoost":1.0,
        "postcodeInOutBoost":0.5,
        "postcodeOutBoost":0.8,
        "postcodeInBoost":0.3
    },
    "organisationName":{
        "pafOrganisationNameBoost":1.0,
        "lpiOrganisationBoost":1.0,
        "lpiPaoTextBoost":1.0,
        "lpiLegalNameBoost":1.0,
        "lpiSaoTextBoost":0.5
    },
    "departmentName":{
        "pafDepartmentNameBoost":1.0,
        "lpiLegalNameBoost":0.5
    },
    "locality":{
        "pafPostTownBoost":0.2,
        "pafWelshPostTownBoost":0.2,
        "lpiTownNameBoost":0.2,
        "pafDependentLocalityBoost":0.6,
        "pafWelshDependentLocalityBoost":0.6,
        "lpiLocalityBoost":0.6,
        "pafDoubleDependentLocalityBoost":0.3,
        "pafWelshDoubleDependentLocalityBoost":0.3
    },
    "fallback" :{
        "fallbackQueryBoost":0.5,
        "fallbackPafBoost":1.0,
        "fallbackLpiBoost":1.0,
        "fallbackPafBigramBoost":0.4,
        "fallbackLpiBigramBoost":0.4,
        "fallbackMinimumShouldMatch":"-40%",
        "bigramFuzziness": "0"
    },
    "nisra" : {
        "partialNiBoostBoost":1.1,
        "partialEwBoostBoost":0.5,
        "partialAllBoost":0.8,
        "fullFallBackNiBoost":1.0,
        "fullFallBackBigramNiBoost":0.4
    },
    "excludingDisMaxTieBreaker":0.0,
    "includingDisMaxTieBreaker":0.5,
    "topDisMaxTieBreaker":1.0,
    "paoSaoMinimumShouldMatch":"-45%",
    "organisationDepartmentMinimumShouldMatch":"30%",
    "mainMinimumShouldMatch":"-40%"
}


# Set up logging
import sys
import logging

logging.basicConfig(
    format="%(asctime)s - %(levelname)s - %(name)s -   %(message)s",
    datefmt="%m/%d/%Y %H:%M:%S",
    handlers=[logging.StreamHandler(sys.stdout)],
    level=logging.WARNING,
)
logger = logging.getLogger(__name__)

from typing import Optional
from dataclasses import dataclass, field
import os
import json
from contextlib import nullcontext
from alive_progress import alive_bar
from transformers.hf_argparser import HfArgumentParser
from transformers.models.auto import AutoConfig, AutoTokenizer, AutoModelForSeq2SeqLM
from seq2seq.utils.pipeline import ConversationalText2SQLGenerationPipeline, Text2SQLGenerationPipeline, Text2SQLInput, ConversationalText2SQLInput
from seq2seq.utils.picard_model_wrapper import PicardArguments, PicardLauncher, with_picard
from seq2seq.utils.dataset import DataTrainingArguments

@dataclass
class PredictionOutputArguments:
    """
    Arguments pertaining to execution.
    """

    model_path: str = field(
        default="tscholak/cxmefzzi",
        metadata={"help": "Path to pretrained model"},
    )
    cache_dir: Optional[str] = field(
        default="/tmp",
        metadata={"help": "Where to cache pretrained models and data"},
    )
    db_path: str = field(
        default="database",
        metadata={"help": "Where to to find the sqlite files"},
    )
    inputs_path: str = field(default="data/dev.json", metadata={"help": "Where to find the inputs"})
    output_path: str = field(
        default="predicted_sql.txt", metadata={"help": "Where to write the output queries"}
    )
    device: int = field(
        default=0,
        metadata={
            "help": "Device ordinal for CPU/GPU supports. Setting this to -1 will leverage CPU. A non-negative value will run the model on the corresponding CUDA device id."
        },
    )
    conversational: bool = field(default=False, metadata={"help": "Whether or not the inputs are conversations"})

def main():
    # See all possible arguments by passing the --help flag to this program.
    parser = HfArgumentParser((PicardArguments, PredictionOutputArguments, DataTrainingArguments))
    picard_args: PicardArguments
    prediction_output_args: PredictionOutputArguments
    data_training_args: DataTrainingArguments
    if len(sys.argv) == 2 and sys.argv[1].endswith(".json"):
        # If we pass only one argument to the script and it's the path to a json file,
        # let's parse it to get our arguments.
        picard_args, prediction_output_args, data_training_args = parser.parse_json_file(json_file=os.path.abspath(sys.argv[1]))
    else:
        picard_args, prediction_output_args, data_training_args = parser.parse_args_into_dataclasses()

    if os.path.isfile(prediction_output_args.output_path):
        raise RuntimeError("file `{}` already exists".format(prediction_output_args.output_path))

    # Initialize config
    config = AutoConfig.from_pretrained(
        prediction_output_args.model_path,
        cache_dir=prediction_output_args.cache_dir,
        max_length=data_training_args.max_target_length,
        num_beams=data_training_args.num_beams,
        num_beam_groups=data_training_args.num_beam_groups,
        diversity_penalty=data_training_args.diversity_penalty,
    )

    # Initialize tokenizer
    tokenizer = AutoTokenizer.from_pretrained(
        prediction_output_args.model_path,
        cache_dir=prediction_output_args.cache_dir,
        use_fast=True,
    )

    # Initialize Picard if necessary
    with PicardLauncher() if picard_args.launch_picard else nullcontext(None):
        # Get Picard model class wrapper
        if picard_args.use_picard:
            model_cls_wrapper = lambda model_cls: with_picard(
                model_cls=model_cls, picard_args=picard_args, tokenizer=tokenizer
            )
        else:
            model_cls_wrapper = lambda model_cls: model_cls

        # Initialize model
        model = model_cls_wrapper(AutoModelForSeq2SeqLM).from_pretrained(
            prediction_output_args.model_path,
            config=config,
            cache_dir=prediction_output_args.cache_dir,
        )

        if prediction_output_args.conversational:
            conversational_text2sql(model, tokenizer, prediction_output_args, data_training_args)
        else:
            text2sql(model, tokenizer, prediction_output_args, data_training_args)

def get_pipeline_kwargs(
    model, tokenizer: AutoTokenizer, prediction_output_args: PredictionOutputArguments, data_training_args: DataTrainingArguments
) -> dict:
    return {
        "model": model,
        "tokenizer": tokenizer,
        "db_path": prediction_output_args.db_path,
        "prefix": data_training_args.source_prefix,
        "normalize_query": data_training_args.normalize_query,
        "schema_serialization_type": data_training_args.schema_serialization_type,
        "schema_serialization_with_db_id": data_training_args.schema_serialization_with_db_id,
        "schema_serialization_with_db_content": data_training_args.schema_serialization_with_db_content,
        "device": prediction_output_args.device,
    }

def text2sql(model, tokenizer, prediction_output_args, data_training_args):
    # Initalize generation pipeline
    pipe = Text2SQLGenerationPipeline(**get_pipeline_kwargs(model, tokenizer, prediction_output_args, data_training_args))

    with open(prediction_output_args.inputs_path) as fp:
        questions = json.load(fp)

    with alive_bar(len(questions)) as bar:
        for question in questions:
            try:
                outputs = pipe(inputs=Text2SQLInput(question["question"],question["db_id"]))
                output = outputs[0]
                query = output["generated_text"]
            except Exception as e:
                logger.error(e)
                query = ""
            logger.info("writing `{}` to `{}`".format(query, prediction_output_args.output_path))
            bar.text(query)
            bar()
            with open(prediction_output_args.output_path, "a") as fp:
                fp.write(query + "\n")

def conversational_text2sql(model, tokenizer, prediction_output_args, data_training_args):
    # Initalize generation pipeline
    pipe = ConversationalText2SQLGenerationPipeline(
        **get_pipeline_kwargs(model, tokenizer, prediction_output_args, data_training_args)
    )

    with open(prediction_output_args.inputs_path) as fp:
        conversations = json.load(fp)

    length = sum(len(conversation["interaction"]) for conversation in conversations)
    with alive_bar(length) as bar:
        for conversation in conversations:
            utterances = []
            for turn in conversation["interaction"]:
                utterances.extend((utterance.strip() for utterance in turn["utterance"].split(sep="|")))
                try:
                    outputs = pipe(
                        inputs=ConversationalText2SQLInput(list(utterances),
                        db_id=conversation["database_id"])
                    )
                    output = outputs[0]
                    query = output["generated_text"]
                except Exception as e:
                    logger.error(e)
                    query = ""
                logger.info("writing `{}` to `{}`".format(query, prediction_output_args.output_path))
                bar.text(query)
                bar()
                with open(prediction_output_args.output_path, "a") as fp:
                    fp.write(query + "\n")

            with open(prediction_output_args.output_path, "a") as fp:
                fp.write("\n")

if __name__ == "__main__":
    main()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Feb 20 23 20:40:00

@author: kirsh012
"""

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import seaborn as sns
import joblib

from sklearn.model_selection import PredefinedSplit, GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import roc_curve, auc, precision_recall_curve
from sklearn.utils import class_weight

### Load custom modules
import nn_models as nnm
import dataprocessing as dp
import visualization as viz

### Load the data for comparison
data, varnames, target = dp.load_data_nn('1-sf', sensor='both', dlh=0, keep_SH=False, return_target=True)

# Split data into time oriented chunks
train_idx, test_idx, val_idx = nnm.split_data_cv_indx(data,target)

train_labels = target[train_idx]
test_labels = target[test_idx]
val_labels = target[val_idx]

print("Train labels shape: ", train_labels.shape)
print("Test labels shape: ", test_labels.shape)
print("Val labels shape: ", val_labels.shape)

train_data = data[train_idx,:]
test_data = data[test_idx,:]
val_data = data[val_idx,:]

print("Train shape: ", train_data.shape)
print("Test shape: ", test_data.shape)
print("Val shape: ", val_data.shape)

# Use indices to make PredefinedSplit for hyperparameter optimization
train_idx = np.full( (train_data.shape[0],) , -1, dtype=int)
val_idx  = np.full( (val_data.shape[0], ) , 0, dtype=int)

test_fold = np.append(train_idx, val_idx)
print(test_fold.shape)
ps = PredefinedSplit(test_fold)
print(ps)
combined_train_data   = np.vstack((train_data, val_data))
combined_train_labels = np.vstack((train_labels.reshape(-1,1), val_labels.reshape(-1,1))).ravel()
print("Combined train data shape: ", combined_train_data.shape)
print("Combined labels shape:", combined_train_labels)

param_grid = {
    'n_estimators': [100, 200, 500, 1000, 2000, 5000],
    'max_depth': [5, 10, 15, 20, 25, None]
}

# Compute the class weights
train_weights = class_weight.compute_class_weight(class_weight='balanced',
                                classes=np.unique(combined_train_labels), y=combined_train_labels)
train_weights = {i: weight for i, weight in enumerate(train_weights)}

from pathlib import Path
filename =  Path("tuned_rf_model_weighted.pkl")

### Save the model
if not filename.exists():

    print("Running the hyperparameter testing model...")
    clf = GridSearchCV(RandomForestClassifier(class_weight=train_weights), param_grid=param_grid, scoring='roc_auc_ovr_weighted', cv = ps, verbose=3)
    clf.fit(combined_train_data, combined_train_labels)

    joblib.dump(clf, filename)
else:
    clf = joblib.load(filename)

# Print hyperparameter esults
print("Report: \n", pd.DataFrame(clf.cv_results_))
print("Best inner loop score: ", clf.best_score_)
print("Best parameters: ", clf.best_params_)

# Predict on the anomalous
train_preds = clf.predict_proba(train_data)
test_preds  = clf.predict_proba(test_data)
val_preds   = clf.predict_proba(val_data)

### Visualize Performance
# Return AU-ROC
fpr_test, tpr_test, thresh_test     = roc_curve(test_labels, test_preds[:,1])
fpr_train, tpr_train, thresh_train  = roc_curve(train_labels, train_preds[:,1])
fpr_val, tpr_val, thresh_val        = roc_curve(val_labels, val_preds[:,1])

# Return AU-PRC
ppr_test, rec_test, pthresh_test    = precision_recall_curve(test_labels, test_preds[:,1])
ppr_train, rec_train, pthresh_train = precision_recall_curve(train_labels, train_preds[:,1])
ppr_val, rec_val, pthresh_val       = precision_recall_curve(val_labels, val_preds[:,1])

viz.plot_roc_curve(tpr_train, fpr_train, tpr_val, fpr_val, tpr_test, fpr_test, title = "RandomForest AU-ROC")

viz.plot_prc_curve(rec_train, ppr_train, rec_val, ppr_val, rec_test, ppr_test, title = "RandomForest AU-PRC")

plt.show()


import typing

from qittle.http.client import ABCHTTPClient, AiohttpClient
from .abc import ABCSessionManager

class SessionManager(ABCSessionManager):
    def __init__(self, http_client: typing.Optional[typing.Type[ABCHTTPClient]] = None):
        self.http_client = http_client or AiohttpClient
        self._active_session: typing.Optional[ABCHTTPClient] = None

    async def __aenter__(self) -> ABCHTTPClient:
        self._active_session = self.http_client()
        return self._active_session

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        await self._active_session.close()


import sys
from os.path import join

from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QListWidgetItem, QWidget
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt
import sqlite3
from functools import partial

class EditInfo(QWidget):
    def __init__(self, id) -> None:
        super().__init__()
        uic.loadUi(join("task5", "addEditCoffeeForm.ui"), self)
        self.id = id
        self.edit.clicked.connect(self.update)

    def update(self):
        db = sqlite3.connect(join("task5", "coffee.sqlite"))
        cur = db.cursor()
        try:
            name = self.bookTitle.text()
            elem1 = self.bookAuthor.text()
            elem2 = self.bookReleaseYear.text()
            desc = self.bookGenre.text()
            for i in [name, elem1, elem2, desc]:
                if not (bool(i) and bool(i.strip())):
                    raise ValueError
                for w in i:
                    if w.isdigit():
                        raise ValueError

            cs = float(self.costl.text())
            vl = float(self.volumel.text())
        except ValueError:
            self.errors.setText("Введены некорректные данные!!!")
        else:
            cur.execute(f'''
                        UPDATE coffee SET name_of_the_variety = ?, degree_of_roasting = ?,
                        ground_or_in_grains = ?,
                        taste_description = ?, cost = ?, packing_volume = ?

                        WHERE id = ?''',
                        [name, elem1, elem2, desc, cs, vl, self.id])

            db.commit()
            db.close()

    def addNewCoffeeSort(self):
        # req = INSERT INTO coffee (name_of_the_variety, degree_of_roasting, ground_or_in_grains, taste_description, cost, packing_volume)
        # VALUES ("1", "1", "1", "1", 1, 1)
        db = sqlite3.connect(join("task5", "coffee.sqlite"))
        cur = db.cursor()
        try:
            name = self.bookTitle.text()
            elem1 = self.bookAuthor.text()
            elem2 = self.bookReleaseYear.text()
            desc = self.bookGenre.text()
            for i in [name, elem1, elem2, desc]:
                if not (bool(i) and bool(i.strip())):
                    raise ValueError
                for w in i:
                    if w.isdigit():
                        raise ValueError

            cs = float(self.costl.text())
            vl = float(self.volumel.text())
        except ValueError:
            self.errors.setText("Введены некорректные данные!!!")

        cur.execute(f'''
                    INSERT INTO coffee (name_of_the_variety, degree_of_roasting, ground_or_in_grains, taste_description, cost, packing_volume)
                    VALUES (?, ?, ?, ?, ?, ?)''',
                    [name, elem1, elem2, desc, cs, vl])

        db.commit()
        db.close()

class AddNewInfo(QWidget):
    def __init__(self) -> None:
        super().__init__()
        uic.loadUi(join("task5", "addEditCoffeeForm2.ui"), self)
        self.add.clicked.connect(self.addNewItem)

    def addNewItem(self):
        db = sqlite3.connect(join("task5", "coffee.sqlite"))
        cur = db.cursor()
        try:
            name = self.bookTitle.text()
            elem1 = self.bookAuthor.text()
            elem2 = self.bookReleaseYear.text()
            desc = self.bookGenre.text()
            for i in [name, elem1, elem2, desc]:
                if not (bool(i) and bool(i.strip())):
                    raise ValueError
                for w in i:
                    if w.isdigit():
                        raise ValueError

            cs = float(self.costl.text())
            vl = float(self.volumel.text())
        except ValueError:
            self.errors.setText("Введены некорректные данные!!!")
        else:
            cur.execute(f'''
                        INSERT INTO coffee (name_of_the_variety, degree_of_roasting, ground_or_in_grains, taste_description, cost, packing_volume)
                        VALUES (?, ?, ?, ?, ?, ?)''',
                        [name, elem1, elem2, desc, cs, vl])

            db.commit()
            db.close()

class MyWidget(QMainWindow):
    def __init__(self) -> None:
        super().__init__()
        uic.loadUi(join("task5", "main.ui"), self)
        self.btn.clicked.connect(self.search)
        self.addNewCoffe.clicked.connect(self.addSomeInfo)

    def search(self):
        self.listWidget.clear()
        # searchText = self.lineEdit.text()
        # db = sqlite3.connect(join("QT_Standalone", "task7", "books.db"))
        db = sqlite3.connect(join("task5", "coffee.sqlite"))
        cur = db.cursor()
        res = cur.execute(
            f'''SELECT * FROM coffee''')

        for elem in res:
            # print(elem)
            btn = QPushButton(f"{elem[1]}(нажми для большей информации)", self)

            clickFunc = partial(self.some, elem[0], elem[1],
                                elem[2], elem[3], elem[4], elem[5], elem[6])
            btn.clicked.connect(clickFunc)

            item = QListWidgetItem()
            item.setSizeHint(btn.sizeHint())
            self.listWidget.addItem(item)
            self.listWidget.setItemWidget(item, btn)

    def some(self, id, name, author, year, genre, cost, volume):
        self.pop = EditInfo(id)
        # там снизу есть нужные поля для ввода
        self.pop.bookAuthor.setText(author)
        self.pop.bookTitle.setText(name)
        self.pop.bookGenre.setText(genre)
        self.pop.bookReleaseYear.setText(str(year))
        self.pop.costl.setText(str(cost))
        self.pop.volumel.setText(str(volume))

        self.pop.show()

    def addSomeInfo(self):
        self.pop2 = AddNewInfo()
        self.pop2.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyWidget()
    ex.show()
    # print(eval("9!"))
    sys.exit(app.exec_())


from django.shortcuts import render, redirect, reverse, get_object_or_404
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import View

from .forms import (CreateCourseForm,
                    CreateCourseRegistrationForm,
                    CreateDepartmentForm,
                    CreateRegistrationForm)

from .models import Course, CourseRegistration, Department, Registration

import datetime
from django.utils import timezone

class CreateCourseView(LoginRequiredMixin, View):
    """
    View for admin to create new Course.
    """

    template_name = 'academicInfo/create_course.html'
    create_course_form = CreateCourseForm

    def get(self, request, *args, **kwargs):

        # Render this page only for the Admin.
        if hasattr(request.user, 'staff') and request.user.staff.is_admin:
            create_course_form = self.create_course_form()
            return render(request, self.template_name, {'create_course_form' : create_course_form})
        else:
            return redirect('home')

    def post(self, request, *args, **kwargs):
        create_course_form = CreateCourseForm(request.POST)

        if create_course_form.is_valid():
            course = create_course_form.save()
            course.save()

            return redirect('view_course')

        return render(request, self.template_name, {'create_course_form' : create_course_form})

class CreateCourseRegistrationView(LoginRequiredMixin, View):
    """
    View for admin to add Course to the Registration.
    """

    template_name = 'academicInfo/create_course_registration.html'
    create_course_registration_form = CreateCourseRegistrationForm

    def get(self, request, *args, **kwargs):

        # Render this page only for the Admin.
        if hasattr(request.user, 'staff') and request.user.staff.is_admin:
            create_course_registration_form = self.create_course_registration_form()
            return render(request, self.template_name, {'create_course_registration_form' : create_course_registration_form})
        else:
            return redirect('home')

    def post(self, request, *args, **kwargs):
        create_course_registration_form = CreateCourseRegistrationForm(request.POST)

        if create_course_registration_form.is_valid():

            # Add course to registration only if this course is not added already
            # in this registration.
            course_registration = create_course_registration_form.save(commit=False)

            # Check if the registration has already started.
            if course_registration.registration.startTime <= timezone.now():
                create_course_registration_form.add_error('registration',
                                                          'The registration has already started, you cannot add course to it now.')
                return render(request, self.template_name, {'create_course_registration_form' : create_course_registration_form})

            courses_in_registration = course_registration.registration.courseregistration_set.all()
            similar_course_registration = courses_in_registration.filter(course=course_registration.course,
                                                                         semester=course_registration.semester)

            # Check if course is not already present in the same registration and semester.
            if len(similar_course_registration) == 0:
                course_registration.save()
                return render(request, self.template_name, {'create_course_registration_form' : create_course_registration_form,
                                                            'success': 'Successfully added course to the registration.'})
            else:
                create_course_registration_form.add_error('course', 'This course is already added in this semester.')
                create_course_registration_form.add_error('semester', 'This semester already has this course.')

        return render(request, self.template_name, {'create_course_registration_form' : create_course_registration_form})

class CreateDepartmentView(LoginRequiredMixin, View):
    """
    View for admin to add new Department.
    """

    template_name = 'academicInfo/create_department.html'
    create_department_form = CreateDepartmentForm

    def get(self, request, *args, **kwargs):

        # Render this page only for the Admin.
        if hasattr(request.user, 'staff') and request.user.staff.is_admin:
            create_department_form = self.create_department_form()
            return render(request, self.template_name, {'create_department_form' : create_department_form})
        else:
            return redirect('home')

    def post(self, request, *args, **kwargs):
        create_department_form = CreateDepartmentForm(request.POST)

        # Check if Department with same name does not already exist.
        if create_department_form.is_valid():
            department = create_department_form.save()
            department.save()
            return redirect('view_department')
        else:
            return render(request, self.template_name, {'create_department_form' : create_department_form})

class CreateRegistrationView(LoginRequiredMixin, View):
    """
    View for admin to create new Registration.
    """

    template_name = 'academicInfo/create_registration.html'
    create_registration_form = CreateRegistrationForm

    def get(self, request, *args, **kwargs):

        # Render this page only for the Admin.
        if hasattr(request.user, 'staff') and request.user.staff.is_admin:
            create_registration_form = self.create_registration_form()
            return render(request, self.template_name, {'create_registration_form' : create_registration_form})
        else:
            return redirect('home')

    def post(self, request, *args, **kwargs):
        create_registration_form = CreateRegistrationForm(request.POST)

        # Check if the Registration form is valid.
        if create_registration_form.is_valid():
            days = int(request.POST['days'])
            hours = int(request.POST['hours'])
            minutes = int(request.POST['minutes'])

            # Check if duration is 0 or not.
            if days + hours + minutes == 0:

                # Duration cannot be 0.
                return render(request, self.template_name, {'create_registration_form' : create_registration_form,
                                                            'error' : 'Duration cannot be 0.'})

            startTime = create_registration_form.cleaned_data['startTime']
            duration = datetime.timedelta(days=days, hours=hours, minutes=minutes)
            endTime = startTime + duration
            registration = Registration.objects.create(name=create_registration_form.cleaned_data['name'],
                                                       startTime=startTime,
                                                       duration=duration,
                                                       endTime=endTime)

            registration.save()
            return redirect('registration')

        return render(request, self.template_name, {'create_registration_form' : create_registration_form})

class RegistrationsView(View):
    """
    View for everyone to view all the registrations.
    """

    template_name = 'academicInfo/registration.html'

    def get(self, request, *args, **kwargs):

        time = timezone.now()

        future_registrations = Registration.objects.filter(startTime__gt=time).order_by('startTime')
        present_registrations = Registration.objects.filter(
                                                            endTime__gt=time
                                                            ).exclude(startTime__gt=time).order_by('endTime')
        past_registrations = Registration.objects.filter(endTime__lt=time)

        return render(request, self.template_name, {'future_registrations': future_registrations,
                                                    'present_registrations': present_registrations,
                                                    'past_registrations': past_registrations})

class LiveRegistrationView(LoginRequiredMixin, View):
    """
    View for student to register and unregister from live registrations.
    """

    template_name = 'academicInfo/live_registration.html'

    def get(self, request, *args, **kwargs):

        # Render this page only for the students.
        if hasattr(request.user, 'student'):

            registration = get_object_or_404(Registration, pk=self.kwargs['registration_id'])
            time = timezone.now()

            # Check if registration is currently live.
            if registration.startTime < time and registration.endTime > time:

                student = request.user.student

                # Show courses which are in either current semester or the next semester of student.
                courses_in_registration = registration.courseregistration_set.all()
                course_registration = courses_in_registration.filter(
                                                                     semester__gt=student.get_student_semester
                                                                     ).exclude(semester__gt=student.get_student_semester+1)
                return render(request, self.template_name, {'course_registration' : course_registration,
                                                            'student_courses' : student.courseregistration_set.all()})
            else:
                return redirect('registration')

        else:
            return redirect('home')

    def post(self, request, *args, **kwargs):

        # Only students should be allowed to register.
        if hasattr(request.user, 'student'):

            course_registration = get_object_or_404(CourseRegistration,
                                                    pk=request.POST['course_registration_id'])
            registration = course_registration.registration
            currTime = timezone.now()
            student = request.user.student
            semester = student.get_student_semester

            # If student wants to register for the course.
            if 'Register' in request.POST:
                if (currTime > registration.startTime and
                    currTime < registration.endTime and
                    course_registration.semester in range(semester, semester+2)):

                    if (not student in course_registration.students.all() and
                        course_registration.remaining_seats > 0):
                        course_registration.students.add(student)

                    return redirect(reverse('live_registration',
                                                kwargs={'registration_id' : registration.id}))

                else:
                    return redirect('home')

            # If student wants to unregister from the course.
            elif 'UnRegister' in request.POST:
                if (currTime > registration.startTime and
                    currTime < registration.endTime and
                    student in course_registration.students.all()):
                    course_registration.students.remove(student)

                return redirect(reverse('live_registration',
                                        kwargs={'registration_id' : registration.id}))

        else:
            return redirect('home')

class DepartmentsView(LoginRequiredMixin, View):
    """
    View for admin to see departments and add new department.
    """

    template_name = 'academicInfo/departments.html'

    def get(self, request, *args, **kwargs):

        # Render this page only for the Admin.
        if hasattr(request.user, 'staff') and request.user.staff.is_admin:
            departments = Department.objects.all()
            return render(request, self.template_name, {'departments' : departments})
        else:
            return redirect('home')

class CourseView(LoginRequiredMixin, View):
    """
    View for admin to see Courses and add new Course.
    """

    template_name = 'academicInfo/courses.html'

    def get(self, request, *args, **kwargs):

        # Render this page only for the Admin.
        if hasattr(request.user, 'staff') and request.user.staff.is_admin:
            courses = Course.objects.all()
            return render(request, self.template_name, {'courses' : courses})
        else:
            return redirect('home')


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Jan 18 12:44:53 2022

@author: mathaes
"""
import copy

class HexBoard:
    """
    The HexBoard class represents a state of a game of Hex on an
    n x n hexagonal-parallelogram board.

    The two players are represented by X and O.

    One player plays in the left-right (across columns) and
    the other in the top-bottom (across rows).  These can
    be changed but the default is that O plays first, in left-right direction.
    """

    EMPTY_TOKEN = '-'
    X_TOKEN = 'X'
    O_TOKEN = 'O'

    def __init__(self,
                 size=11,
                 first_player = O_TOKEN,
                 lr_player = O_TOKEN):
        self.size = size
        self.first_player = first_player
        self.lr_player = lr_player
        self.label = '0'
        self.clear()

    def __repr__(self):
        strrep = ''
        for row in range(0, self.size):
            if row == int(self.size / 2):
                strrep += self.lr_player
                strrep += ' ' * (row)
            else:
                strrep += ' ' * (row + 1)

            for col in range(0, self.size):
                curValue = self.getTileValue(row, col)
                strrep += curValue
                if col < self.size - 1:
                    strrep += ' '

            strrep += '\n'

        if None != self.label:
            strrep += f"({self.label})\n"

        return strrep

    def __copy__(self):
        clone = HexBoard()
        clone.size = self.size
        clone.first_player = self.first_player
        clone.lr_player = self.lr_player
        clone.board = copy.deepcopy(self.board)
        clone.label = self.label
        return clone

    def copy(self):
        return copy.copy(self)

    def getTileValue(self, row, col):
        if row < 0 or col < 0 or row >= self.size or col >= self.size:
            raise Exception(f"Coordinate ({row},{col}) is out of range for this board.")

        return self.board[row][col]

    def playX(self, row, col):
        if self.getNextPlayer() != self.X_TOKEN:
            raise Exception("playX called but next player is not X")

        cur = self.getTileValue(row, col)
        if not HexBoard.EMPTY_TOKEN == cur:
            raise Exception(f"Coordinate ({row},{col}) is {cur} (not unset).")

        self.board[row][col] = HexBoard.X_TOKEN

    def playO(self, row, col):
        if self.getNextPlayer() != self.O_TOKEN:
            raise Exception("playX called but next player is not X")

        cur = self.getTileValue(row, col)
        if not HexBoard.EMPTY_TOKEN == cur:
            raise Exception(f"Coordinate ({row},{col}) is {cur} (not unset).")

        self.board[row][col] = HexBoard.O_TOKEN

    def getSelfPlayer(self):
        """
        Determine which player played last for the current board state.

        Returns
        -------
        Either TOKEN_X or TOKEN_O, unless the board is empty
        in which case it returns TOKEN_EMPTY

        """
        xcount = self.countXTiles()
        ocount = self.countOTiles()

        if self.first_player == HexBoard.O_TOKEN:
            if xcount == ocount:
                return HexBoard.X_TOKEN
            elif xcount == ocount-1:
                return HexBoard.O_TOKEN
            else:
                raise Exception(f"Bad board state: O goes first but there are {ocount} O tiles and {xcount} X tiles")

        elif self.first_player == HexBoard.X_TOKEN:
            if xcount == ocount:
                return HexBoard.O_TOKEN
            elif ocount == xcount-1:
                return HexBoard.X_TOKEN
            else:
                raise Exception(f"Bad board state: X goes first but there are {ocount} O tiles and {xcount} X tiles")

        return HexBoard.EMPTY_TOKEN

    def getNextPlayer(self):
        """
        Determine which player plays next from the current board state.

        Returns
        -------
        Either TOKEN_X or TOKEN_O, unless the game is over
        in which case it returns TOKEN_EMPTY

        """
        if self.isGameOver():
            return HexBoard.EMPTY_TOKEN
        cur = self.getSelfPlayer()
        if cur == HexBoard.O_TOKEN:
            return HexBoard.X_TOKEN
        elif cur == HexBoard.X_TOKEN:
            return HexBoard.O_TOKEN

        return HexBoard.EMPTY_TOKEN

    def clear(self):
        self.board = []
        for n in range(0, self.size):
            self.board.append([HexBoard.EMPTY_TOKEN] * self.size)

    def getTileCoordinatesOfValue(self, value):
        coords = []
        for i in range(0, self.size):
            for j in range(0, self.size):
                cur = self.getTileValue(i, j)
                if cur == value:
                    coords.append([i, j])
        return coords

    def countXTiles(self):
        return self.countTiles(HexBoard.X_TOKEN)

    def countOTiles(self):
        return self.countTiles(HexBoard.O_TOKEN)

    def countEmptyTiles(self):
        return self.countTiles(HexBoard.EMPTY_TOKEN)

    def countTiles(self, value):
        count = 0
        for i in range(0, self.size):
            for j in range(0, self.size):
                cur = self.getTileValue(i, j)
                if cur == value:
                    count += 1
        return count

    def getXTiles(self):
        return self.getTileCoordinatesOfValue(HexBoard.X_TOKEN)

    def getOTiles(self):
        return self.getTileCoordinatesOfValue(HexBoard.O_TOKEN)

    def getEmptyTiles(self):
        return self.getTileCoordinatesOfValue(HexBoard.EMPTY_TOKEN)

    def adjacent(tile1, tile2):
        rowDiff = tile1[0] - tile2[0]
        colDiff = tile1[1] - tile2[1]
        rowAdjacent = rowDiff == 0 and abs(colDiff) == 1
        colAdjacent = colDiff == 0 and abs(rowDiff) == 1
        diagAdjacent = abs(rowDiff) == 1 and rowDiff + colDiff == 0
        return rowAdjacent or colAdjacent or diagAdjacent

    def adjacentIndexes(tile, tileArray):
        indexes = []
        for n in range(0, len(tileArray)):
            if HexBoard.adjacent(tile, tileArray[n]):
                indexes.append(n)
        return indexes

    def getConnectedOBlocks(self):
        return HexBoard.getBlocks(self.getOTiles())

    def getConnectedXBlocks(self):
        return HexBoard.getBlocks(self.getXTiles())

    def getBlocks(tiles):
        """
        Given a set of tiles, return them partitioned into
        blocks of adjacent tiles

        Parameters
        ----------
        tiles : list
            A list of tile coordinates

        Returns
        -------
        blocks : list of lists
            A list coordinate-list blocks, where each block
            is a group of connected coordinates (by hexagonal adjacency)
        """
        blocks = []
        while len(tiles) > 0:
            nextTile = tiles.pop(0)
            block = HexBoard.recursiveAdjacencies(nextTile, tiles)
            block.append(nextTile)
            block.sort()
            blocks.append(block)

        return blocks

    def recursiveAdjacencies(tile, tileArray):
        adjacencies = []
        adjixs = HexBoard.adjacentIndexes(tile, tileArray)
        if len(adjixs) == 0:
            return []

        adjixs.sort()
        adjixs.reverse()
        subtiles = []

        for ix in adjixs:
            subtile = tileArray.pop(ix)
            subtiles.append(subtile)
        adjacencies.extend(subtiles)

        for sub in subtiles:
            more = HexBoard.recursiveAdjacencies(sub, tileArray)
            if len(more) > 0:
                adjacencies.extend(more)

        return adjacencies

    def isXWin(self):
        check_lr = self.lr_player == HexBoard.X_TOKEN
        xblocks = self.getConnectedXBlocks()
        for xblock in xblocks:
            if check_lr:
                if self.block_spans_lr(xblock):
                    return True
            else:
                if self.block_spans_tb(xblock):
                    return True

        return False

    def isOWin(self):
        check_lr = self.lr_player == HexBoard.O_TOKEN
        oblocks = self.getConnectedOBlocks()
        for oblock in oblocks:
            if check_lr:
                if self.block_spans_lr(oblock):
                    return True
            else:
                if self.block_spans_tb(oblock):
                    return True

        return False

    def block_spans_lr(self, block):
        # we assume the block is connected, so we
        # just look for an element with 0 first entry
        # and one with size-1 first entry
        foundLeft = False
        foundRight = False
        for coord in block:
            if coord[0] == 0:
                foundLeft = True
            elif coord[0] == self.size - 1:
                foundRight = True
            if foundLeft and foundRight:
                return True

        return False

    def block_spans_tb(self, block):
        # we assume the block is connected, so we
        # just look for an element with 0 first entry
        # and one with size-1 first entry
        foundTop = False
        foundBottom = False
        for coord in block:
            if coord[1] == 0:
                foundTop = True
            elif coord[1] == self.size - 1:
                foundBottom = True
            if foundTop and foundBottom:
                return True

        return False

    def isGameOver(self):
        if self.countEmptyTiles() == 0:
            return True

        return self.isXWin() or self.isOWin()


"""Destroy unused AMIs in your AWS account.

Usage:
    ami_destroyer.py <requiredtag> [options]

Arguments:
    <requiredtag>               Tag required for an AMI to be cleaned up in the form tag:NameOfTag

Options:
    --retain=<retain>           Number of images to retain, sorted newest to latest [default: 2]
    --regions=<regions>         A comma-separated list of AWS Regions to run against [default: us-east-1]
    --help                      Show this help string
    --dryrun                    List the AMIs that'll be destroyed by this script
"""
import sys
import logging
from operator import itemgetter
from docopt import docopt
import boto3
import botocore.exceptions as botoex

_LOGGER = logging.Logger("ami-destroyer")

def setup_logging():
    _LOGGER.setLevel(logging.INFO)
    handler = logging.StreamHandler(sys.stdout)
    formatter = logging.Formatter('%(asctime)s : %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    _LOGGER.addHandler(handler)

def get_account_id():
    acctid = sts.get_caller_identity().get('Account')
    _LOGGER.info("Retrieving Account ID: {}".format(acctid))
    return acctid

def get_curated_images(tagname, accountid):
    _LOGGER.info("Retrieving AMIs with {}".format(tagname))
    return ec2.images.filter(
        Owners=[accountid],
        Filters=[
            {
                'Name':tagname,
                'Values':['True']
            }
        ]
)

def sort_curated_images(curatedimages):
    _LOGGER.info("Sorting tagged AMIs into a nice dictionary of lists of dictionaries")
    sortedimages = {}
    for i in curatedimages:
        for tag in i.tags:
            if tag['Key'] == 'Name':
                iname = tag['Value']
                break
            else:
                iname = "nonametag"
        if iname not in sortedimages:
            sortedimages[iname] = []
        sortedimages[iname].append({
            'creation_date': i.creation_date,
            'ami_id': i.image_id,
            'snapshot_id': i.block_device_mappings[0]['Ebs']['SnapshotId']
        })
        sortedimages[iname] = sorted(
            sortedimages[iname],
            key=itemgetter('creation_date'),
            reverse=True
        )
    return sortedimages

def prune_sorted_images(images, retain):
    for family in images:
        _LOGGER.info(
            "Found {} tagged images for type {}. Retaining the latest {}".format(
                len(images[family]),
                family,
                retain
            )
        )
        images[family] = images[family][retain:]
        if not images[family]:
            _LOGGER.info("No images to prune for {}".format(family))
    return images

def destroy_ami(ami_id, family, dryrun):
    try:
        ec2.Image(ami_id).deregister(DryRun=dryrun)
        _LOGGER.info("Family: {} - Deregistered {}".format(family, ami_id))
    except botoex.ClientError as e:
        _LOGGER.warning("{} - {}".format(ami_id, e))

def destroy_snapshot(snapshot_id, family, dryrun):
    try:
        ec2.Snapshot(snapshot_id).delete(DryRun=dryrun)
        _LOGGER.info("Family: {} - Deleted {}".format(family, snapshot_id))
    except botoex.ClientError as e:
        _LOGGER.warning("{} - {}".format(snapshot_id, e))

def run(tag, retain, dryrun):
    acctid = get_account_id()
    curatedimages = get_curated_images(tag, acctid)
    sortedimages = sort_curated_images(curatedimages)
    if sortedimages:
        prunedimages = prune_sorted_images(sortedimages, numretain)

        for family in prunedimages:
            if prunedimages[family]:
                for ami in prunedimages[family]:
                    destroy_ami(ami['ami_id'], family, dryrun)
                    destroy_snapshot(ami['snapshot_id'], family, dryrun)
    else:
        _LOGGER.error("No tagged images to prune")

if __name__ == '__main__':
    args = docopt(__doc__)
    requiredtag = args['<requiredtag>']
    dryrun = args['--dryrun']
    numretain = int(args['--retain'])
    regions = args['--regions']
    setup_logging()

    for r in regions.split(','):
        _LOGGER.info("##### Running cleanup for region {} #####".format(r))
        ec2 = boto3.resource('ec2', region_name=r)
        sts = boto3.client('sts')

        run(requiredtag, numretain, dryrun)


import time
import unittest

import s1ap_types
from integ_tests.s1aptests import s1ap_wrapper
from integ_tests.s1aptests.s1ap_utils import MagmadUtil, SpgwUtil

class TestAttachNwInitiatedDetachFail(unittest.TestCase):
    """
    S1AP Integration test for Failed Network Initiated Detach
    """

    def setUp(self):
        """Initialize s1ap wrapper and spgw utility
        """
        self._s1ap_wrapper = s1ap_wrapper.TestWrapper(
            stateless_mode=MagmadUtil.stateless_cmds.ENABLE,
        )
        self._spgw_util = SpgwUtil()

    def tearDown(self):
        """Clean up utilities and sctp connection
        """
        self._s1ap_wrapper.cleanup()

    def test_attach_nw_initiated_detach_fail(self):
        """
        The test case validates retransmission of Detach Request after MME
        restarts
        Step 1: UE attaches to network
        Step 2: Send request to delete default bearer, since deletion is
                invoked for default bearer, MME initiates detach procedure
        Step 3: MME starts 3422 timer to receive Detach Accept message
        Step 4: S1AP tester ignores and does not send Detach Accept
        """
        self._s1ap_wrapper.configUEDevice(1)

        req = self._s1ap_wrapper.ue_req
        print(
            "********************** Running End to End attach for ",
            "UE id ",
            req.ue_id,
        )
        # Now actually complete the attach
        attach = self._s1ap_wrapper._s1_util.attach(
            req.ue_id,
            s1ap_types.tfwCmd.UE_END_TO_END_ATTACH_REQUEST,
            s1ap_types.tfwCmd.UE_ATTACH_ACCEPT_IND,
            s1ap_types.ueAttachAccept_t,
        )

        # Wait on EMM Information from MME
        self._s1ap_wrapper._s1_util.receive_emm_info()

        print("Sleeping for 5 seconds")
        time.sleep(5)
        print(
            "********************** Deleting default bearer for IMSI",
            "".join([str(i) for i in req.imsi]),
        )
        # Delete default bearer
        self._spgw_util.delete_bearer(
            "IMSI" + "".join([str(i) for i in req.imsi]),
            attach.esmInfo.epsBearerId,
            attach.esmInfo.epsBearerId,
        )
        # Receive NW initiated detach request
        # Wait for timer 3422 expiry 5 times
        for _ in range(5):
            response = self._s1ap_wrapper.s1_util.get_response()
            assert response.msg_type == s1ap_types.tfwCmd.UE_NW_INIT_DETACH_REQUEST.value
            print("**************** Received NW initiated Detach Req")

        time.sleep(6)

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


#!usr/bin/python

import os
import SimpleITK as sitk
import numpy as np
import scipy.ndimage.interpolation
import skimage.exposure
import skimage.filters
import skimage.transform

path="//Users//zhangyuwei//Desktop//test"
ShrinkFactor = 4

for i in os.walk(path):
    for j in range(len(i[2])):
        if os.path.splitext(i[2][j])[1] == ".gz" :
            print(os.path.splitext(i[2][j])[0])
            nifti_file = sitk.ReadImage(os.path.join(i[0],i[2][j]))
            mask_img   = sitk.BinaryThreshold(nifti_file, 80, 5000)

            mask_filename    = "globalmask_" + os.path.splitext(i[2][j])[0] + ".gz"
            output_filename  = "N4ITKcorrected_" + os.path.splitext(i[2][j])[0] + ".gz"
            output_biasname1 = "bias_in_" + os.path.splitext(i[2][j])[0] + ".gz"
            output_biasname2 = "bias_out_" + os.path.splitext(i[2][j])[0] + ".gz"
            sitk.WriteImage(mask_img, mask_filename)

            nifti_shape  = sitk.GetArrayFromImage(nifti_file)
            nifti_shape  = nifti_shape.shape

            # Call and initialize an N4 corrector instance.
            corrector                              = sitk.N4BiasFieldCorrectionImageFilter()
            corrector.SetMaximumNumberOfIterations = 50
            corrector.SetNumberOfHistogramBins     = 128
            corrector.SetSplineOrder               = 10
            corrector.SetConvergenceThreshold      = 0.001
            corrector.SetNumberOfControlPoints     = 8
            print("> Initializing Compelete!")

            if ShrinkFactor > 1 :

                shrinked_img  = sitk.Shrink(nifti_file, [ShrinkFactor] * nifti_file.GetDimension())
                shrinked_mask = sitk.Shrink(mask_img, [ShrinkFactor] * nifti_file.GetDimension())

                shrinked_img = sitk.Cast(shrinked_img, sitk.sitkFloat32)
                #shrinked_mask = sitk.Cast(shrinked_mask, sitk.sitkFloat32)

                print("> Starting Execution...")
                corrected_img = corrector.Execute(shrinked_img, shrinked_mask)
                print("> Execution Complete!")

                # Estimate the bias field of corrected image
                re_corrected = corrector.Execute(corrected_img, shrinked_mask)
                print("> Corrected Bias Estimation Complete!")

                corrected_img = sitk.GetArrayFromImage(corrected_img)
                corrected_img[corrected_img == 0] = 0.001
                re_corrected = sitk.GetArrayFromImage(re_corrected)
                re_corrected[re_corrected == 0] = 0.001
                shrinked_img = sitk.GetArrayFromImage(shrinked_img)

                # Generate biasfield
                shrinked_bias  = shrinked_img / corrected_img
                corrected_bias = corrected_img / re_corrected

                # Output
                output_bias  = scipy.ndimage.zoom(shrinked_bias, np.array(nifti_shape) / shrinked_bias.shape)
                output_bias2 = scipy.ndimage.zoom(corrected_bias, np.array(nifti_shape) / shrinked_bias.shape)
                output_img   = sitk.GetArrayFromImage(nifti_file) / output_bias

                output_bias  = sitk.GetImageFromArray(output_bias)
                output_bias2 = sitk.GetImageFromArray(output_bias2)
                output_img   = sitk.Cast(sitk.GetImageFromArray(output_img), sitk.sitkUInt16)

                sitk.WriteImage(output_img, output_filename)
                sitk.WriteImage(output_bias, output_biasname1)
                sitk.WriteImage(output_bias2, output_biasname2)
                print("> Save Complete!")

            else:
                source_img = sitk.Shrink(nifti_file, [ShrinkFactor] * nifti_file.GetDimension())
                mask_img   = sitk.Shrink(mask_img, [ShrinkFactor] * mask_img.GetDimension())
                source_img = sitk.Cast(source_img, sitk.sitkFloat32)

                output_img = corrector.Execute(source_img, mask_img)
                output_img = sitk.Cast(output_img, sitk.sitkUInt16)

                sitk.WriteImage(output_img, output_filename)
                #biasfield_img = source_img / output_img
                #biasfield_img[biasfield_img <  0.5] = 0.5


# Filename  : 02-添加子类属性.py
# Date  : 2018/8/2
"""
对象属性的继承：是通过继承init方法来继承的对象属性
给当前类添加对象属性：重写init方法，如果需要保留父类的对象属性，需要使用
super()去调用父类的init方法

多态：同一个事物有多种形态，子类继承父类的方法，可以对方法进行重写，
一个方法就有多种形态（多态的表现）
类的多态：继承产生多态
"""

class Person:
    def __init__(self, name='', age=2):
        self.name = name
        self.age = age

class Staff(Person):
    # init方法的参数：保证在创建对象的时候就可以给某些属性赋值
    def __init__(self, name):
        super().__init__(name)
        self.salary = 0

if __name__ == '__main__':
    s1 = Person()
    s1.__init__('wd', 12)
    print(s1.name, s1.age)

# 练习
"""
声明人类，有属性，名字、年龄、性别。身高
要求创建人的对象的时候可以给名字、性别、年龄赋初值

再创建学生类继承自人类，拥有人类的所有的属性，再添加学号、
成绩、电话属性
要求创建学生对象的时候可以给名字、年龄和电话赋初值
"""

class Human:
    def __init__(self,   name, age=0, sex='男'):
        self.name = name
        self.height = 0
        self.age = age
        self.sex = sex

class Student(Human):
    def __init__(self, name, age, tel):
        super().__init__(self, name, age)
        self.score = 0
        self.id_num = 0
        self.tel = 13

02-添加子类属性.py


import numpy as np
import pandas as pd
from scipy import ndimage
from scipy.interpolate import interp1d

import astropy.units as u
import astropy.coordinates as coord
from astropy.cosmology import FlatLambdaCDM
from astropy.constants import M_sun

import tensorflow as tf
from flowpm import utils as ut

import copy
import time
from sys import argv,exit,byteorder

from field_util import Field

class FGPA(object):
    def __init__(self, fn, box_size = 512*u.Mpc, box_res = 256, origin = [3550*u.Mpc, -256*u.Mpc, -256*u.Mpc],
                 tau_0 = 1, T_0 = 1, beta = 1.6, gamma = 1.6, from_npy = True):
        if from_npy:
            self.dark = self.read_from_npy(fn)
        else:
            self.header, self.gas, self.dark, self.star = self.tipsy_read(fn)
            self.auxilinary(box_size, box_res)
        self.set_origin(origin)
        self.set_FGPA_param(tau_0, T_0, beta, gamma)

    def set_FGPA_param(self, tau_0 = None, T_0 = None, beta = None, gamma = None):
        if tau_0 is not None:
            self.tau_0 = tau_0 # TBD
        if T_0 is not None:
            self.T_0   = T_0 # TBD
        if beta is not None:
            self.beta = beta
        if gamma is not None:
            self.gamma = gamma
        return

    def set_origin(self, orig_pos):
        '''
        Set a offset value (move the origin point to the given [x0, y0, z0])
        add units!
        '''
        self.x0, self.y0, self.z0 =orig_pos
        return

    def auxilinary(self, box_size, box_res, N_particles = None):
        # settings of the simulation
        self.box_size = box_size # unit: Mpc
        self.box_res = box_res # unit: none
        self.res = box_size/box_res # unit: Mpc
        if N_particles is None:
            self.n_den = self.header['N'] / self.box_size**3
        else:
            self.n_den = N_particles / self.box_size**3
        #Do general cosmo things
        self.cosmo = FlatLambdaCDM(H0=100, Om0=0.315)
        self.mass_res = self.cosmo.critical_density0.to(u.M_sun/u.Mpc**3)*(self.box_size)**3/self.box_res**3*self.cosmo.Om(0.)

        #get speed of light in km/s
        self.ckms = 299792
        self.velkms = (self.box_size/8677.2079486362706)*self.ckms

    def read_from_npy(self, fn, costco_style = True):
        '''
        use this function to read reduced data, and recover the data to tipsy style.
        '''
        dark = np.load(fn)
        self.auxilinary(box_size = 512*u.Mpc, box_res = 256, N_particles = len(dark))

        dark = pd.DataFrame(dark,columns=dark.dtype.names)

        # basically what we do in the rev function
        dark['x'] = dark['x'] / self.box_size - 0.5
        dark['y'] = dark['y'] / self.box_size - 0.5
        dark['z'] = dark['z'] / self.box_size - 0.5
        dark['x'].units = None
        dark['y'].units = None
        dark['z'].units = None

        dark['vx'] = dark['vx'] / self.velkms
        dark['vy'] = dark['vy'] / self.velkms
        dark['vz'] = dark['vz'] / self.velkms
        dark['vx'].units = None
        dark['vy'].units = None
        dark['vz'].units = None

        if costco_style:
            dark['x'], dark['y'], dark['z'] = dark['y'], dark['x'], dark['z'] # ?
            dark['vx'], dark['vy'], dark['vz'] = dark['vy'], dark['vx'], dark['vz'] # dont forget the vel data!

        return dark

    def tipsy_read(self, fn, costco_style = True):
        tipsy = open(fn, 'rb')
        header_type = np.dtype([('time', '>f8'),('N', '>i4'), ('Dims', '>i4'), ('Ngas', '>i4'), ('Ndark', '>i4'), ('Nstar', '>i4'), ('pad', '>i4')])
        gas_type  = np.dtype([('mass','>f4'), ('x', '>f4'),('y', '>f4'),('z', '>f4'), ('vx', '>f4'),('vy', '>f4'),('vz', '>f4'),
                            ('rho','>f4'), ('temp','>f4'), ('hsmooth','>f4'), ('metals','>f4'), ('phi','>f4')])
        dark_type = np.dtype([('mass','>f4'), ('x', '>f4'),('y', '>f4'),('z', '>f4'), ('vx', '>f4'),('vy', '>f4'),('vz', '>f4'),
                            ('eps','>f4'), ('phi','>f4')])
        star_type  = np.dtype([('mass','>f4'), ('x', '>f4'),('y', '>f4'),('z', '>f4'), ('vx', '>f4'),('vy', '>f4'),('vz', '>f4'),
                            ('metals','>f4'), ('tform','>f4'), ('eps','>f4'), ('phi','>f4')])

        header = np.fromfile(tipsy,dtype=header_type,count=1)
        header = dict(zip(header_type.names,header[0]))

        gas  = np.fromfile(tipsy,dtype=gas_type,count=header['Ngas'])
        dark = np.fromfile(tipsy,dtype=dark_type,count=header['Ndark'])
        star = np.fromfile(tipsy,dtype=star_type,count=header['Nstar'])

        if byteorder == 'little':
            gas  =   gas.byteswap().newbyteorder('=')
            dark =   dark.byteswap().newbyteorder('=')
            star =   star.byteswap().newbyteorder('=')

        gas  = pd.DataFrame(gas,columns=gas.dtype.names)
        dark = pd.DataFrame(dark,columns=dark.dtype.names) # here is the raw data
        # in raw_data:
        # x - RA
        # y - DEC
        # z - red

        # what we want:
        # x - red
        # y - RA
        # z - DEC
        if costco_style:
            dark['x'], dark['y'], dark['z'] = dark['y'], dark['x'], dark['z'] # ?
            dark['vx'], dark['vy'], dark['vz'] = dark['vy'], dark['vx'], dark['vz'] # dont forget the vel data!
        star = pd.DataFrame(star,columns=star.dtype.names)
        tipsy.close()
        return header, gas, dark, star

    def process_dark(self, dark = None):
        # for painting, keep the particles in [0, 512]^3 box
        # this function write in-situ results, so be careful
        # only use if you want to ensure the particles are in reasonable positions
        if dark is None:
            dark = copy.deepcopy(self.dark)

        dark['x'] = (dark['x']+0.5) * self.box_size + self.x0
        dark['y'] = (dark['y']+0.5) * self.box_size + self.y0
        dark['z'] = (dark['z']+0.5) * self.box_size + self.z0

        dark['x'].units = u.Mpc
        dark['y'].units = u.Mpc
        dark['z'].units = u.Mpc

        dark['vx'] = dark['vx'] * self.velkms
        dark['vy'] = dark['vy'] * self.velkms
        dark['vz'] = dark['vz'] * self.velkms

        dark['vx'].units = u.km * u.s**-1
        dark['vy'].units = u.km * u.s**-1
        dark['vz'].units = u.km * u.s**-1

        dark['mass'] = self.mass_res.value
        dark['mass'].units= M_sun

        return dark

    def process_dark_rev(self, dark_processed):
        '''
        recover the input field (to raw format)
        '''

        dark_processed['x'] = (dark_processed['x']-self.x0) / self.box_size - 0.5
        dark_processed['y'] = (dark_processed['y']-self.y0) / self.box_size - 0.5
        dark_processed['z'] = (dark_processed['z']-self.z0) / self.box_size - 0.5
        dark_processed['x'].units = None
        dark_processed['y'].units = None
        dark_processed['z'].units = None

        dark_processed['vx'] = dark_processed['vx'] / self.velkms
        dark_processed['vy'] = dark_processed['vy'] / self.velkms
        dark_processed['vz'] = dark_processed['vz'] / self.velkms
        dark_processed['vx'].units = None
        dark_processed['vy'].units = None
        dark_processed['vz'].units = None
        return dark_processed

    def particle_paint(self, nc, weight_col = None):
        '''
        nc: # of cells along any direction
        raw_part_data: *raw* particle data from the simuation (x, y, z, \\in [-0.5, 0.5])
        weight_col: pick one col in raw_data as weight; default value is 1 for all the particles
        '''

        mesh = tf.zeros([1, nc, nc, nc], dtype = float)
        dark_raw = self.dark

        dark_pos = tf.convert_to_tensor([dark_raw['x'], dark_raw['y'], dark_raw['z']], dtype = float)
        dark_pos = tf.transpose((dark_pos + 0.5) * nc)
        dark_pos = tf.expand_dims(dark_pos, axis = 0) # [1, partN, 3]

        partN = dark_pos.shape[1]
        n_den = partN / nc**3

        if weight_col is None:
            weight = tf.ones([1, partN])
        else:
            weight = tf.convert_to_tensor(dark_raw[weight_col])
            weight = tf.expand_dims(weight, axis = 0)

        return ut.cic_paint(mesh, dark_pos, weight = weight) / n_den

    def particle_paint_clip_with_real_coord(self, real_coord_start, real_coord_end, dl, dark_raw = None, weight_col = None, smooth  = False):
        '''
        translate real space box to box in [-0.5, 0.5]^3 then run particle_paint_clip
        plz add units to all the parameters

        Issue: get things wrong here
        '''
        if dark_raw is None:
            dark_raw = self.dark

        rcs_x, rcs_y, rcs_z = real_coord_start
        rce_x, rce_y, rce_z = real_coord_end

        box_scale = round((self.box_size/dl).value)

        nc = np.round([((rce_x-rcs_x)/dl).value,
                       ((rce_y-rcs_y)/dl).value,
                       ((rce_z-rcs_z)/dl).value]).astype(int)
        offset = np.round([((rcs_x-self.x0)/dl).value,
                           ((rcs_y-self.y0)/dl).value,
                           ((rcs_z-self.z0)/dl).value]).astype(int)
        n_den = self.n_den * dl**3 #  global density per grid
        field_data = self.particle_paint_clip(nc, offset, box_scale, n_den, dark_raw = dark_raw, weight_col = weight_col)[0] # [nx, ny, nz] tensor
        field = Field(rcs_x, rcs_y, rcs_z, dl, field_data)
        if smooth:
            field.smooth(dl)
        return field

    def particle_paint_clip(self, nc, offset, box_scale, n_den, dark_raw = None, weight_col = None):
        '''
        nc: [nx, ny, nz]
            the shape/physical-scale of mesh.
        offset: [ox, oy, oz]
            [0,0,0] position of the mesh; default value  ox=0, oy=0, oz=0
        box_scale: the full scale of the simulation - box coord: [0, box_scale]^3
        # raw_part_data: *raw* particle data from the simuation (x, y, z, \\in [-0.5, 0.5])
        weight_col: pick one col in raw_data as weight; default value is 1 for all the particles

        this function cutouts a box [ox, ox+nx] * [oy, oy+ny] * [oz, oz+nz] with field values.
        auto periodical condition(?)
        '''
        if dark_raw is None:
            dark_raw = self.dark

        nx, ny, nz = nc
        ox, oy, oz = offset

        mesh = tf.zeros([1, nx, ny, nz], dtype = float)

        # remove particles out of the boundary
        dark_clip = dark_raw[(dark_raw['x']<=(ox+nx)/box_scale-0.5) & (dark_raw['x']>= ox/box_scale-0.5) &
                             (dark_raw['y']<=(oy+ny)/box_scale-0.5) & (dark_raw['y']>= oy/box_scale-0.5) &
                             (dark_raw['z']<=(oz+nz)/box_scale-0.5) & (dark_raw['z']>= oz/box_scale-0.5)]

        dark_pos = tf.convert_to_tensor([(dark_clip['x']+ 0.5)*box_scale - ox,
                                         (dark_clip['y']+ 0.5)*box_scale - oy,
                                         (dark_clip['z']+ 0.5)*box_scale - oz], dtype = float)

        assert (np.max(dark_pos[0]) <= nx) & (np.max(dark_pos[1]) <= ny) & (np.max(dark_pos[2]) <= nz), print(np.max(dark_pos[0]), np.max(dark_pos[1]), np.max(dark_pos[2]))
        assert (np.min(dark_pos[0]) >= 0 ) & (np.min(dark_pos[1]) >= 0 ) & (np.min(dark_pos[2]) >= 0 )
        dark_pos = tf.transpose(dark_pos)
        dark_pos = tf.expand_dims(dark_pos, axis = 0) # [1, partN, 3]

        partN = dark_pos.shape[1]

        if weight_col is None:
            weight = tf.ones([1, partN])
        else:
            weight = tf.convert_to_tensor(dark_clip[weight_col])
            weight = tf.expand_dims(weight, axis = 0)

        paint = ut.cic_paint(mesh, dark_pos, weight = weight) / n_den

        return paint

    def RSD_catalog(self, real_coord_start, real_coord_end, dl):
        '''
        return a particle catalog with RSDed pos
        '''
        opd_clip = self.particle_paint_clip_with_real_coord(real_coord_start, real_coord_end, dl)
        fvx_clip = self.particle_paint_clip_with_real_coord(real_coord_start, real_coord_end, dl, weight_col = 'vx')
        fvy_clip = self.particle_paint_clip_with_real_coord(real_coord_start, real_coord_end, dl, weight_col = 'vy')
        fvz_clip = self.particle_paint_clip_with_real_coord(real_coord_start, real_coord_end, dl, weight_col = 'vz')

        part_new_pos  = self.field_to_part_pos(opd_clip)

        # generate a new particle catalog
        part_new = pd.DataFrame(part_new_pos[0], columns = ['x', 'y', 'z'])

        opd_tensor = tf.expand_dims(opd_clip.field_data, axis = 0)
        fvx_tensor = tf.expand_dims(fvx_clip.field_data, axis = 0)
        fvy_tensor = tf.expand_dims(fvy_clip.field_data, axis = 0)
        fvz_tensor = tf.expand_dims(fvz_clip.field_data, axis = 0)

        # flowpm.cic_readout requires a compatible mesh and coord ([nx, ny, nz] grid - [0, n*]^3 coord)
        part_pos_grid = self.mesh_to_part_pos(tf.expand_dims(opd_clip.field_data, axis = 0))
        part_new['opd'] = ut.cic_readout(opd_tensor, part_pos_grid)[0]
        part_new['vx']  = ut.cic_readout(fvx_tensor, part_pos_grid)[0]
        part_new['vy']  = ut.cic_readout(fvy_tensor, part_pos_grid)[0]
        part_new['vz']  = ut.cic_readout(fvz_tensor, part_pos_grid)[0]

        # convert to real space
        part_new = self.process_dark(part_new)

        # RSD
        # TODO: consider the effect of yz distance
        part_new['red_real'] = self.z_from_dist(part_new['x'] * u.Mpc)
        part_new['red_rs'] = part_new['red_real'] + part_new['vx'] / self.ckms
        part_new['x_red'] = self.z_to_dist(part_new['red_rs'])
        return part_new

    def FGPA_eval(self, mesh_catalog):
        # calculate tau and T for each particle
        # TODO: find out characterized tau_0 & T_0
        mesh_catalog['tau'] = self.tau_0 * mesh_catalog['opd']**self.beta

        mesh_catalog['T']   = self.T_0 * mesh_catalog['opd']**self.gamma
        return mesh_catalog

    def raw_tau_map(self, real_coord_start, real_coord_end, dl):

        # generate the particle catalog
        part_new = self.RSD_catalog(real_coord_start, real_coord_end, dl)
        # add tau / T to the catalog
        part_new = self.FGPA_eval(part_new)
        # this one in the RS space
        part_new_new = pd.DataFrame(part_new[['y', 'z', 'vx', 'vy', 'vz', 'tau', 'T']], columns = ['y', 'z',  'vx', 'vy', 'vz', 'tau', 'T'])
        part_new_new['x'] = part_new['x_red'] # not sure why this doesn't work
        # recover the raw_field
        part_new_new = self.process_dark_rev(part_new_new)
        # paint the final result
        tau_field = self.particle_paint_clip_with_real_coord(real_coord_start, real_coord_end, dl,
                                                        dark_raw = part_new_new, weight_col = 'tau', smooth = False)
        return tau_field

    def tau_map(self, real_coord_start, real_coord_end, dl, z_comp = 2.30, F_obs = 0.8447):
        # derive the A_norm by comparing the desired value in obs with calculation
        self.set_FGPA_param(tau_0=1)
        raw_tau_field = self.raw_tau_map(real_coord_start, real_coord_end, dl)
        # construct the clip coord
        # hardcode bad, but works here
        clip_start = copy.deepcopy(real_coord_start)
        clip_start[0] = self.cosmo.comoving_distance(z_comp - 0.05)
        clip_end = copy.deepcopy(real_coord_end)
        clip_end[0] = self.cosmo.comoving_distance(z_comp + 0.05)

        test_tau_field = raw_tau_field.clip_with_coord(clip_start, clip_end)

        # no newton, just interp
        tau_list = test_tau_field.field_data
        tau_list = tau_list[~np.isnan(tau_list)]
        l = []
        for A in np.arange(0, 0.5, 0.001):
            l.append(np.mean(np.exp(-tau_list * A)))
        A_func = interp1d(l, np.arange(0, 0.5, 0.001))
        A_norm = A_func(F_obs)

        tau_field = copy.deepcopy(raw_tau_field)
        tau_field.field_data = tau_field.field_data * A_norm
        return tau_field

    def trans_map(self, real_coord_start, real_coord_end, dl):
        tau_field = self.tau_map(real_coord_start, real_coord_end, dl)
        trans_field = copy.deepcopy(tau_field)
        trans_field.field_data = np.exp(-trans_field.field_data)
        trans_field.field_data = trans_field.field_data / np.mean(trans_field.field_data)
        return trans_field

    def field_to_part_pos(self, field, tensor = True):
        '''

        '''
        nx, ny, nz = field.field_data.shape
        part_mesh = np.meshgrid(np.arange(nx), np.arange(ny), np.arange(nz))
        part_mesh = np.reshape(part_mesh, [3, nx*ny*nz]).T.astype(float)
        part_mesh[:, 0] = (part_mesh[:, 0]*field.dl + field.x0 - self.x0) / self.box_size - 0.5
        part_mesh[:, 1] = (part_mesh[:, 1]*field.dl + field.y0 - self.y0) / self.box_size - 0.5
        part_mesh[:, 2] = (part_mesh[:, 2]*field.dl + field.z0 - self.z0) / self.box_size - 0.5

        if tensor:
            part_mesh = tf.convert_to_tensor(part_mesh, dtype = float)
            part_mesh = tf.expand_dims(part_mesh, 0)
        return part_mesh

    def mesh_to_part_pos(self, mesh):
        '''
        Note this function is not complete: it converts the mesh into position [0, 0, 0] ... [nx, ny, nz] regardless the position
        Obselated
        '''
        _, nx, ny, nz = mesh.shape
        part_mesh = np.meshgrid(np.arange(nx), np.arange(ny), np.arange(nz))
        part_mesh = np.reshape(part_mesh, [3, nx*ny*nz]).T.astype(float)

        part_mesh = tf.convert_to_tensor(part_mesh, dtype = float)
        part_mesh = tf.expand_dims(part_mesh, 0)
        return part_mesh

    def z_from_dist(self, distance):
        dummyred = np.linspace(0.,10.,10000)
        dummydist = self.cosmo.comoving_distance(dummyred)
        res = np.interp(distance,dummydist,dummyred)
        return (res)

    def z_to_dist(self, red):
        return self.cosmo.comoving_distance(red).value


n = int(input())
L = [list(map(int,input().split())) for _ in range(n)]

papers = [0,0,0] #-1,0,1

def same(A):
    ref = A[0][0]
    for row in A:
        for i in row:
            if i != ref:
                return 9
    return ref

def cut(y,x,n):
    global papers

    num = same([L[i][x:x+n] for i in range(y,y+n)])
    if num != 9:
        papers[num+1] += 1
        return

    for i in range(3):
        for j in range(3):
            cut(y+i*(n//3), x+j*(n//3), n//3)

cut(0,0,n)
for i in papers:
    print(i)


from collections import defaultdict
def func(nums1, nums2):
    hash = defaultdict(int)

    while nums1:
        np1 = nums1.pop()
        hash[np1[0]] += np1[1]

    while nums2:
        np2 = nums2.pop()
        hash[np2[0]] += np2[1]

    return sorted([[key, value] for key, value in hash.items()])

nums1 = [[2,4],[3,6],[5,5]]
nums2 = [[1,3],[4,3]]

print(func(nums1, nums2))

주리머/2-2w/wc/(성공) 6362. Merge Two 2D Arrays by Summing Values.py


#! python3
import sys
import win32api
from PyQt5.QtWidgets import QApplication, QWidget, \
    QToolTip, QPushButton, QMessageBox, QDesktopWidget, \
    QMainWindow, QAction, QMenu, QStatusBar
from PyQt5.QtGui import QIcon, QFont
from PyQt5.QtCore import QCoreApplication

'''
#面向过程
app = QApplication(sys.argv)
w = QWidget()
w.resize(300, 150)
w.setFixedSize(700, 400)
x, y = win32api.GetSystemMetrics(0), win32api.GetSystemMetrics(1)
w.move((x - 250) / 2, (y - 150) / 2)
w.setWindowTitle('将图片转换为jpg 1920*1080')
w.show()
sys.exit(app.exec_())
'''
x , y= 0,0
class Example(QMainWindow):
    def __init__(self):
        super().__init__()#调用父类构造函数
        self.initUI()

    def initUI(self):

        global x,y

        QToolTip.setFont(QFont('SansSerif', 10))
        self.setToolTip('This is a QWidget widget')

        btn = QPushButton('Quit', self)
        btn.setToolTip('This is a QPushButton widget')
        # btn.clicked.connect(QCoreApplication.instance().quit) #clicked btn and exit app
        btn.clicked.connect(QApplication.instance().exit) #clicked btn and exit app
        btn.resize(btn.sizeHint())
        btn.move(50, 50)

        exitAct:QAction = QAction(QIcon('46.jpg'), 'Exit', self)
        exitAct.setShortcut('Ctrl+Q')
        exitAct.setStatusTip('Exit application')
        exitAct.triggered.connect(QApplication.instance().quit)

        menuBar = self.menuBar()
        fileMenu = menuBar.addMenu('File')
        fileMenu.addAction(exitAct)

        self.toolbar = self.addToolBar('Exit')
        self.toolbar.addAction(exitAct)

        # subMenu add to FileMenu
        subMenu = QMenu('Import', self)
        subAct = QAction('Import file', self)
        subMenu.addAction(subAct)
        fileMenu.addMenu(subMenu)

        #checkMenu
        viewSBar:QAction = QAction('View statusbar', self, checkable=True)
        viewSBar.setStatusTip('View statusbar')
        viewSBar.setChecked(True)
        viewSBar.triggered.connect(self.toggleMenu)
        fileMenu.addAction(viewSBar)

        # x, y = win32api.GetSystemMetrics(0), win32api.GetSystemMetrics(1)
        # self.setGeometry((x-700)/2, (y-400)/2, 700, 400)
        self.center()
        self.setFixedSize(700, 400)
        self.setWindowTitle('将图片转换成jpg 1080')
        self.statusbar = self.statusBar()
        self.statusbar.showMessage('Ready')
        self.setWindowIcon(QIcon('46.jpg'))
        self.show()

    def center(self):
        qr = self.frameGeometry()#get self RECT
        cp = QDesktopWidget().availableGeometry().center()#
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    #When Widgets is closing, call this function by automaticlly
    #virtualFunction
    def closeEvent(self, event):
        reply = QMessageBox.question(self, 'Message', 'Are you sure to quit',
                                     QMessageBox.Yes|QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

    #virtual Function
    def contextMenuEvent(self, event):
        cmenu = QMenu(self)

        newAct = cmenu.addAction('New')
        opnAct = cmenu.addAction('Open')
        quitAct = cmenu.addAction('Quit')

        #which Action
        print(type(event), event.pos())
        action = cmenu.exec_(self.mapToGlobal(event.pos()))

        if action == quitAct:
            QApplication.instance().quit()

    def toggleMenu(self, state):
        print(state)
        if state:
            self.statusbar.show()
        else:
            self.statusbar.hide()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


from functools import partial
from pathlib import Path
from typing import Dict, Any, Callable, Tuple, Optional, Sequence

import PIL
import imageio
import numpy as np
import torch
from PIL import Image
from torch import Tensor
from torch.nn import Module, Tanh, Parameter
from torch.nn.functional import grid_sample, l1_loss, mse_loss
from torch.utils.tensorboard import SummaryWriter

from thre3d_atom.networks.dense_nets import SkipMLP, SkipMLPConfig
from thre3d_atom.networks.network_interface import Network
from thre3d_atom.networks.shared.layers import (
    PositionalEncodingsEmbedder,
    PixelwiseNorm,
)
from thre3d_atom.utils.constants import NUM_COLOUR_CHANNELS
from thre3d_atom.utils.imaging_utils import (
    adjust_dynamic_range,
    to8b,
    mse2psnr,
    get_2d_coordinates,
)
from thre3d_atom.utils.logging import log

class FeatureGrid2D(Module):
    def __init__(
        self,
        height: int,
        width: int,
        feature_dims: int,
        tunable: bool = True,
        device: torch.device = torch.device(
            "cuda" if torch.cuda.is_available() else "cpu"
        ),
    ) -> None:
        super().__init__()

        # state of the object:
        self._height = height
        self._width = width
        self._feature_dims = feature_dims
        self._tunable = tunable

        self.features = torch.empty(
            (1, feature_dims, height, width), device=device, requires_grad=True
        )
        torch.nn.init.xavier_uniform_(self.features)

        if self._tunable:
            self.features = Parameter(self.features)

    @classmethod
    def from_feature_tensor(cls, feature_tensor: Tensor) -> Any:
        _, feature_dims, height, width = feature_tensor.shape
        # initialize a random feature_grid
        feature_grid = cls(
            height=height,
            width=width,
            feature_dims=feature_dims,
            tunable=False,
            device=feature_tensor.device,
        )

        # use the given feature_tensor as it's features:
        feature_grid.features = feature_tensor

        return feature_grid

    def extra_repr(self) -> str:
        return (
            f"grid_dims: {self.features.shape[2:]}, "
            f"feature_dims: {self.features.shape[1]}, "
            f"tunable: {self._tunable}"
        )

    def get_save_info(self) -> Dict[str, Any]:
        return {
            "conf": {
                "height": self._height,
                "width": self._width,
                "feature_dims": self._feature_dims,
                "tunable": self._tunable,
            },
            "state_dict": self.state_dict(),
        }

    def forward(self, coords: Tensor) -> Tensor:
        """coords should be of shape => [N x 2], and be in the range [-1, 1]"""
        sam_vals = grid_sample(
            # note the convention difference between the image and sample coordinates
            self.features.permute(0, 1, 3, 2),
            coords[None, None, ...],
            mode="bilinear",
            align_corners=False,
        )
        return sam_vals.permute(0, 2, 3, 1)[0, 0, ...]

class ImageDecoderMLP(Network):
    # noinspection PyUnresolvedReferences
    def __init__(
        self,
        mlp: SkipMLP,
        feature_dims: int = 32,
        feature_embedding_dims: int = 0,
        use_local_coords: bool = False,
        local_coords_embedding_dims: int = 0,
        normalize_features: bool = False,
    ) -> None:
        super().__init__()
        self._mlp = mlp
        self._feature_dims = feature_dims
        self._feature_embedding_dims = feature_embedding_dims
        self._use_local_coords = use_local_coords
        self._local_coords_embedding_dims = local_coords_embedding_dims
        self._normalize_features = normalize_features

        # objects of modification:
        self._normalizer = PixelwiseNorm()
        self._feature_embedder = PositionalEncodingsEmbedder(
            input_dims=self._feature_dims, emb_dims=self._feature_embedding_dims
        )
        self._local_coords_embedder = PositionalEncodingsEmbedder(
            input_dims=2, emb_dims=self._local_coords_embedding_dims
        )

    @property
    def input_shape(self) -> Sequence[Tuple[int, ...]]:
        return self._mlp.input_shape

    @property
    def output_shape(self) -> Sequence[Tuple[int, ...]]:
        return self._mlp.output_shape

    @property
    def feature_dims(self) -> int:
        return self._feature_dims

    @property
    def use_local_coords(self) -> bool:
        return self._use_local_coords

    def get_save_info(self) -> Dict[str, Any]:
        return {
            "conf": {
                "feature_dims": self._feature_dims,
                "feature_embedding_dims": self._feature_embedding_dims,
                "use_local_coords": self._use_local_coords,
                "local_coords_embedding_dims": self._local_coords_embedding_dims,
                "normalize_features": self._normalize_features,
            },
            "mlp": self._mlp.get_save_info(),
            "state_dict": self.state_dict(),
        }

    def load_weights(self, weights: Dict[str, Any]) -> None:
        self._mlp.load_state_dict(weights["mlp"]["state_dict"])

    def forward(self, x: Tensor) -> Tensor:
        if self._use_local_coords:
            features, local_coords = (
                x[..., : self._feature_dims],
                x[..., self._feature_dims :],
            )
        else:
            features, local_coords = x, torch.zeros(size=(x.shape[0], 0))

        embedded_features = self._feature_embedder(features)
        embedded_local_coords = self._local_coords_embedder(local_coords)
        normalized_features = self._normalizer(features)

        if self._use_local_coords:
            feats = (
                normalized_features if self._normalize_features else embedded_features
            )
            mlp_input = torch.cat([feats, embedded_local_coords], dim=-1)
        else:
            mlp_input = (
                normalized_features if self._normalize_features else embedded_features
            )
        return self._mlp(mlp_input)

def get_default_image_decoder_mlp(
    feature_dims: int = 32,
    feature_embedding_dims: int = 0,
    use_local_coords: bool = False,
    local_coords_embedding_dims: int = 0,
    normalize_features: bool = False,
) -> ImageDecoderMLP:
    feat_inp_dims = feature_dims + (2 * feature_dims * feature_embedding_dims)
    lc_inp_dims = 2 + (2 * 2 * local_coords_embedding_dims)
    if use_local_coords:
        mlp_input_dims = feat_inp_dims + lc_inp_dims
    elif normalize_features:
        mlp_input_dims = feature_dims
    else:
        mlp_input_dims = feat_inp_dims

    mlp_config = SkipMLPConfig(
        input_dims=mlp_input_dims,
        layer_depths=[256],
        output_dims=NUM_COLOUR_CHANNELS,
        skips=[False],
        use_equalized_learning_rate=True,
        out_activation_fn=Tanh(),
    )
    return ImageDecoderMLP(
        SkipMLP(mlp_config),
        feature_dims=feature_dims,
        feature_embedding_dims=feature_embedding_dims,
        use_local_coords=use_local_coords,
        local_coords_embedding_dims=local_coords_embedding_dims,
        normalize_features=normalize_features,
    )

def decode_coords_with_fg_and_mlp(
    coords: Tensor,
    feature_grid: FeatureGrid2D,
    decoder_mlp: ImageDecoderMLP,
    image_resolution: Tuple[int, int],
) -> Tensor:
    """decodes the coords tensor into RGB pixel values"""
    orig_shape = coords.shape
    coords = coords.reshape(-1, orig_shape[-1])
    image_height, image_width = image_resolution

    local_coords = adjust_dynamic_range(coords, drange_in=(-1, 1), drange_out=(0, 1))
    local_coords[..., 0] *= image_height
    local_coords[..., 1] *= image_width
    local_coords = local_coords - torch.floor(local_coords)

    decoded_features = feature_grid(coords)
    decoder_input = (
        torch.cat([decoded_features, local_coords], dim=-1)
        if decoder_mlp.use_local_coords
        else decoded_features
    )
    return decoder_mlp(decoder_input).reshape(*orig_shape[:-1], -1)

class ImageModel:
    def __init__(
        self,
        image_height: int,
        image_width: int,
        feature_dims: int = 32,
        decoder_mlp_maker: Callable[[], Network] = get_default_image_decoder_mlp,
        device: torch.device = torch.device(
            "cuda" if torch.cuda.is_available() else "cpu"
        ),
        verbose_creation: bool = True,
    ) -> None:
        self._image_height = image_height
        self._image_width = image_width
        self._feature_dims = feature_dims
        self._device = device

        # compute the height and width of the feature-grid so as to keep the number of
        # parameters in the image and the parametric-model same:
        self._setup_feature_dims()

        # create a feature grid object (note that these are kept public):
        self.feature_grid = FeatureGrid2D(
            self._feature_height, self._feature_width, feature_dims, device=device
        )
        self.decoder_mlp = decoder_mlp_maker().to(self._device)

        # print info related to the Feature Grid and the Decoder MLP:
        if verbose_creation:
            log.info(f"Created Feature grid: {self.feature_grid}")
            log.info(f"Created Decoder MLP: {self.decoder_mlp}")

    @property
    def image_resolution(self) -> Tuple[int, int]:
        return self._image_height, self._image_width

    @staticmethod
    def compute_feature_grid_dims(
        image_resolution: Tuple[int, int], feature_dims: int
    ) -> Tuple[int, int]:
        image_height, image_width = image_resolution
        aspect_ratio = image_width / image_height
        total_image_params = image_width * image_height * NUM_COLOUR_CHANNELS
        needed_params = total_image_params / feature_dims
        feature_grid_height = int(np.ceil(np.sqrt(needed_params / aspect_ratio)))
        feature_grid_width = int(aspect_ratio * feature_grid_height)
        return feature_grid_height, feature_grid_width

    def _setup_feature_dims(self) -> None:
        self._feature_height, self._feature_width = self.compute_feature_grid_dims(
            image_resolution=(self._image_height, self._image_width),
            feature_dims=self._feature_dims,
        )

    @staticmethod
    def _shuffle_tensor_2d(tensor_2d: Tensor) -> Tensor:
        """ shuffles a 2D Tensor of shape [N x C]"""
        return tensor_2d[torch.randperm(len(tensor_2d))]

    def _infinite_data_loader(self, data: Tensor, batch_size: int) -> Tensor:
        while True:
            data = self._shuffle_tensor_2d(data)
            for batch_index in range(0, len(data), batch_size):
                data_batch = data[batch_index : batch_index + batch_size]
                if data_batch.shape[0] == batch_size:
                    yield data_batch
                else:
                    break

    @staticmethod
    def _check_log_condition(
        current_step: int, frequency_step: int, start_step: int, end_step: int
    ) -> bool:
        return (
            current_step % frequency_step == 0
            or current_step == start_step
            or current_step == end_step
        )

    def get_save_info(self) -> Dict[str, Any]:
        return {
            "conf": {
                "image_height": self._image_height,
                "image_width": self._image_width,
                "feature_dims": self._feature_dims,
            },
            "feature_grid": self.feature_grid.get_save_info(),
            "decoder_mlp": self.decoder_mlp.get_save_info(),
        }

    def render(
        self,
        render_resolution: Optional[Tuple[int, int]] = None,
        chunk_size: int = 64 * 1024,
    ) -> Tensor:
        height, width = (
            (self._image_height, self._image_width)
            if render_resolution is None
            else render_resolution
        )

        # create a coordinates mesh-grid:
        coords = get_2d_coordinates(height, width)

        # flatten the coordinates and bring them on the GPU:
        flat_coords = coords.reshape(-1, coords.shape[-1]).to(self._device)

        # decode all the coordinates into pixel values chunk by chunk:
        decoded_image = []
        with torch.no_grad():
            for chunk_index in range(0, len(flat_coords), chunk_size):
                coord_chunk = flat_coords[chunk_index : chunk_index + chunk_size]
                decoded_image.append(
                    decode_coords_with_fg_and_mlp(
                        coord_chunk,
                        self.feature_grid,
                        self.decoder_mlp,
                        self.image_resolution,
                    )
                )
        decoded_image = torch.cat(decoded_image, dim=0)
        decoded_image = decoded_image.reshape(height, width, -1)
        decoded_image = adjust_dynamic_range(
            decoded_image.cpu(),
            drange_in=(-1, 1),
            drange_out=(0, 1),
            slack=True,
        )
        return decoded_image

    def train(
        self,
        training_image: PIL.Image.Image,
        num_iterations: int = 10000,
        batch_size: int = 8192,
        learning_rate: float = 0.003,
        lr_decay_steps: int = 5000,
        feedback_frequency: int = 1000,
        loss_feedback_frequency: int = 10,
        testing_frequency: int = 1000,
        save_frequency: int = 2000,
        output_dir: Path = Path(__file__).parent.absolute() / "logs",
    ) -> None:
        # load the training image and create a dataset of pixel_coordinates -> pixel RGB values:
        image_np = np.array(training_image).astype(np.float32) / 255
        if len(image_np.shape) < 3:
            image_np = np.tile(image_np[..., None], (1, 1, 3))
        image_np = image_np[..., :3]  # in case of > 3 channel images
        real_feedback_image = image_np
        # bring the pixel range to (-1, 1) for training
        image_np = adjust_dynamic_range(image_np, drange_in=(0, 1), drange_out=(-1, 1))

        # make sure the training image is compatible with the ImageModel
        assert (
            self._image_height == image_np.shape[0]
            and self._image_width == image_np.shape[1]
        ), (
            f"The provided training image with size ({image_np.shape[:-1]}) is incompatible with the Image-Model's"
            f"image size ({self._image_height, self._image_width})"
        )

        image_coords = get_2d_coordinates(self._image_height, self._image_width)
        coord_rgb_image = torch.cat(
            [
                image_coords.to(self._device),
                torch.from_numpy(image_np).to(self._device),
            ],
            dim=-1,
        )
        training_data = coord_rgb_image.reshape(-1, coord_rgb_image.shape[-1])
        training_data_loader = iter(
            self._infinite_data_loader(training_data, batch_size=batch_size)
        )

        # setup optimizer:
        optimizer = torch.optim.Adam(
            params=[
                {"params": self.feature_grid.parameters(), "lr": learning_rate},
                {"params": self.decoder_mlp.parameters(), "lr": learning_rate},
            ],
            betas=(0, 0.99),
        )
        lr_scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.1)

        # setup output directories
        # fmt: off
        model_dir = output_dir / "saved_models"
        logs_dir = output_dir / "training_logs"
        tensorboard_dir = logs_dir / "tensorboard"
        render_dir = logs_dir / "rendered_output"
        for directory in (model_dir, logs_dir, tensorboard_dir,
                          render_dir):
            directory.mkdir(exist_ok=True, parents=True)
        # fmt: on

        # create the tensorboard directory:
        tensorboard_writer = SummaryWriter(tensorboard_dir)

        # log the real image for feedback:
        log.info(f"Logging real feedback image")
        imageio.imwrite(
            render_dir / f"1__real_log.png",
            to8b(real_feedback_image),
        )

        log.info(f"!! Beginning Training !!")
        for num_iter in range(1, num_iterations + 1):
            # load the next batch of data:
            data_batch = next(training_data_loader)
            coords, gt_rgb = (
                data_batch[..., :-NUM_COLOUR_CHANNELS],
                data_batch[..., -NUM_COLOUR_CHANNELS:],
            )

            # forward pass and compute the loss
            pred_rgb = decode_coords_with_fg_and_mlp(
                coords,
                self.feature_grid,
                self.decoder_mlp,
                self.image_resolution,
            )
            loss = l1_loss(pred_rgb, gt_rgb)

            # perform single step of optimization
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

            # verbose logging per iteration:
            loss_value = loss.item()
            psnr_value = mse2psnr(mse_loss(pred_rgb, gt_rgb).item())

            # tensorboard summaries feedback (logged every iteration)
            for summary_name, summary_value in (
                ("loss", loss_value),
                ("psnr", psnr_value),
            ):
                if summary_value is not None:
                    tensorboard_writer.add_scalar(
                        summary_name, summary_value, global_step=num_iter
                    )

            # console loss feedback log
            if self._check_log_condition(
                num_iter, loss_feedback_frequency, 1, num_iterations
            ):
                loss_info_string = (
                    f"Global Iteration: {num_iter} "
                    f"Loss: {loss_value: .5f} "
                    f"PSNR: {psnr_value: .5f} "
                )
                log.info(loss_info_string)

            # step the learning rate schedulers
            if num_iter % lr_decay_steps == 0:
                lr_scheduler.step()
                new_lrs = [param_group["lr"] for param_group in optimizer.param_groups]
                log_string = f"Adjusted learning rate | learning rate: {new_lrs} "
                log.info(log_string)

            # save the rendered feedback
            if self._check_log_condition(
                num_iter, feedback_frequency, 1, num_iterations
            ):
                imageio.imwrite(
                    render_dir / f"render_log_{num_iter}.png",
                    to8b(self.render().numpy()),
                )

            # obtain and log test metrics
            if self._check_log_condition(
                num_iter, testing_frequency, 1, num_iterations
            ):
                log.info(f"Computing test score ...")
                test_psnr = mse2psnr(
                    mse_loss(
                        self.render(),
                        torch.from_numpy(real_feedback_image),
                    ).item()
                )
                log.info(f"Full image PSNR: {test_psnr: .5f}")
                tensorboard_writer.add_scalar(
                    "full_image_psnr", test_psnr, global_step=num_iter
                )

            # save the model
            if self._check_log_condition(num_iter, save_frequency, 1, num_iterations):
                torch.save(
                    self.get_save_info(),
                    model_dir / f"model_iter_{num_iter}.pth",
                )

        # save the final model
        torch.save(self.get_save_info(), model_dir / f"model_final.pth")
        log.info("!! Training complete !!")

def load_trained_image_model(
    model_path: Path, device: torch.device, verbose_creation: bool = True
) -> ImageModel:
    loaded_model = torch.load(model_path)
    if verbose_creation:
        log.info(f"loaded trained model from: {model_path}")
    img_mod = ImageModel(
        **loaded_model["conf"],
        device=device,
        verbose_creation=verbose_creation,
        decoder_mlp_maker=partial(
            get_default_image_decoder_mlp,
            **loaded_model["decoder_mlp"]["conf"],
        ),
    )
    img_mod.feature_grid.load_state_dict(loaded_model["feature_grid"]["state_dict"])
    img_mod.decoder_mlp.load_weights(loaded_model["decoder_mlp"])
    return img_mod


import torch

def unpack_data(results):
    pix = results['input']
    hand_pix = results['hand_pix']
    fake_fish_depth = results['fake_fish_depth']
    heatmap = results['heatmap']
    heatmap_true = results['heatmap_true']
    heatmap_reprojected = results['heatmap_reprojected']
    joint = results['joint']

    return pix, hand_pix, fake_fish_depth, heatmap, heatmap_true, heatmap_reprojected, joint


import setuptools

with open('README.md', 'r') as fh:
    long_description = fh.read()

setuptools.setup(
    name='bhamcal',
    version='0.1',
    license='GPL 3',
    python_requires='>=3',

    author='Justin Chadwell',
    author_email='jedevc@gmail.com',

    url='https://github.com/jedevc/bhamcal',
    description='A timetable extractor for University of Birmingham',
    long_description=long_description,
    long_description_content_type='text/markdown',

    packages=setuptools.find_packages(),
    install_requires=[
        'click',
        'colorama',
        'beautifulsoup4',
        'pytz',
        'google-api-python-client',
        'google-auth-httplib2',
        'google-auth-oauthlib'
    ],

    extras_require={
        'browser': ['selenium']
    },

    entry_points={
        'console_scripts': [
            'bhamcal=bhamcal:main'
        ]
    },
)


# count 메소드를 활용해서 풀어보자

s='110010101001'
answer=[]
num=0
cnt=0
zero=0

while (not (s=='1')):
    ones = s.count('1')
    zero += len(s)-ones
    s=bin(ones)[2:]
    cnt+=1

# while(True):

#     if(s=='1'):
#         break
#     #0 걷어내기
#     new_s=''

#     for i in s:
#         if (i=='1'):
#             new_s+=i
#         else:
#             zero+=1

#     c=len(new_s)
#     s=bin(c)[2:]

#     # print('new',s,new_s)
#     cnt+=1
#     if(cnt>10):
#         break

answer.append(cnt)
answer.append(zero)
print(answer)