from django.db.models import Q
from django.test import TestCase
from unittest.mock import patch

from corehq.apps.users.models import HqPermissions
from corehq.apps.users.models_role import UserRole, RolePermission, Permission
from corehq.apps.users.management.commands.add_data_dict_permissions import (
    build_role_can_edit_commcare_data_q_object,
    build_role_can_export_data_q_object,
    build_role_can_download_data_files_q_object,
    role_can_view_data_tab,
    role_already_migrated,
    get_user_role_ids_to_migrate
)
from corehq.apps.users.permissions import EXPORT_PERMISSIONS

class TestMigrationQuery(TestCase):
    domain = "test-query"

    @classmethod
    def setUpTestData(cls):
        Permission.create_all()

    def setUp(self):
        patcher1 = patch(
            ('corehq.apps.users.management.commands.add_data_dict_permissions'
            '.DATA_FILE_DOWNLOAD.get_enabled_domains'),
            return_value=[self.domain]
        )
        patcher2 = patch(
            ('corehq.apps.users.management.commands.add_data_dict_permissions'
             '.DATA_DICTIONARY.get_enabled_domains'),
            return_value=[]
        )
        patcher3 = patch(
            ('corehq.apps.users.management.commands.add_data_dict_permissions'
             '.get_domains_with_privilege'),
            return_value=[self.domain]
        )
        patcher1.start()
        patcher2.start()
        patcher3.start()
        self.role = UserRole(domain=self.domain, name="role1")
        self.role.save()
        self.addCleanup(self.role.delete)
        self.addCleanup(patcher1.stop)
        self.addCleanup(patcher2.stop)

    def test_role_has_edit_data_permission(self):
        self.role.rolepermission_set.set([
            RolePermission(permission=HqPermissions.edit_data.name)
        ], bulk=False)

        can_edit_commcare_data = build_role_can_edit_commcare_data_q_object()
        queried_role_ids = self._query_role(can_edit_commcare_data)
        self.assertQuerysetEqual(queried_role_ids, [self.role.id], ordered=False)

    def test_role_has_all_reports_permission(self):
        self.role.rolepermission_set.set([
            RolePermission(permission=HqPermissions.view_reports.name)
        ], bulk=False)

        self.can_export_data = build_role_can_export_data_q_object()
        queried_role_ids = self._query_role(self.can_export_data)
        self.assertQuerysetEqual(queried_role_ids, [self.role.id], ordered=False)

    def test_role_has_export_reports_permission(self):
        self.role.rolepermission_set.set([
            RolePermission(permission=HqPermissions.view_reports.name, allow_all=False,
                allowed_items=list(EXPORT_PERMISSIONS))
        ], bulk=False)

        self.can_export_data = build_role_can_export_data_q_object()
        queried_role_ids = self._query_role(self.can_export_data)
        self.assertQuerysetEqual(queried_role_ids, [self.role.id], ordered=False)

    def test_role_has_download_data_files_permission(self):
        self.role.rolepermission_set.set([
            RolePermission(permission=HqPermissions.view_file_dropzone.name)
        ], bulk=False)

        self.can_download_data_files = build_role_can_download_data_files_q_object()
        queried_role_ids = self._query_role(self.can_download_data_files)
        self.assertQuerysetEqual(queried_role_ids, [self.role.id], ordered=False)

    def test_role_can_view_data_tab_all_permissions(self):
        perms = HqPermissions.max()
        setattr(perms, HqPermissions.view_data_dict.name, False)
        setattr(perms, HqPermissions.edit_data_dict.name, False)
        self.role.set_permissions(perms.to_list())

        can_view_data_tab = role_can_view_data_tab()
        queried_role_ids = self._query_role(can_view_data_tab)
        self.assertQuerysetEqual(queried_role_ids, [self.role.id], ordered=False)

    def test_role_can_not_view_data_tab(self):
        perms = HqPermissions.max()
        perms = self._revoke_permissions_to_access_data_dict(perms)
        self.role.set_permissions(perms.to_list())

        can_not_view_data_tab = ~role_can_view_data_tab()
        queried_role_ids = self._query_role(can_not_view_data_tab)
        self.assertQuerysetEqual(queried_role_ids, [self.role.id], ordered=False)

    def test_role_already_migrated(self):
        self.role.rolepermission_set.set([
            RolePermission(permission=HqPermissions.edit_data_dict.name)
        ], bulk=False)
        role_migrated = role_already_migrated()
        queried_role_ids = self._query_role(role_migrated)
        self.assertQuerysetEqual(queried_role_ids, [self.role.id], ordered=False)

    def test_get_user_roles_to_migrate(self):
        perms = HqPermissions.max()
        self.role.set_permissions(perms.to_list())

        user_roles_to_migrate_ids = get_user_role_ids_to_migrate()
        self.assertFalse(user_roles_to_migrate_ids.exists())

        setattr(perms, HqPermissions.view_data_dict.name, False)
        setattr(perms, HqPermissions.edit_data_dict.name, False)
        self.role.set_permissions(perms.to_list())
        self.assertCountEqual(user_roles_to_migrate_ids, [self.role.id])

    def _query_role(self, filter_query: Q):
        user_roles_can_view_data_tab_id = (UserRole.objects
                    .filter(domain=self.domain)
                    .filter(filter_query)
                    .distinct()
                    .values_list("id", flat=True)
        )
        return user_roles_can_view_data_tab_id

    def _revoke_permissions_to_access_data_dict(self, perms: HqPermissions):
        permissions = {
            HqPermissions.view_data_dict.name: False,
            HqPermissions.edit_data_dict.name: False,
            HqPermissions.edit_data.name: False,
            HqPermissions.view_reports.name: False,
            HqPermissions.view_report_list.name: ["not_export_permission"],
            HqPermissions.view_file_dropzone.name: False,
            HqPermissions.edit_file_dropzone.name: False
        }
        for name, value in permissions.items():
            setattr(perms, name, value)

        return perms


from __future__ import print_function
from __future__ import division
import numpy as np
import pyigrf

def llh2xyz(latg,lon,h):
    # returns geocentric xyz coordinates (ECEF) in km of a target with
    # latitude       latg (rad) --- geodetic
    # longitude      lon (rad)
    # height         h (km above local ellipsoid)
    n=a_WGS / np.sqrt(1.-flatness*(2.-flatness) * np.sin(latg)**2.)
    # cartesian geocentric coordinates wrt Greenwich
    x=(n+h)*np.cos(latg)*np.cos(lon)
    y=(n+h)*np.cos(latg)*np.sin(lon)
    z=(n*(1.-eccentricity**2.)+h)*np.sin(latg)
    return x,y,z

def xyz2llh(x,y,z):
    """Returns longitude 'lon', geodetic latitude 'lat', and height 'h'
    of position (x,y,z) defined in geocentric coordinate system (ECEF)

    Parameters
    ----------
    x : array_like or single number
        ECEF x component in km
    y : array_like or single number
        ECEF y component in km
    z : array_like or single number
        ECEF z component in km

    Returns
    -------
    lat : array_like or single number
        geodetic latitude in rad
    lon : array_like or single number
        longitude in rad
    h : array_like of single number
        altitude in km

    """

    p=np.sqrt(x**2.+y**2.)
    lon=np.arctan2(y,x)
    lat=np.arctan2(z,p)
    latp=lat.copy()
    for i in range(10):
        n=a_WGS/np.sqrt(1.-flatness*(2-flatness)*np.sin(latp)**2.)
        h=p/np.cos(latp)-n
        lat=np.arctan(z/(p*(1.-n*eccentricity**2./(n+h))))
        if (abs(lat-latp)<3.*eps).all():
            n=a_WGS/np.sqrt(1.-flatness*(2.-flatness)*np.sin(lat)**2.)
            h=p/np.cos(lat)-n
            break
        latp=lat.copy()
    return lat,lon,h

def enu2xyz(xr,yr,zr,east,north,up):
    # moves a point from xr,yr,zr to x,y,z by moving into the direction
    # specified by east,north,up (enu) coordinates in km
    latg,lon,h = xyz2llh(xr,yr,zr)
    A = np.array([
        [-np.sin(lon), -np.sin(latg)*np.cos(lon), np.cos(latg)*np.cos(lon)],
        [ np.cos(lon), -np.sin(latg)*np.sin(lon), np.cos(latg)*np.sin(lon)],
        [           0,  np.cos(latg)            , np.sin(latg)]])
    x,y,z = np.dot(A,np.array([east,north,up]))+np.array([xr,yr,zr])
    return x,y,z

def blowup(arr,rep):            # enlarges square array arr by a factor rep
    dimarr = int(np.sqrt(np.size(arr)))
    dim = dimarr * rep
    arrl = np.zeros([dim,dim])
    for m in range(dimarr):
        for n in range(dimarr):
            arrl[m*rep:(m+1)*rep,n*rep:(n+1)*rep] = arr[m,n]
    return arrl

# --------------------------------------------------------------

eps=np.finfo(float).eps         # float resolution
deg=np.pi/180.                  # to express angles in degree values

# WGS84 constants
# reference:
# http://earth-info.nga.mil/GandG/publications/tr8350.2/wgs84fin.pdf

a_WGS=6378.137         # equatorial radius WGS 84 (semi-major axis) in km
#flatness=1/298.257
flatness = 1./298.257223563  # flatenning
b_WGS=a_WGS*(1.-flatness)    # WGS polar radius (semi-minor axis) in km
eccentricity=np.sqrt(a_WGS**2-b_WGS**2)/a_WGS

# ------------ radar specifications -------------------------
class Antenna_Beam:
    def __init__(self, Bname, antenna_specs, wide_beam_pattern, beam_pattern,
            Txdir, Tydir, el, az,
            TxComb, RxComb, dir_mode, dB_threshold,Rx_order):
        self.Bname = Bname
        self.Txdir = Txdir
        self.Tydir = Tydir
        self.el = el
        self.az = az
        self.wide_beam_pattern = wide_beam_pattern
        self.wide_beam_N_pts = antenna_specs.wide_beam_N_pts
        #N = self.wide_beam_N_pts
        self.beam_pattern = beam_pattern
        self.narrow_beam_N_pts = antenna_specs.narrow_beam_N_pts
        self.ThetaX = antenna_specs.ThetaX
        self.ThetaY = antenna_specs.ThetaY
        self.rotation_xy = antenna_specs.rotation_xy
        self.ThetaXprime = antenna_specs.ThetaXprime
        self.ThetaYprime  = antenna_specs.ThetaYprime
        self.wide_ThetaX = antenna_specs.wide_ThetaX
        self.wide_ThetaY = antenna_specs.wide_ThetaY
        self.TxComb = TxComb
        self.RxComb = RxComb
        self.dir_mode = dir_mode
        self.dB_threshold = dB_threshold
        self.Rx_order = Rx_order

    def get_basic_info(self):
        return {'Bname':self.Bname,'el':self.el,'az':self.az,
                'Txdir':self.Txdir, 'Tydir':self.Tydir,
                'TxComb':self.TxComb,'RxComb':self.RxComb,
                'dir_mode':self.dir_mode,'dB_threshold':self.dB_threshold,
                'Rx_order':self.Rx_order
                }

    def print_summary(self):
        print ( "%8s"%self.Bname +
                ": (Theta_x,Theta_y)=(%11.8f,%11.8f)"%(self.Txdir,self.Tydir) +
                ", (el,az)=(%6.3f,%8.3f)"%(self.el, self.az))

class radarspecs:
    """Will contain radar coordinates and coordinate conversions
    saved locations:
    JRO : lat: -11.947917 , lon: -76.872306, h0: 0.463 km
    JRO_GE : as zoom in with GoogleEarth to the center of the antenna.
    IRIS@ROI
    ALTAIR
    IRIS@URBANA
    """
    def __init__(self,lat0=None,lon0=None,h0=None,location=None,fload='',dec=0.,ha=0.,
            rotation_xy=0.,igrf_file=None):

        self.igrf0 = pyigrf.igrf_version(igrf_file) # loading the latest coefficients

        self.ph_arr_d = {}
        self.Uphs = {}
        self.ph_exp_d = {}
        self.comb4q_arr = {}
        self.wide_comb4q_arr = {}
        self.beam_pattern = {}
        self.rotation_xy = rotation_xy
        self.next_order = 0
        if lat0 != None and lon0 != None and h0 != None:
            self.lat0 = lat0 * deg
            self.lon0 = lon0* deg
            self.h0 = h0 # local height in km above reference ellipsoid
            if location == None:
                self.location = "Unknown"
            else:
                self.location = location
            self.dec = dec
            self.ha = ha
        elif location!=None:
            self.location = location.upper()
            if self.location == "JRO":
                # geodetic, the usual map or GPS latitude
                self.lat0 = -11.947917 * deg
                self.lon0 = -76.872306 * deg
                self.h0 = 0.463 # local height in km above reference ellipsoid
                self.dec=-12.88*deg
                self.ha=-(4.+37./60.)*deg # on-axis direction at JRO
            elif self.location == "JRO_GE":
                # gusing google earth to the center of the Antenna
                # -11.9514944444 = -(11.+57./60.+5.38/3600.) # 11deg57'5.38"S
                self.lat0 = -11.9514944444 * deg
                # -76.8743916667#-(76.+52./60.+27.81/3600.) #  76deg52'27.81"W
                self.lon0 = -76.8743916667 * deg
                self.h0 = 0.463 # local height in km above reference ellipsoid
                self.dec=-12.88*deg
                self.ha=-(4.+37./60.)*deg # on-axis direction at JRO
            elif self.location == "IRIS@ROI":
                #  9.39794444444 = (9.+23./60.+52.6/3600.) # 9deg23'52.60"N
                self.lat0 = 9.39794444444 * deg
                #  167.469166667 = (167.+28./60.+9./3600.) # 167deg28'9.00"E
                self.lon0 = 167.469166667 * deg
                self.h0 = 0.012
                self.dec= 8.*deg
                self.ha= 0. #
            elif self.location == "ALTAIR":
                #  9.39794444444 = (9.+23./60.+43.5/3600.) # 9deg23'43.50"N
                self.lat0 = 9.39541666667 * deg
                #  167.469166667 = (167.+28./60.+45.6/3600.) # 167deg28'45.60"E
                self.lon0 = 167.479333333 * deg
                self.h0 = 0.012
                self.dec= 30.*deg
                self.ha= 0. #
            elif self.location == "IRIS@URBANA":
                # 40.16683888888889 = (40.+10./60.+0.62/3600.) #40deg10'0.62"N
                self.lat0 = 40.16683888888889 * deg
                #-88.1586 = -(88.+9./60.+30.96/3600.) #88deg9'30.96"W
                self.lon0 = -88.1586 * deg
                self.h0 = 0.221
                self.dec= 30.*deg
                self.ha= 0. #
            elif self.location == "SANYA":
                self.lat0 = 18.34 * deg
                self.lon0 = 109.62 * deg
                self.h0 = 0.035
                self.dec= - 30.*deg
                self.ha= 0. #
            elif self.location == "PFISR":
                # source: https://amisr.com/amisr/about/about_pfisr/pfisr-specs/
                self.lat0 = 65.12992 * deg
                self.lon0 = -147.47104 * deg
                self.h0 = 0.213
                # to obtain dec and ha :
                # pfisr0 = radarbeam.radarspecs(location="PFISR")
                # xyz_target = pfisr0.elaz2xyz(1000,el=(90-real_tilt)*np.pi/180, az=real_rot*np.pi/180)
                # dec_deg, ha_min = pfisr0.xyz2dec_ha(xyz_target - pfisr0.xyz0)
                # dec_deg, ha_min
                # = (79.73223212243532, 92.21660368556627)
                self.dec= 79.73223212243532 * deg
                self.ha= 92.21660368556627 * deg #
        elif fload!='':
            fp = np.load(fload, encoding='bytes',allow_pickle=True)
            self.comb4q_arr = fp['comb4q_arr'][0]
            self.wide_comb4q_arr = fp['wide_comb4q_arr'][0]
            self.h0 = fp['h0'][0]
            self.aspect_ranges = fp['aspect_ranges']
            self.aspects = fp['aspects']
            self.B_xyz = fp['B_xyz']
            self.month = fp['month'][0]
            self.yyyymmdd = fp['yyyymmdd'][0]
            self.year = fp['year'][0]
            self.ph_exp_d = fp['ph_exp_d'][0]
            self.day = fp['day'][0]
            self.fyear = fp['fyear'][0]
            self.month_name = fp['month_name'][0]
            self.location = fp['location'][0]
            self.ph_arr_d = fp['ph_arr_d'][0]
            self.ThetaX = fp['ThetaX']
            self.ThetaY = fp['ThetaY']
            self.rotation_xy = fp['rotation_xy']
            self.ThetaXprime = fp['ThetaXprime']
            self.ThetaYprime = fp['ThetaYprime']
            self.wide_ThetaY = fp['wide_ThetaY']
            self.wide_ThetaX = fp['wide_ThetaX']
            self.lat0 = fp['lat0'][0]
            self.wide_beam_N_pts = fp['wide_beam_N_pts'][0]
            self.narrow_beam_N_pts = fp['narrow_beam_N_pts'][0]
            self.doy = fp['doy'][0]
            self.Uphs = fp['Uphs'][0]
            self.lon0 = fp['lon0'][0]
            if 'declination' in fp:
                self.dec = fp['declination'][0]
            else:
                self.dec = -12.88*deg
            if 'hour_angle' in fp:
                self.ha = fp['hour_angle'][0]
            else:
                self.ha = -(4.+37./60.)*deg # on-axis direction at JRO
            wide_beam_patterns = fp['wide_beam_patterns'][0]
            beam_patterns = fp['beam_patterns'][0]
            beams_info = fp['beams_info'][0]
            for Bname in beams_info:
                beam = beams_info[Bname]
                wide_beam_pattern = wide_beam_patterns[Bname]
                beam_pattern = beam_patterns[Bname]
                BnameAntenna = Antenna_Beam(Bname,self, wide_beam_pattern,
                        beam_pattern,
                        beam[b'Txdir'], beam[b'Tydir'], beam[b'el'],beam[b'az'],
                        beam[b'TxComb'], beam[b'RxComb'], beam[b'dir_mode'],
                        beam[b'dB_threshold'],beam[b'Rx_order'])
                self.beam_pattern.update({Bname:BnameAntenna})
            fp.close()
        else:
            # gusing google earth to the center of the Antenna
            # -11.9514944444 = -(11.+57./60.+5.38/3600.) # 11deg57'5.38"S
            self.lat0 = -11.9514944444 * deg
            # -76.8743916667#-(76.+52./60.+27.81/3600.) #  76deg52'27.81"W
            self.lon0 = -76.8743916667 * deg
            self.h0 = 0.463 # local height in km above reference ellipsoid
            self.dec=-12.88*deg
            self.ha=-(4.+37./60.)*deg # on-axis direction at JRO

            self.location = 'JRO'

        x0,y0,z0 = llh2xyz(self.lat0,self.lon0,self.h0)
        self.xyz0 = np.array([x0,y0,z0])
        xy0 = np.array([x0,y0])
        p0 = np.sqrt(np.dot(xy0,xy0))

        # unit vectors from jro
        self.east0 = np.array([-y0,x0,0])/p0
        # zenith and north directions wrt local ellipsoid
        self.zenith0 = np.array([np.cos(self.lat0) * np.cos(self.lon0),
                            np.cos(self.lat0) * np.sin(self.lon0),
                            np.sin(self.lat0)])
        self.north0 = np.cross(self.zenith0,self.east0)

        # orthonormal basis vectors including the jro on-axis direction
        self.uo = np.array([np.cos(self.dec) * np.cos(self.ha/4. + self.lon0), # on axis
                    np.cos(self.dec) * np.sin(self.ha/4. + self.lon0), np.sin(self.dec)])
        self.ux = np.cross(self.zenith0,self.uo)
        # along the building to the right
        self.ux = self.ux / np.sqrt(np.dot(self.ux,self.ux))
        # away from the building into the valley
        self.uy = np.cross(self.uo,self.ux)
        #rotation of xy plane:
        self.uDn = self.ux.copy()
        self.uUp = self.uy.copy()

    def get_beam_pattern(self, Bname):
        return self.beam_pattern[Bname]

    def get_beam_names(self):
        return list(self.beam_pattern.keys())

    def get_beam_names_ordered(self):
        oindex = []
        unordered = self.get_beam_names()
        for bname in unordered:
            oindex += [self.beam_pattern[bname].Rx_order]
        ordered = []
        for i in oindex:
            ordered +=[unordered[i]]
        return ordered

    def print_beams_summary(self,ordered=False):
        if ordered:
            bnames = self.get_beam_names_ordered()
        else:
            bnames = self.get_beam_names()
        for Bname in bnames:
            self.beam_pattern[Bname].print_summary()

    def print_html_stearing_phases(self):

        """
        Returns html code for the stearing phases table.
        """
        out = "\n"
        out += '
\n'
        for i in range(4):
            if i==3:
                comm_style = "border-bottom: 5px double;"
            else:
                comm_style = ""
            out += "
\n"
            for j in range(4):
                up = self.ph_arr_d['N']['up'][::12,::12][i,j]
                dn = self.ph_arr_d['N']['dn'][::12,::12][i,j]
                if j<3:
                    css_style = comm_style
                else:
                    css_style = comm_style + "border-right: 5px double;"
                out += '  %g
%g	\n'%(css_style,up,dn)
            for j in range(4):
                up = self.ph_arr_d['E']['up'][::12,::12][i,j]
                dn = self.ph_arr_d['E']['dn'][::12,::12][i,j]
                out += '  %g
%g	\n'%(comm_style,up,dn)
            out += "
\n"
        for i in range(4):
            comm_style = ""
            out += "
\n"
            for j in range(4):
                up = self.ph_arr_d['W']['up'][::12,::12][i,j]
                dn = self.ph_arr_d['W']['dn'][::12,::12][i,j]
                if j<3:
                    css_style = comm_style
                else:
                    css_style = comm_style + "border-right: 5px double;"
                out += '  %g
%g	\n'%(css_style,up,dn)
            for j in range(4):
                up = self.ph_arr_d['S']['up'][::12,::12][i,j]
                dn = self.ph_arr_d['S']['dn'][::12,::12][i,j]
                out += '  %g
%g	\n'%(comm_style,up,dn)
            out += "
\n"
        out += "
\n"
        out += "
Ues:\n"
        out += '
\n'
        out += "
\n"
        for i,antenna in enumerate(['W','N','E','S']):
            comm_style = "text-align: center;"
            pol = ["D","U"][(i+1)%2]
            out += '  %s%s	\n'%(antenna,pol)
            pol = ["D","U"][(i)%2]
            out += '  %s%s	\n'%(antenna,pol)
        out += "
\n"
        out += "
\n"
        for i,antenna in enumerate(['W','N','E','S']):
            comm_style = "text-align: center;"
            pol = ["dn","up"][(i+1)%2]
            out += '  %.2f	\n'%(
                                            self.Uphs[antenna][pol])
            pol = ["dn","up"][(i)%2]
            out += '  %.2f	\n'%(
                                            self.Uphs[antenna][pol])
        out += "
\n"

        out += "
\n"
        return out

    def save_beams_info(self, expname,folder=''):
        fname = (folder+'/'+'Beams_'+expname+
                '_%.4d.%.2d.%.2d.npz'%(self.year,self.month,self.day))
        print('saving... '+fname)
        beams_info = {}
        beam_patterns = {}
        wide_beam_patterns = {}
        for Bname in self.get_beam_names():
            beams_info.update({Bname:self.beam_pattern[Bname].get_basic_info()})
            beam_patterns.update({Bname:self.beam_pattern[Bname].beam_pattern})
            wide_beam_patterns.update({Bname:self.beam_pattern[Bname].wide_beam_pattern})
        np.savez_compressed(fname,
                beams_info = [beams_info],
                beam_patterns = [beam_patterns],
                wide_beam_patterns = [wide_beam_patterns],
                ThetaX = self.ThetaX,
                ThetaY = self.ThetaY,
                rotation_xy = self.rotation_xy,
                ThetaXprime = self.ThetaXprime,
                ThetaYprime = self.ThetaYprime,
                wide_ThetaX = self.wide_ThetaX,
                wide_ThetaY = self.wide_ThetaY,
                wide_beam_N_pts = [self.wide_beam_N_pts],
                narrow_beam_N_pts = [self.narrow_beam_N_pts],
                declination = [self.dec],
                hour_angle = [self.ha],
                ph_arr_d = [self.ph_arr_d],
                Uphs = [self.Uphs], lon0 = [self.lon0], lat0 = [self.lat0],
                h0 = [self.h0], location=[self.location], day = [self.day],
                doy = [self.doy], fyear = [self.fyear], month = [self.month],
                month_name = [self.month_name], year = [self.year],
                comb4q_arr= [self.comb4q_arr],
                wide_comb4q_arr= [self.wide_comb4q_arr],
                yyyymmdd = [self.yyyymmdd],
                aspect_ranges = self.aspect_ranges,
                ph_exp_d = [self.ph_exp_d],
                aspects = self.aspects,
                radar_east = self.east0,
                radar_north = self.north0,
                radar_zenith = self.zenith0,
                radar_xyz = self.xyz0,
                radar_ux = self.ux,
                radar_uy = self.uy,
                radar_uo = self.uo,
                radar_ux_prime = self.ux_prime,
                radar_uy_prime = self.uy_prime,
                B_xyz = self.B_xyz,
                ordered_bnames = self.get_beam_names_ordered())

    def set_beam_pattern(self, Bname, TxComb, RxComb, dir_mode='max',
            dB_threshold=-6, order=None):
        """
        Inputs:
            Bname: string containing the name to give to this pattern
            TxComb: string containing the antenna name, combination of
                JRO quarters corresponding to a transmitting antenna,
                created usin the self.create_4quarters routine.
            RxComb: string containing the antenna name, combination of
                JRO quarters corresponding to a transmitting antenna,
                created usin the self.create_4quarters routine.
            dir_mode: A string specifying the method of calculating
                the direction of the beam. The default is 'max' which
                finds the maximum value of the beam pattern
                'weighted_avg' is also available. This is the weighted average
                and it calculates the first moment of the beam pattern
                over the values db_threshold to 0 dB.
            dB_threshold: Used for 'weighted_avg' mode in dir_mode.
            order: The order of the receiving channel starting at 0.
                If order == None, then the order will be given as an
                increasing sequence each time this function is called.
        """
        wide_logarg = abs(self.wide_comb4q_arr[TxComb]['FFTa'])**2. * \
                abs(self.wide_comb4q_arr[RxComb]['FFTa'])**2.
        wide_logarg[wide_logarg<=0] = np.nan  # to avoid errors when calculating log10
        wide_beam_pa = 10. * np.log10(wide_logarg)
        wide_beam_pa -= np.nanmax(wide_beam_pa)  # normalizing for max value = 0 dB
        Txdir, Tydir = self.calc_Beam_Direction(wide_beam_pa, method=dir_mode,
                dB_threshold = dB_threshold)
        el, az = self.dir_cos2el_az(Txdir, Tydir)

        logarg = abs(self.comb4q_arr[TxComb]['FFTa'])**2. * \
                abs(self.comb4q_arr[RxComb]['FFTa'])**2.
        logarg[logarg<=0] = np.nan  # to avoid errors when calculating log10
        beam_pa = 10. * np.log10(logarg)
        beam_pa -= np.nanmax(beam_pa)  # normalizing for max value = 0 dB

        if type(order)==type(None):
            current_order = self.next_order
            self.next_order += 1
        else:
            current_order = order
        BnameAntenna = Antenna_Beam(Bname,self,wide_beam_pa,beam_pa,
                Txdir,Tydir,el,az,
                TxComb, RxComb, dir_mode, dB_threshold, current_order)
        self.beam_pattern.update({Bname:BnameAntenna})

        return BnameAntenna

    def calc_Beam_Direction(self, Bpattern, method='max', dB_threshold=-6):
        """Bpattern is the beam pattern with respect to the antenna
        where the coordinates of the 2D array are the direction
        cosines self.ThetaX, and self.ThetaY.
        The values are in dBs and has been normalized with the
        maximum being 0dB.
        If method = 'weighted_avg', then the input dB_threshold is used
        """
        b = Bpattern
        if method == 'max':
            [i,j]=np.unravel_index(np.nanargmax(b), b.shape)
            ThetaX_dir, ThetaY_dir = self.wide_ThetaX[i,j], self.wide_ThetaY[i,j]
        elif method == 'weighted_avg':
            b[np.isnan(b)] = dB_threshold - 1
            th_select = b >= dB_threshold
            lin_b = 10 ** (b/10.)
            b_avg = np.trapz(lin_b[th_select])
            ThetaX_dir = np.trapz((lin_b * self.wide_ThetaX)[th_select]) / b_avg
            ThetaY_dir = np.trapz((lin_b * self.wide_ThetaY)[th_select]) / b_avg
        return ThetaX_dir, ThetaY_dir

    def create_4quarters(self, CombName, N, E, W, S):
        quarters ={}
        ons = np.ones([48,48]); offs = ons * 0 # amplitude distributions
        col0 = np.zeros([48,1]); row0 = np.zeros([1,97])
        for q in 'NEWS':
            if locals()[q] == 'ons':
                quarters.update({q:ons})
            elif locals()[q] == 'offs':
                quarters.update({q:offs})
            else:
                name,pol = locals()[q].split('.')
                quarters.update({q:self.ph_exp_d[name][pol]})

        qN = quarters['N']
        qE = quarters['E']
        qW = quarters['W']
        qS = quarters['S']

        N_pts = self.wide_beam_N_pts
        N2_pts = self.narrow_beam_N_pts

        temp_wide_FFTa = np.fft.fftshift(np.fft.fft2(
            np.asarray(np.bmat('qN,col0,qE;row0;qW,col0,qS')), s=(N_pts,N_pts)))

        #temp_FFTa = temp_wide_FFTa[N_pts/2.-N_pts/16.:N_pts/2.+N_pts/16.,
        #                                N_pts/2.-N_pts/16.:N_pts/2.+N_pts/16.]
        from scipy import interpolate
        f_real = interpolate.interp2d(self.wide_ThetaX[0,:], self.wide_ThetaY[:,0],
                temp_wide_FFTa.real, kind='linear')
        f_imag = interpolate.interp2d(self.wide_ThetaX[0,:], self.wide_ThetaY[:,0],
                temp_wide_FFTa.imag, kind='linear')

        temp_FFTa = np.empty_like(self.ThetaX, dtype="complex128")
        for row,TX_row in enumerate(self.ThetaX):
            for col,TX in enumerate(TX_row):
                TY = self.ThetaY[row,col]
                temp_FFTa.real[row,col] = f_real(TX,TY)
                temp_FFTa.imag[row,col] = f_imag(TX,TY)

        if self.wide_comb4q_arr.has_key(CombName):
            # This will overwrite the quarter combination
            self.wide_comb4q_arr[CombName]['FFTa'] = temp_wide_FFTa
            self.wide_comb4q_arr[CombName]['N'] = N
            self.wide_comb4q_arr[CombName]['E'] = E
            self.wide_comb4q_arr[CombName]['W'] = W
            self.wide_comb4q_arr[CombName]['S'] = S
        else:
            # This will create a quarter combination
            self.wide_comb4q_arr.update({CombName:
                {'FFTa':temp_wide_FFTa,
                    'N':N,'E':E,'W':W,'S':S}
                })

        if self.comb4q_arr.has_key(CombName):
            # This will overwrite the quarter combination
            self.comb4q_arr[CombName]['FFTa'] = temp_FFTa
            self.comb4q_arr[CombName]['N'] = N
            self.comb4q_arr[CombName]['E'] = E
            self.comb4q_arr[CombName]['W'] = W
            self.comb4q_arr[CombName]['S'] = S
        else:
            # This will create a quarter combination
            self.comb4q_arr.update({CombName:{'FFTa':temp_FFTa,'N':N,'E':E,'W':W,'S':S} })

    def __update_exp_array(self,Aname, Apol):
        val = np.exp(2j * np.pi *
                (self.ph_arr_d[Aname][Apol] + self.Uphs[Aname][Apol])/4.)
        if self.ph_exp_d.has_key(Aname):
            self.ph_exp_d[Aname].update({Apol:val})
        else:
            self.ph_exp_d.update({Aname:{Apol:val}})

    def copy_phase_arr(self, Aname, Apol, newAname, newApol, Uph):
        """
        Copy the Aname, Apol to newAname, newApol
        """
        if self.ph_arr_d.has_key(newAname):
            self.ph_arr_d[newAname].update({newApol:self.ph_arr_d[Aname][Apol]})
            self.Uphs[newAname].update({newApol:Uph})
        else:
            self.ph_arr_d.update({newAname:{newApol:self.ph_arr_d[Aname][Apol]}})
            self.Uphs.update({newAname:{newApol:Uph}})
        self.__update_exp_array(newAname, newApol)

    def create_beam_aspect_angle_grid(self, N,N2, yyyymmdd, ranges_km, xp_overs_fact=1.,
            yp_overs_fact=1., verbose=False ):
        """
        Create grid of direction cosines ThetaX, ThetaY
        yyyymmdd : year, month and day separated by dots, e.g 2014.10.12
                   for October 12, 2014
        xp_overs_fact: oversample factor in the x prime axis(rotated by rotation_xy)
        yp_overs_fact: oversample factor in the y prime axis(rotated by rotation_xy)
        """
        from calendar import isleap, timegm
        from time import gmtime, strftime
        self.yyyymmdd = yyyymmdd
        ts = gmtime(timegm(np.array((yyyymmdd+'.0.0.0').split('.'),dtype=int)))
        self.year = ts.tm_year
        self.month = ts.tm_mon
        self.month_name = strftime('%b',ts)
        self.day = ts.tm_mday
        self.doy = ts.tm_yday
        yeardays = 366. if isleap(self.year) else 365.
        self.fyear = self.year + self.doy/yeardays
        self.wide_beam_N_pts = N
        self.narrow_beam_N_pts = N2
        [self.wide_ThetaY,self.wide_ThetaX] = np.mgrid[-N/2.:N/2.,-N/2.:N/2.]
        self.wide_ThetaY = - self.wide_ThetaY / (N / 2.)
        self.wide_ThetaX =   self.wide_ThetaX / (N / 2.)

        [self.ThetaYprime,self.ThetaXprime] = np.mgrid[
                -N2/2.*yp_overs_fact:N2/2.*yp_overs_fact,
                -N2/2.*xp_overs_fact : N2/2.*xp_overs_fact]
        self.ThetaYprime = - self.ThetaYprime / (N / 2. * yp_overs_fact)
        self.ThetaXprime =   self.ThetaXprime / (N / 2. * xp_overs_fact)

        self.ThetaX = np.empty_like(self.ThetaXprime)
        self.ThetaY = np.empty_like(self.ThetaYprime)

        if self.rotation_xy == "opt_rot":
            rtarget = 300. * self.uo # from Antenna
            xyz = self.xyz0 + rtarget # from center of Earth
            r,lat,lon,aspect,B = self.aspect_angle(self.fyear,xyz)
            mag_B = np.sqrt(np.dot(B,B))
            mag_uy = np.sqrt(np.dot(self.uy,self.uy))
            opt_rot = np.arccos(np.dot(self.uy,B)/mag_B/mag_uy)
            self.rotation_xy = opt_rot
        cosrot = np.cos(self.rotation_xy)
        sinrot = np.sin(self.rotation_xy)
        self.ux_prime = cosrot * self.uDn + sinrot * self.uUp
        self.uy_prime = -sinrot * self.uDn + cosrot * self.uUp

        for row,Xp_row in enumerate(self.ThetaXprime):
            for col,Xp in enumerate(Xp_row):
                Yp = self.ThetaYprime[row,col]
                self.ThetaX[row,col] = cosrot * Xp - sinrot * Yp
                self.ThetaY[row,col] = sinrot * Xp + cosrot * Yp

        self.aspect_ranges = ranges_km
        self.aspects = np.empty(((len(ranges_km),)+self.ThetaX.shape))
        self.B_xyz = np.empty(((3,len(ranges_km),)+self.ThetaX.shape))
        for i, current_range in enumerate(ranges_km):
            if verbose:
                print("calculating B at %.2f. range %d out of %d."%(
                        current_range,i+1,len(ranges_km)))
            for row,Xp_row in enumerate(self.ThetaX):
                for col,Xp in enumerate(Xp_row):
                    [r,lon,lat,dec,ha,aspect,B] = self.aspect_txty(self.fyear,
                            current_range, self.ThetaX[row,col], self.ThetaY[row,col])
                    self.aspects[i,row,col] = aspect * 180. / np.pi
                    self.B_xyz[:,i,row,col] = B

    def add_phase_arr(self, Aname, Apol, rep, phs, Uph=0.,add_to_cables=0.):
        """
        Aname: Name of the Antenna e.g. 'N','S','W','E'
        Apol: Polarizarion of the Antenna, e.g 'up', 'dn'
        rep: Number of dipoles per unit block, e.g. 12
        phs: nxn phases, e.g. 4x4 phases
        """
        phs = np.array(phs) + add_to_cables
        phs[phs>5] -= 4
        phs[phs<2] += 4
        if self.ph_arr_d.has_key(Aname):
            self.ph_arr_d[Aname].update({Apol:blowup(phs,rep)})
            self.Uphs[Aname].update({Apol:Uph})
        else:
            self.ph_arr_d.update({Aname:{Apol:blowup(phs,rep)}})
            self.Uphs.update({Aname:{Apol:Uph}})
        self.__update_exp_array(Aname, Apol)

    def locations(self):
        return ["JRO","JRO_GE","IRIS@ROI","ALTAIR","IRIS@URBANA"]

    def dec_ha2el_az(self,dec,ha):
        # returns elevation and azimuth angles of a radar beam
        # with respect to local tangent plane.
        # the beam is specified by:
        #		declination dec (deg)
        #		hour angle  ha  (min)
        # with respect to radar location at longitude lon0 and height h0
        # above reference ellipsiod at geodetic latitude lat0

        lat = dec * deg                 # on celestial sphere
        lon = 2. * np.pi * (ha/(24.*60.))
        lon = lon + self.lon0                # on celestial sphere
        vec = np.array([np.cos(lat) * np.cos(lon), np.cos(lat) * np.sin(lon),
                        np.sin(lat)])
        hor = vec - np.dot(vec, self.zenith0) * self.zenith0
        hor = hor / np.sqrt(np.dot(hor, hor))
        el = np.arccos(np.dot(hor, vec)) / deg
        north = np.dot(hor, self.north0)
        east = np.dot(hor, self.east0)
        az = np.arctan2(east, north)/deg
        return el,az

    def xyz2dec_ha(self,vec):
        """    declination and hour angle in target direction used to
        describe radar beam direction at JRO, corresponding to latitude and
        relative longitude of the beam-spot on the celestial sphere, corresponds
        to rr->\infty, in which case:"""
        vec = vec/np.sqrt(np.dot(vec,vec))
        p = np.sqrt(vec[0]**2.+vec[1]**2.)
        dec = np.arctan2(vec[2],p)/deg                           # in degrees
        ha = (np.arctan2(vec[1],vec[0]) - self.lon0)*(24./(2.*np.pi))*60.    # in minutes
        return dec,ha

    def dir_cos2xyz(self, Theta_x, Theta_y):
        """    Direction Cosines Theta_x and Theta_y describe radar beam
        direction with respect to the antenna of a radar.
        input: direction cosines
        output: unit vector in ECEF"""
        Theta_z = np.sqrt(1. - (Theta_x ** 2. + Theta_y ** 2.))
        return  Theta_x * self.ux + Theta_y * self.uy + Theta_z * self.uo

    def dir_cos2el_az(self, Theta_x, Theta_y):
        """    Direction Cosines Theta_x and Theta_y describe radar beam
        direction with respect to the antenna of a radar.
        input: direction cosines
        output: elevation and azimuth angles"""
        beam_hat = self.dir_cos2xyz(Theta_x, Theta_y)
        vert_comp = np.dot(beam_hat, self.zenith0) * self.zenith0
        horiz_comp = beam_hat - vert_comp
        horiz_hat = horiz_comp / np.sqrt(np.dot(horiz_comp,horiz_comp))
        el = np.arccos(np.dot(horiz_hat, beam_hat)) / deg
        north_comp = np.dot(horiz_hat, self.north0)
        east_comp  = np.dot(horiz_hat, self.east0)
        az = np.arctan2(east_comp, north_comp) / deg
        return el,az

    def aspect_angle(self,year,xyz,radar_xyz=None):
        # returns the magnetic aspect angle (rad) of a target with
        # geocentric vector xyz defined in geocentric coordinates

        r   = np.sqrt(np.dot(xyz,xyz))    # from center of earth
        p   = np.sqrt(xyz[0]**2. + xyz[1]**2.)
        lat = np.arctan2(xyz[2],p)      # geocentric latitude (theta)
        lon = np.arctan2(xyz[1],xyz[0]) # geocentric or geodetic longitude (phi)
        radial = xyz/r;     # radial direction of target from center of Earth
        east   = np.array([-xyz[1],xyz[0],0.])/p  # geocentric or geodetic east
        north  = -np.cross(east,radial)   # geocentric north unit vector
        if type(radar_xyz) == type(None):
            rr = xyz - self.xyz0     # target vector from radar antenna
        else:
            rr = xyz - radar_xyz
        u_rr = rr / np.sqrt(np.dot(rr,rr))   # unit vector from radar to target
        [bX,bY,bZ,bB] = self.igrf0.igrf_B(year, r - self.igrf0.a, lon/deg, lat/deg)
        bfield = np.array([bX,bY,bZ])
        B = bX*north + bY*east - bZ*radial
        u_B = B / np.sqrt(np.dot(B,B))
        aspect = np.arccos(np.dot(u_B, u_rr))
        return r,lat,lon,aspect,B

    def aspect_txty(self,year,rr,tx,ty):
        # returns magnetic aspect angle and geocentric coordinates of a target
        # tracked by jro at
        # range rr (km)
        # tx along jro building
        # ty into the building

        tz = np.sqrt(1.-tx**2.-ty**2.)
        #geocentric coordinates of target
        xyz = self.xyz0 + rr*(tx*self.ux + ty*self.uy + tz*self.uo)

        [r,lat,lon,aspect,B] = self.aspect_angle(year,xyz)
        [dec,ha] = self.xyz2dec_ha(xyz - self.xyz0)
        return r,lon,lat,dec,ha,aspect,B

    def elaz2xyz(self,rr,el,az):
        """
        returns the xyz ECEF coordinates of a target specified by elevation and
        azimuth and range from a radar.
        # range       rr (km)
        # elevation   el (rad above local tangent plane to ellipsoid)
        # azimuth     az (rad east of local north)
        """
        tx = np.cos(el) * np.sin(az)        # direction cosines wrt east and north
        ty = np.cos(el) * np.cos(az)
        tz = np.sin(el)
        #geocentric coordinates of target :
        xyz = self.xyz0 + rr*(tx * self.east0 + ty*self.north0+tz*self.zenith0)

        return xyz

    def aspect_elaz(self,year,rr,el,az):
        # returns magnetic aspect angle and geocentric coordinates of a target
        # tracked by jro at
        # range       rr (km)
        # elevation   el (rad above local tangent plane to ellipsoid)
        # azimuth     az (rad east of local north)

        xyz = self.elaz2xyz(rr,el,az)

        [r,lat,lon,aspect,B] = self.aspect_angle(year,xyz)
        [dec,ha] = self.xyz2dec_ha(xyz - self.xyz0)
        return r,lon,lat,dec,ha,aspect,B


import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
import sqlite3
import datetime as dt

conn = sqlite3.connect('/Users/apurvasaksena/Desktop/database.sqlite')
cursor = conn.cursor()
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")

df_league = pd.read_sql_query("select * from League;", conn)
df_league.head()
df_player_attributes = pd.read_sql_query("select * from Player_Attributes;", conn)
df_player = pd.read_sql_query("select * from Player;", conn)
df_match = pd.read_sql_query("select * from Match;", conn)
df_country = pd.read_sql_query("select * from Country;", conn)
df_team_attributes = pd.read_sql_query("select * from Team_Attributes;", conn)
df_team = pd.read_sql_query("select * from Team;", conn)

df_match.isna().sum()
df_match = df_match[['country_id', 'league_id', 'season', 'stage', 'date', 'match_api_id', 'home_team_api_id', 'away_team_api_id', 'home_player_1',
       'home_player_2', 'home_player_3', 'home_player_4', 'home_player_5','home_player_6', 'home_player_7', 'home_player_8', 'home_player_9',
       'home_player_10', 'home_player_11', 'away_player_1', 'away_player_2','away_player_3', 'away_player_4', 'away_player_5', 'away_player_6',
       'away_player_7', 'away_player_8', 'away_player_9', 'away_player_10','away_player_11']]

df_match.isna().sum()

df_team_attributes = df_team_attributes[['id', 'team_api_id', 'date']]
df_team_attributes.isna().sum()

df_team.isna().sum()
df_team = df_team[['id', 'team_api_id', 'team_long_name']]
df_team.isna().sum()

df_player.isna().sum()
df_player = df_player[['player_api_id', 'player_name' ]]

df_player_attributes = df_player_attributes[[ 'player_api_id', 'date', 'overall_rating','potential']]
df_player_attributes.isna().sum()

df_player_attributes = df_player_attributes.dropna()
df_player_attributes.isna().sum()


class Solution(object):
    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: None Do not return anything, modify matrix in-place instead.
        """
        n = len(matrix)
        # diag
        for i in range(0, n):
            for j in range(0, i):
                swap(matrix, (i, j), (j, i))

        # left right
        for i in range(0, n):
            for j in range(0, n / 2):
                swap(matrix, (i, j), (i, n - j - 1))

        return None

def swap(matrix, n1, n2):
    tmp = matrix[n1[0]][n1[1]]
    matrix[n1[0]][n1[1]] = matrix[n2[0]][n2[1]]
    matrix[n2[0]][n2[1]] = tmp


from math import sqrt
from random import random
"""
 ORC: 1000-2500
 ELF: 1500-2000

"""
ORC_START_MAX_LIFE = 2500
ORC_START_MIN_LIFE = 1000
ELF_START_MAX_LIFE = 2000
ELF_START_MIN_LIFE = 1500
MAX_GRID_UNITS_X = 100
MAX_GRID_UNITS_Y = 100

AMULET_ITEM = 0
WEAPON_ITEM = 1
HEALING_ITEM = 2

def getRandomBetween(min,max):
    return random()*(max-min)+min

def getDistance(x1,y1,x2,y2):
    return sqrt( (x2-x1)**2 + (y2-y1)**2  )

class Horde:
    # when fighting the opponent on creature will not be set as there can be many to one Battle
    def __init__(self):
        self.members = []
        self.opponent = None
        self.x = 0
        self.y = 0
        self.speed_x = 0
        self.speed_y = 0
        self.mate = None

    def addMember(self, creature):
        self.members.append(creature)
    def getMembers(self):
        return self.members
    def setMate(self, m):
        self.mate = m
    def isFighting(self):
        return self.opponent is not  None
    def isMating(self):
        return self.mate is not  None
    def setOpponent(self, opp):
        self.opponent =  opp
    def getOpponent(self):
        return self.opponent
    def isAlive(self):
        for i in self.members:
            if i.isAlive:
                return True
        return False
    def move(self):
        cx = 0
        cy = 0

        for i in self.members:
            i.move( [self.speed_x, self.speed_y] )
            cx = cx + i.getX()
            cy = cy + i.getY()

        self.x = int(cx/len(self.members))
        self.y = int(cy/len(self.members))

    def invertSpeedX(self):
        self.speed_x = self.speed_x * -1
    def invertSpeedY(self):
        self.speed_y = self.speed_y * -1
    def newSpeed(self):
        self.speed_x = int(getRandomBetween(-4,4))
        self.speed_y = int(getRandomBetween(-4,4))
    def getX(self):
        return self.x
    def getY(self):
        return self.y
    def getSpeedX(self):
        return self.speed_x
    def getSpeedY(self):
        return self.speed_y

    def takeItems(self, items):
        for i in self.members:
            for j in items:
                dist = getDistance(i.getX(), i.getY(), j.getX(), j.getY())
                if dist < 5 :
                    j.apply(i)

    def cleanMembers(self):
        alive = []
        for i in self.members:
            if i.isAlive():
                alive.append(i)
        self.members = alive
    def __str__(self):
        res = "" + f'x:{self.x} y:{self.y} sx:{self.speed_x} sy:{self.speed_y} \n'
        for i in self.members:
            res = res + f'{i}{i.life}\n'
        return res

class Creature:
    def __init__(self):
        self.magic = 0
        self.life = 0
        self.start_life = 0
        self.strength = 0
        self.x = 0
        self.y = 0
        self.speed_x = 0
        self.speed_y = 0
        self.strength_mult = 1
        self.magic_mult = 1
        self.x = int(getRandomBetween(0,MAX_GRID_UNITS_X))
        self.y = int(getRandomBetween(0,MAX_GRID_UNITS_Y))
        self.opponent = None
        self.mate = None
    def addMagic(self, m):
        self.magic = self.magic + m
    def addStrength(self, s):
        self.strength = self.strength + s
    def recover(self, pct):
        self.life = min(self.start_life ,  self.life + int(self.start_life*pct))
    def setOpponent(self,opp):
        self.opponent = opp
    def getOpponent(self):
        return self.opponent
    def setMate(self, m):
        self.mate = m
    def isFighting(self):
        return self.opponent is not  None
    def isMating(self):
        return self.mate is not  None
    def getX(self):
        return self.x
    def getY(self):
        return self.y
    def getSpeedX(self):
        return self.speed_x
    def getSpeedY(self):
        return self.speed_y
    def getItem(self, item):
        return True
    def getHit(self):
        return self.strength*self.strength_mult + self.magic*self.magic_mult
    def setDamage(self, damage):
        self.life = max(0,self.life - damage )
    def takeItems(self, items):
        for j in items:
            dist = getDistance(self.getX(), self.getY(), j.getX(), j.getY())
            if dist < 5 :
                j.apply(self)
    def isAlive(self):
        return self.life > 0
    def move(self, us =  None ):

        if(us is None):
            self.x = self.x + self.speed_x
            self.y = self.y + self.speed_y
        else:
            self.speed_x = us[0]
            self.speed_y = us[1]
            self.x = self.x + self.speed_x
            self.y = self.y + self.speed_y

    def invertSpeedX(self):
        self.speed_x = self.speed_x * -1
    def invertSpeedY(self):
        self.speed_y = self.speed_y * -1
    def newSpeed(self):
        self.speed_x = int(getRandomBetween(-8,8))
        self.speed_y = int(getRandomBetween(-8,8))
    def __str__(self):
        # https://stackoverflow.com/questions/45310254/fixed-digits-after-decimal-with-f-strings
        return f'(x:{self.x} y:{self.y} l:{self.life:.2f} m:{self.magic:.2f} s:{self.strength:.2f})'

class Elf(Creature):
    def __init__(self):
        super().__init__()
        self.start_life = getRandomBetween(ELF_START_MIN_LIFE, ELF_START_MAX_LIFE)
        self.life = self.start_life
        self.strength_mult = 0.2
        self.magic_mult = 0.8
        self.magic = getRandomBetween(60,120)
        self.strength = getRandomBetween(20,50)
        self.newSpeed()

class Orc(Creature):
    def __init__(self):
        super().__init__()
        self.start_life = getRandomBetween(ORC_START_MIN_LIFE, ORC_START_MAX_LIFE)
        self.life = self.start_life
        self.strength_mult = 0.7
        self.magic_mult = 0.3
        self.magic = getRandomBetween(1,10)
        self.strength = getRandomBetween(50,140)
        self.newSpeed()

class Troll(Creature):
    def __init__(self):
        super().__init__()
        self.start_life = getRandomBetween(100000, 200000)
        self.life = self.start_life
        self.strength_mult = 5
        self.magic_mult = 5
        self.magic = getRandomBetween(1000,2000)
        self.strength = getRandomBetween(1000,2000)

class Item:
    def __init__(self, type, x, y):
        self.type = type
        self.x = x
        self.y = y
        self.taken = False

    def getX(self):
        return self.x

    def getY(self):
        return self.y

    def isTaken(self):
        return self.taken

    def apply(self, creature):
        if( self.taken ):
            return
        self.taken = True

        if type(creature) is Elf and self.type == AMULET_ITEM :
            creature.addMagic(40)
        if type(creature) is Orc and self.type == WEAPON_ITEM :
            creature.addStrength(30)
        if type(creature) is Elf and self.type == WEAPON_ITEM :
            creature.addStrength(10)
        if(self.type == HEALING_ITEM):
            creature.recover(0.5)

        print(f"\n ****** ITEM Applying item {self.type} to {creature} \n")

class World :
    def __init__(self, elfs = 0, orcs = 0, trolls = 0):
        self.creatures = []
        self.items = []
        self.elf_hordes = []
        self.orc_hordes = []
        self.day = 0
        self.trolls = []

        for i in range(0,elfs):
            self.creatures.append( Elf() )

        for i in range(0,orcs):
            self.creatures.append( Orc() )

        for i in range(0,trolls):
            self.trolls.append( Troll() )

        self.items.append( Item(AMULET_ITEM, getRandomBetween(0, 100), getRandomBetween(0, 100) ) )
        self.items.append( Item(AMULET_ITEM, getRandomBetween(0, 100), getRandomBetween(0, 100) ) )
        self.items.append( Item(WEAPON_ITEM, getRandomBetween(0, 100), getRandomBetween(0, 100) ) )
        self.items.append( Item(WEAPON_ITEM, getRandomBetween(0, 100), getRandomBetween(0, 100) ) )
        self.items.append( Item(HEALING_ITEM, getRandomBetween(0, 100), getRandomBetween(0, 100) ) )
        self.items.append( Item(HEALING_ITEM, getRandomBetween(0, 100), getRandomBetween(0, 100) ) )

    def moveEntity(self , entity , days):

        if(days%5 == 0):
            entity.newSpeed()
        if( entity.getX()+entity.getSpeedX() > MAX_GRID_UNITS_X and entity.getSpeedX() > 0 ):
            entity.invertSpeedX()
        if( entity.getX()+entity.getSpeedX() < 0 and entity.getSpeedX() < 0 ):
            entity.invertSpeedX()

        if( entity.getY()+entity.getSpeedY() > MAX_GRID_UNITS_Y and entity.getSpeedY() > 0 ):
            entity.invertSpeedY()
        if( entity.getY()+entity.getSpeedY() < 0  and entity.getSpeedY() < 0):
            entity.invertSpeedY()
        entity.move()

    def fight(self, c1, c2):

        if( not c1.isFighting() and  not c2.isFighting() and c1.isAlive() and c2.isAlive() and not c1.isMating() and not c2.isMating() ):
            c1.setOpponent(c2)
            c2.setOpponent(c1)

        if c1.getOpponent() is c2:
            c1.setDamage(c2.getHit())
            c2.setDamage(c1.getHit())

            if not (c1.isAlive() and c2.isAlive()):
                c1.setOpponent(None)
                c2.setOpponent(None)

    def horde(self, c1, c2):
        print("horde!")
        if( not c1.isFighting() and  not c2.isFighting() and c1.isAlive() and c2.isAlive() and not c1.isMating() and not c2.isMating() ):
            c1.setMate(c2)
            c2.setMate(c1)

            h = Horde()
            h.addMember(c1)
            h.addMember(c2)

            return h
        return None

    def horde_fight(self, m1,m2):

        a = m1 if (len(m1) > len(m2) ) else m2
        b = m2 if (len(m1) > len(m1) ) else m1

        i = 0
        j = 0
        for i in range (0, len(a) ):
            c1 = a[i]
            c2 = b[i%len(b)]
            c1.setDamage(c2.getHit())
            c2.setDamage(c1.getHit())

        print( f'{a}{b}')

    def hordes_fight(self, h1, h2):
        a = h1
        b = h2
        if (not a.isFighting() and not a.isMating() and a.isAlive()) and  (not b.isFighting() and not b.isMating() and b.isAlive()):
            h1.setOpponent(h2)
            h2.setOpponent(h1)

        if h1.getOpponent() is h2:
            print( "fighting!!!!")
            self.horde_fight( h1.getMembers() , h2.getMembers()  )
            h1.cleanMembers()
            h2.cleanMembers()
            if( not (h1.isAlive()  and h2.isAlive() ) ):
                print("******************** dead!")
                h1.setOpponent(None)
                h2.setOpponent(None)

    def update(self):
        minDistance = 50
        self.day = self.day + 1

        # update move and horde merging
        hordes_to_remove = []
        for i in range(0, len(self.elf_hordes)):
            a = self.elf_hordes[i]
            a.takeItems(self.items)
            if( not a.isMating() and not a.isFighting() and a.isAlive()  ):
                for j in range(i+1, len(self.elf_hordes)):
                    b = self.elf_hordes[j]
                    print("do")
                    if (not a.isMating() and a.isAlive() and not a.isFighting()) and (not b.isMating and b.isAlive() and not b.isFighting()):
                        a.setMate(b)
                        b.setMate(a)
                        a.getMembers().extend(b.getMembers())
                        hordes_to_remove.append(b)

                if not self.elf_hordes[i].isMating() :
                    self.moveEntity(self.elf_hordes[i], self.day)

        i = 0
        h_len = len(hordes_to_remove)
        while i < h_len:
            self.elf_hordes.remove(  hordes_to_remove.pop(0)  )
            i = i+1

        hordes_to_remove = []
        # update move and horde merging
        for i in range(0, len(self.orc_hordes)):
            a = self.orc_hordes[i]
            a.takeItems(self.items)
            if( not a.isMating() and not a.isFighting() and a.isAlive()  ):
                for j in range(i+1, len(self.orc_hordes)):
                    b = self.orc_hordes[j]
                    print("do")
                    if (not a.isMating() and a.isAlive() and not a.isFighting()) and (not b.isMating and b.isAlive() and not b.isFighting()):
                        a.setMate(b)
                        b.setMate(a)
                        a.getMembers().extend(b.getMembers())
                        hordes_to_remove.append(b)

                if not self.orc_hordes[i].isMating() :
                    self.moveEntity(self.orc_hordes[i], self.day)

        # check fighting

        # check dead ones
        dead_elf_hordes = []
        dead_orc_hordes = []

        for i in range(0, len(self.elf_hordes)):
            a = self.elf_hordes[i]

            for j in range(0, len(self.orc_hordes)):
                b = self.orc_hordes[j]
                d = getDistance( a.getX(), a.getY(), b.getX() , b.getY())
                if d <= minDistance:
                    self.hordes_fight(a,b)

                if( b.isAlive() ):
                    for j in self.trolls:
                        d = getDistance( b.getX(), b.getY(), j.getX() , j.getY())
                        if( d <= minDistance ):
                            for m in b.getMembers():
                                m.setDamage( j.getHit() )
                                print("***************************** AAAAHRRRRRRRRRR TROLL")
                            break;
                if( not b.isAlive() ):
                    dead_orc_hordes.append(b) if b not in dead_orc_hordes else dead_orc_hordes
            # check trolls
            for j in self.trolls:
                d = getDistance( a.getX(), a.getY(), j.getX() , j.getY())
                if( d <= minDistance ):
                    for m in a.getMembers():
                        m.setDamage( j.getHit() )
                        print("***************************** AAAAHRRRRRRRRRR TROLL")
                    break;

            if( not a.isAlive() ):
                dead_elf_hordes.append(a)

            if( not a.isFighting() and not a.isMating() and a.isAlive()  ):
                for j in range(0, len(self.creatures)):
                    b = self.creatures[j]
                    d = getDistance( a.getX(), a.getY(), b.getX() , b.getY())
                    if d <= minDistance:
                        if type(b) is Elf:
                            if not b.isFighting() and not b.isMating() and b.isAlive():
                                a.addMember(b)
                                b.setMate(a)
                        if type(b) is Orc:
                            if not b.isFighting() and not b.isMating() and b.isAlive():
                                print("DEAD BY ELF HORDE")
                                b.setDamage(1000000) # die because many guys got to you

        for i in dead_elf_hordes:
            self.elf_hordes.remove(i)
        for i in dead_orc_hordes:
            self.orc_hordes.remove(i)

        for i in range(0, len(self.orc_hordes)):
            a = self.orc_hordes[i]
            if( not a.isFighting() and not a.isMating() and a.isAlive()  ):
                for j in range(0, len(self.creatures)):
                    b = self.creatures[j]
                    d = getDistance( a.getX(), a.getY(), b.getX() , b.getY())
                    if d <= minDistance:
                        if type(b) is Orc:
                            if not b.isFighting() and not b.isMating() and b.isAlive():
                                a.addMember(b)
                                b.setMate(a)
                        if type(b) is Elf:
                            if not b.isFighting() and not b.isMating() and b.isAlive():
                                print("DEAD BY ORC HORDE")
                                b.setDamage(1000000) # die because many guys got to you

        i = 0
        while i < len(self.elf_hordes) :
            a = self.elf_hordes[i]
            if( len(a.getMembers() ) == 1 ):
                self.creatures.append( a.getMembers()[0] )
                self.elf_hordes.remove(a)
            else:
                i = i+1

        i = 0
        while i < len(self.orc_hordes) :
            a = self.orc_hordes[i]
            if( len(a.getMembers() ) == 1 ):
                self.creatures.append( a.getMembers()[0] )
                self.orc_hordes.remove(a)
            else:
                i = i+1

        for i in range(0,len(self.creatures)):
            isFighting = False
            a = self.creatures[i]
            a.takeItems(self.items)
            for j in range(i+1, len(self.creatures) ) :
                b =self.creatures[j]
                d = getDistance( a.getX(), a.getY(), b.getX() , b.getY())
                if d <= minDistance:
                    if type(a) == type(b):
                        h = self.horde(a,b)
                        if h is not None:
                            if type(a) is Elf:
                                self.elf_hordes.append(h)
                            if type(a) is Orc:
                                self.orc_hordes.append(h)
                    else:
                        self.fight(a,b)

            if not isFighting:
                self.moveEntity(a, self.day)

        c = 0
        alive = []
        keep = True
        while keep and len(self.creatures) > 0  :
            # self.creatures[:c]
            # self.creatures[c+1:]
            if not self.creatures[c].isMating():
                if self.creatures[c].isAlive():
                    alive.append( self.creatures[c] )
            else:
                self.creatures[c].setMate(None)
            c = c+1
            if( c == len(self.creatures)):
                keep = False

        """
        [x]Agregar un metodo que regrese el valor de "taken"
        [x]Eliminar item de lista de items cuando este "taken"
        Aplicar los nuevos specs a la creatura
        """
        i = 0
        while i < len(self.items):
            if(self.items[i].isTaken() ):
                self.items.remove(self.items[i])
            else:
                i = i + 1
        self.creatures = alive

    def debug(self):
        creatures = ""
        for i in self.creatures:
            creatures =  creatures + f' {i}'
        print(creatures)

    def __str__(self):

        creatures = ""
        for i in self.creatures:
            creatures =  creatures + f' {i}'

        elf_horde_str = ""
        for i in self.elf_hordes:
            elf_horde_str =  elf_horde_str + f' {i}'

        orc_horde_str = ""
        for i in self.orc_hordes:
            orc_horde_str =  orc_horde_str + f' {i}'

        return f'Day:{self.day}\n\
        Creatures\n{creatures}\n\
        Elves\n{elf_horde_str}\n\
        Orcs\n{orc_horde_str}\n\
        Items\n{self.items}\n\
        Trolls\n{self.trolls}'

w = World(5,5,10)

"""
Tareas
- Crear una raza humana que no anda en hordas, solo anda por ahi
- La raza humana puede encontrarse amuletos y armas y utilizarlas para DUPLICAR sus stats
- Los humanos tienen todos un mismo comienzo de fuerza y magia del 50% del elfo mas debil
- Existen 1 dragon en el escenario, si alguien lo encuentra, y lo domina (aleatoriamente) se quedará
con el hacia donde vaya y hará un daño al otro de 1000. Si una horda se encuentra con un dragon, mataran al dragon
Si una creatura se encuentra con un dragon, si aleatoriamente (>0.5) la creatura gana, lo domina, de cualquier otra
manera, la creatura muere.

"""

for i in range(0,50):
    w.update()
    #w.debug()
    print(f'{w}')


def contains_pattern(string, pattern):
    if not string or not pattern:
        return False

    slen, plen = len(string), len(pattern)
    if plen > len(string):
        return False

    hashed_strings = set()
    for i in range(slen - plen + 1):
        hashed_strings.add(string[i:i+plen])

    return pattern in hashed_strings

# Tests
assert contains_pattern("abcabcabcd", "abcd")
assert not contains_pattern("abcabcabc", "abcd")


from ecto.note import Note
import numpy as np

# Schema:
# [pitch int] [velocity float] [duration int] [x int] [y int] [tick int]

def midi_to_txt(name):
	channels = {}
	with open('scores/%s.dat' % name) as f:
		for line in f:
			if 'On' in line:
				t, _, ch, n, v = line.split(' ')
				ch = int(ch[3:])
				t = int(t)
				n = int(n[2:])
				v = int(v[2:])
				if ch not in channels:
					channels[ch] = []
				channels[ch].append((t, n, v))
			if 'Off' in line:
				t, _, ch, n, _ = line.split(' ')
				ch = int(ch[3:])
				t = int(t)
				n = int(n[2:])
				v = 0
				if ch not in channels:
					channels[ch] = []
				channels[ch].append((t, n, v))

	with open('scores/%s.txt' % name, 'w') as f:
		for ch in channels:
			running_notes = {}
			i = sorted(channels.keys()).index(ch)
			x = (i % 5) - 5
			y = (i - (i % 5))/10
			for t, n, v in channels[ch]:
				if v > 0:
					running_notes[n] = t, v
				if v == 0:
					duration = t - running_notes[n][0]
					tick = running_notes[n][0]
					vel = running_notes[n][1] / 127.

					line = '%s %s %s %s %s %s' % (n, vel, duration, x, y, tick)

					f.write('%s\n' % line)

def load_score(name, start_tick=0):
	all_notes = []
	with open('scores/%s.txt' % name) as score_file:
		for line in score_file:
			pitch, velocity, duration, x, y, tick = line.rstrip().split(" ")
			pitch = int(pitch)
			velocity = float(velocity)
			duration = int(duration)
			x = int(x)
			y = int(y)
			tick = int(tick) + start_tick
			channel = x % 5
			all_notes.append(Note(channel, pitch, velocity, duration, x, y, tick))

	all_notes.sort(key=lambda n: (n.tick, n.x, n.y))

	curr_tup = (-37.2, -37.2, -37.2)
	curr_notes = []
	for note in all_notes:
		if (note.tick, note.x, note.y) == curr_tup:
			curr_notes.append(note)
		else:
			if len(curr_notes) == 1:
				pass
			elif len(curr_notes) > 1:
				num_notes = len(curr_notes)
				angle = 2. * np.pi / num_notes
				for i, n in enumerate(curr_notes):
					theta = angle*i + np.pi/2
					n.x += .08 * np.cos(theta)
					n.y += .08 * np.sin(theta)

			curr_notes = [note]
			curr_tup = (note.tick, note.x, note.y)

	return all_notes


"""
n * m크기의 이차원 영역의 각 위치에 정수 값이 하나씩 적혀있습니다.
이 영역 안에서 가능한 양수 직사각형 중 최대 크기를 구하려고 합니다.
양수 직사각형이란, 직사각형의 변들이 주어진 격자 판에 평행하면서, 직사각형 내에 있는 숫자들이 전부 양수인 직사각형을 의미합니다.
최대 크기의 양수 직사각형을 찾는 프로그램을 작성해보세요.

Input           Output
3 3
1 2 3
3 4 5             9
6 7 8

4 5
6 -2 4 -3 1
3 6 7 -4 1        6
6 1 8 15 -5
3 -5 1 16 3
"""
# My, 7%
import sys
input = sys.stdin.readline

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

# (row, col) ~ (row_e, col_e)까지의 면적을 구하는 함수
def get_area(row, col, row_e, col_e):
    area = 0
    for r in range(row, row_e + 1):
        for c in range(col, col_e + 1):
            # 범위를 벗어나면 종료
            if r >= n or c >= m:
                return
            # 해당 범위 내의 음수가 포함되어 있으면 종료
            if board[r][c] < 0:
                return -1
            area += 1
    return area

answer = -1
for i in range(n):
    for j in range(m):
        for k in range(n):
            for l in range(m):
                result = get_area(i, j, k, l)
                answer = max(answer, result)

print(answer)

Algorithm/CodeTree/simulation/격자 안에서 완전 탐색/HW2.py


from numpy import mean, median

if INIT:
    delay = 0
    delayEnd = 5
    INIT = False

    # override delay if set
    from os import listdir
    from os.path import isfile, join

    calDir = "../../InstrConfig/Calibration/InstrCal"
    fnames = listdir(calDir)
    la_fname = None
    for fn in fnames:
        if fn.startswith("LaserTempOffsets") and fn.endswith(".ini"):
            la_fname = join(calDir, fn)
            break

    if la_fname is not None:
        laDict = getInstrParams(la_fname)
        try:
            delayEnd = laDict["Data"]["la_StartDelayEnd"]
        except:
            delayEnd = 5

        #print "delayEnd=", delayEnd

delay += 1
if delay > delayEnd:
    delay -= 1
    d = DATA
    whichVirtual = d.laserUsed >> 2
    virtualLasersUsed = set(whichVirtual)

    meanFineLaserCurrentByVirtualLaser = {}
    RESULT = {}

    for v in virtualLasersUsed:
        meanFineLaserCurrentByVirtualLaser[v] = mean(d.fineLaserCurrent[whichVirtual == v])
        RESULT["fineLaserCurrent_%d_mean" % (v+1,)] = meanFineLaserCurrentByVirtualLaser[v]
    #print RESULT

ANALYSIS = {}


from flask import Blueprint, render_template, request, redirect, url_for, flash
from ..models.items import Items
from ..models.products import Products
from ..forms.product import ProductFrom
from ..forms.edit import EditForm
from .. forms.add import AddForm
from .. import db
product_bp=Blueprint('product',__name__)

@product_bp.route('/product', methods=['GET', 'POST'])
def product():
    form = ProductFrom(request.form)
    if request.method == 'POST' and form.validate():
        search = request.form['search']
        items= Items.query.all()
        if not any(item.name == search for item in items):
            flash('Nem található a keresett cikk az adatbázisban')
            return redirect(url_for('/product/find'))
        item= Items.query.filter_by(name=search)
        return redirect(url_for('/product/find'))
    return render_template('product/product.html' , item=item , search=search)

@product_bp.route('/product/find')
def product_find(items):
    return render_template('product/product.html' , items=items)

@product_bp.route('/product/add')
def product_add():
    items= Items.query.all()
    return render_template('product/product.html' , items=items)

@product_bp.route('/product/edit/<id>', methods=['GET', 'POST'])
def product_edit(id):
    form = (request.form)
    items= Items.query.all()
    return render_template('product/edit.html' , items=items)

@product_bp.route('/product/delete/<id>', methods=['GET', 'POST'])
def product_delete(id):
    item = Items.query.filter(Items.id == id).first()
    if not item:
        flash('Nem található ezzel az ID-vel cikk.')
        return redirect(url_for('/product'))
    item.remove()
    db.session.commit()
    return render_template('product/delete.html')


from datetime import datetime, timedelta
from django.contrib.auth.models import User
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.urls import reverse
from django.utils import timezone
from django.db.models.signals import post_save
from django.dispatch import receiver

class Teams(models.Model):
    class Meta:
        verbose_name = 'команда'
        verbose_name_plural = "команды"

    rangeteam = range(100, 236)
    TEAM = [(i, i) for i in rangeteam]

    team = models.PositiveIntegerField(verbose_name='команда', choices=TEAM, default=1, null=True)

    def __str__(self):
        return str(self.team)

    def get_absolute_url(self):
        return reverse('oneteamstat', kwargs={'comanda': self.team})

class Profile(models.Model):
    class Meta:
        verbose_name = 'участник'
        verbose_name_plural = "участники"

    GENDER = [
        ('м', "м"), ("ж", "ж")
    ]
    CATEGORY = [
        (1, 'Новичок - 50 км'), (2, 'Легкий - 100 км'), (3, 'Средний - 200 км'), (4, 'Тяжелый - 400 км'),
        (5, 'Ультра - 900 км')
    ]

    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='Номер участника', db_index=True)
    runner_team = models.ForeignKey(Teams, on_delete=models.DO_NOTHING, verbose_name='команда')
    runner_age = models.IntegerField(verbose_name='возраст', null=False,default= 18, validators=[
        MaxValueValidator(80), MinValueValidator(18)
    ])
    runner_category = models.PositiveIntegerField(verbose_name='группа', choices=CATEGORY, default=1, db_index=True)
    runner_gender = models.CharField(max_length=1, choices=GENDER, verbose_name='пол участника', default='м')
    is_zabeg_2023 = models.BooleanField(verbose_name='Участник МыZaБег 2023', default=False)
    category_updated = models.PositiveIntegerField(verbose_name='Начальная группа', choices=CATEGORY,
                                                   default=0)
    completed = models.BooleanField(default=False, verbose_name="Выполнена квал-я")

    def __str__(self):
        return str(self.user)

# @receiver(post_save, sender=User)
# def create_user_profile(sender, instance, created, **kwargs):
#     if created:
#         Profile.objects.create(user=instance)
#
#
# @receiver(post_save, sender=User)
# def save_user_profile(sender, instance, **kwargs):
#     instance.profile.save()

class Status(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    online = models.DateTimeField('Был в онлайне', null=True, blank=True)

    def __str__(self):
        return str(self.user)

    def get_online_status(self):
        status = ''
        timezone_delta = timedelta(hours=3, minutes=0)
        online_status_true = timedelta(minutes=5)
        user_online = self.online + timezone_delta

        if self.user.profile.gender == 'F':
            if user_online.date() == (datetime.now() - timedelta(days=1)).date():
                status = 'Была онлайн вчера в ' + user_online.time().strftime("%H:%M")
            elif timezone.now() - self.online < online_status_true:
                status = 'Онлайн'
            elif user_online.date() == datetime.now().date():
                status = 'Была онлайн сегодня в ' + user_online.time().strftime("%H:%M")
            elif user_online.date().year == datetime.now().date().year:
                status = 'Была онлайн ' + user_online.date().strftime("%d.%m") + ' в ' + user_online.time().strftime(
                    "%H:%M")
            else:
                status = 'Была онлайн ' + user_online.date().strftime("%d.%m.%Y") + ' в ' + user_online.time().strftime(
                    "%H:%M")
        else:
            if user_online.date() == (datetime.now() - timedelta(days=1)).date():
                status = 'Был онлайн вчера в ' + user_online.time().strftime("%H:%M")
            elif timezone.now() - self.online < online_status_true:
                status = 'Онлайн'
            elif user_online.date() == datetime.now().date():
                status = 'Был онлайн сегодня в ' + user_online.time().strftime("%H:%M")
            elif user_online.date().year == datetime.now().date().year:
                status = 'Был онлайн ' + user_online.date().strftime("%d.%m") + ' в ' + user_online.time().strftime(
                    "%H:%M")
            else:
                status = 'Был онлайн ' + user_online.date().strftime("%d.%m.%Y") + ' в ' + user_online.time().strftime(
                    "%H:%M")
        return status

    class Meta:
        verbose_name = 'Статус'
        verbose_name_plural = 'Статусы'

class Follower(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    follower_for = models.ForeignKey(User, related_name='follower_for', on_delete=models.CASCADE)

    def __str__(self):
        return str(self.user)

    class Meta:
        verbose_name = 'Подписчик'
        verbose_name_plural = 'Подписчики'


from copy import copy

from hdlConvertorAst.hdlAst._statements import HdlStmAssign
from hwt.hdl.assignment import Assignment
from hwt.hdl.block import HdlStatementBlock
from hwt.hdl.ifContainter import IfContainer
from hwt.hdl.switchContainer import SwitchContainer
from hwt.hdl.typeShortcuts import hBit
from hwt.hdl.types.bits import Bits
from hwt.hdl.types.defs import BOOL
from hwt.hdl.types.sliceVal import SliceVal
from hwt.hdl.value import Value
from hwt.hdl.variables import SignalItem
from hwt.serializer.exceptions import SerializerException

class ToHdlAstVhdl2008_statements():

    def as_hdl_Assignment(self, a: Assignment):
        _dst = dst = a.dst
        assert isinstance(dst, SignalItem)

        if a.indexes is not None:
            for i in reversed(a.indexes):
                if isinstance(i, SliceVal):
                    i = i.__copy__()
                dst = dst[i]

        src_t = a.src._dtype
        dst_t = dst._dtype
        correct = False
        src = a.src
        if dst_t == src_t:
            correct = True
        else:
            src = a.src
            if (isinstance(dst_t, Bits) and isinstance(src_t, Bits)):
                # std_logic <->  std_logic_vector(0 downto 0) auto conversions
                if dst_t.bit_length() == src_t.bit_length() == 1:
                    if dst_t.force_vector and not src_t.force_vector:
                        dst = dst[0]
                        correct = True
                    elif not dst_t.force_vector and src_t.force_vector:
                        src = src[0]
                        correct = True
                    elif src_t == BOOL:
                        src = src._ternary(hBit(1), hBit(0))
                        correct = True
                elif not src_t.strict_width:
                    if isinstance(src, Value):
                        src = copy(src)
                        if a.indexes:
                            raise NotImplementedError()

                        src._dtype = dst_t
                        correct = True
                    else:
                        raise NotImplementedError()
                        pass

        if correct:
            src = self.as_hdl(src)
            hdl_a = HdlStmAssign(src, self.as_hdl(dst))
            hdl_a.is_blocking = _dst.virtual_only
            return hdl_a

        raise SerializerException(
            "%s = %s  is not valid assignment\n"
            " because types are different (%r; %r) " %
            (dst, a.src, dst._dtype, a.src._dtype))

    def can_pop_process_wrap(self, stms, hasToBeVhdlProcess):
        if hasToBeVhdlProcess:
            return False
        else:
            assert len(stms) == 1
            return True

    def has_to_be_process(self, proc: HdlStatementBlock):
        for x in proc.statements:
            if isinstance(x, (IfContainer, SwitchContainer)):
                return True
        return False


import numpy as np
import pandas as pd

class Helper:
    def __init__(self, df_in):
        self.df = df_in
        self.n = len(df_in.index)

    def null_count(self):
        df = self.df
        return df.isnull().sum().sum()

    def train_test_split(self, frac):
        df = self.df
        n = self.n
        train_n = round(n * frac)
        train_df = df.iloc[:train_n, :]
        test_df = df.iloc[train_n:, :]
        return train_df, test_df

# Test helper functions perform intended function:
df = pd.read_csv('/Users/chriscollins/Documents/Datasets/Kaggle Advertising/train.csv')

df_helper = Helper(df)
print(df_helper.null_count())
print(df.isnull().sum().sum())
train, test = df_helper.train_test_split(.3)

print(train.shape, test.shape)


#coding:utf-8

"""
ID:          issue-4259
ISSUE:       4259
TITLE:       Bugcheck 291 (cannot find record back version) if GTT is modified concurrently
  using at least one read-committed read-only transaction
DESCRIPTION:
JIRA:        CORE-3924
FBTEST:      bugs.core_3924
"""

import pytest
from firebird.qa import *

db = db_factory()

test_script = """
    recreate global temporary table gt(f01 int) on commit preserve rows;
    commit;
    insert into gt values(1);
    commit;
    set transaction read only read committed record_version;
    delete from gt;
    set term ^;
    execute block as
    begin
        in autonomous transaction
        do update gt set f01=-1;
    end
    ^
    set term ;^
    commit;
"""

act = isql_act('db', test_script,
                 substitutions=[('-concurrent.*', ''),
                                ('-At block line: [\\d]+, col: [\\d]+', '-At block line')])

expected_stderr = """
    Statement failed, SQLSTATE = 40001
    deadlock
    -update conflicts with concurrent update
    -At block line: 1, col: 53
"""

@pytest.mark.version('>=3')
def test_1(act: Action):
    act.expected_stderr = expected_stderr
    act.execute()
    assert act.clean_stderr == act.clean_expected_stderr


my_str="Hello"
a=my_str[0]
print(a) #H

# len(str) - returns the number of charaters
# my_str[index] - get character ar index
# my_str[1:1] - a substring of my_str from 1 to 1
# Operators
# str + str : combine two strings( concatenate,combine)
# Str * int : repeat str * int numver of times
# Str1 in str2 : return True if str 1 is in str2

fruit="Banana"
b=fruit[0] #B

"T" + fruit[1:] #Tanana

#How many ls in my_str?
count=0
for ch in my_str:
    if ch =="l":
        count += 1
print(count)

i=0
while i < len(my_str):
    if my_str[i] =="l":
        count +=1
    i += 1

# use google documents to see all functions

print("BANANA".lower())
print("banana".upper())
print("banana".capitalize)

print("banana1".isalnum())
print("123".isdigit())

"asdasf".capitalize()

# those are just convertin way, let's see more useful way

# join split strip
print("abs ".strip()+"def") #abcdef - remove white space(blank and empty line

# str.split(sep) : splits a str into a list using sep char
message = "Vancouver is always raining."
l=message.split(" ")
print(l)            #['Vancouver', 'is', 'always', 'raining.']

# join : joins a list into a string with str

print("*".join(l))  #Vancouver*is*always*raining.

# startswith()
st = "Kiwi"
if st.startswith("Ki"):
    print("is it Kiwi?")

print("find():", st.find("i"))  #find(): 1
print("find():", st.find("i",2))  #find(): 3

# 4. count
print("Banana".count("n"))  #2

# Formatting a str
std_info1="Firstname: Derrick, Lastname:Park, City : Vancouver"
std_info2="Firstname: Alex, Lastname:Han, City : Vancouver"

std_info="Firstname: {}, Lastname:{}, City : {}".format("derrick","Part","Vancouver")
print(std_info) #Firstname: derrick, Lastname:Part, City : Vancouver

def pretty_message(first,last,city):
    std_info = "Firstname: {}, Lastname:{}, City : {}".format(first,last,city)
    print(std_info)

pretty_message("JT","han","Van")    #Firstname: JT, Lastname:han, City : Van

grade="Stdent_id:{}, final_grada : {}".format(123,100)
print(grade)        #Stdent_id:123, final_grada : 100

grade2="Stdent_name:%s, final_grada : %d" %("alex",90)
print(grade2)   #Stdent_name:alex, final_grada : 90

#compare
"Apple"<"Banana" # True

'''
mkdir
cat - show the contents

android-4a0d14c8d3943640:HAN ALEX_HAN$ cp myfile.py myfile2.py
android-4a0d14c8d3943640:HAN ALEX_HAN$ ls
myfile.py       myfile2.py
android-4a0d14c8d3943640:HAN ALEX_HAN$ mkdir python_files
android-4a0d14c8d3943640:HAN ALEX_HAN$ ls
myfile.py       myfile2.py      python_files
android-4a0d14c8d3943640:HAN ALEX_HAN$ mv myfile1.py python_files/
mv: rename myfile1.py to python_files/myfile1.py: No such file or directory
android-4a0d14c8d3943640:HAN ALEX_HAN$ mv myfile1.py python_files/
mv: rename myfile1.py to python_files/myfile1.py: No such file or directory
android-4a0d14c8d3943640:HAN ALEX_HAN$ ls
myfile.py       myfile2.py      python_files
android-4a0d14c8d3943640:HAN ALEX_HAN$ mv *.py python_files/
android-4a0d14c8d3943640:HAN ALEX_HAN$ ls
python_files
android-4a0d14c8d3943640:HAN ALEX_HAN$

android-4a0d14c8d3943640:HAN ALEX_HAN$ cd python_files
android-4a0d14c8d3943640:python_files ALEX_HAN$ ls
myfile.py       myfile2.py
android-4a0d14c8d3943640:python_files ALEX_HAN$ rm myfile.py
android-4a0d14c8d3943640:python_files ALEX_HAN$ ls
myfile2.py
android-4a0d14c8d3943640:python_files ALEX_HAN$

android-4a0d14c8d3943640:HAN ALEX_HAN$ ls
python_files
android-4a0d14c8d3943640:HAN ALEX_HAN$ rm -r python_files/
android-4a0d14c8d3943640:HAN ALEX_HAN$ ls
HAN
android-4a0d14c8d3943640:Desktop ALEX_HAN$ ls -l
total 0
drwxr-xr-x  3 ALEX_HAN  staff  102  8 Jan 11:47 HAN

android-4a0d14c8d3943640:Desktop ALEX_HAN$ whoami
ALEX_HAN

android-4a0d14c8d3943640:Desktop ALEX_HAN$ man ls

LS(1)                     BSD General Commands Manual                    LS(1)

NAME
     ls -- list directory contents

SYNOPSIS
     ls [-ABCFGHLOPRSTUW@abcdefghiklmnopqrstuwx1] [file ...]

DESCRIPTION
     For each operand that names a file of a type other than directory, ls
     displays its name as well as any requested, associated information.  For
     each operand that names a file of type directory, ls displays the names
     of files contained within that directory, as well as any requested, asso-
     ciated information.

     If no operands are given, the contents of the current directory are dis-
     played.  If more than one operand is given, non-directory operands are
     displayed first; directory and non-directory operands are sorted sepa-
     rately and in lexicographical order.

     The following options are available:

/long -> find function

android-4a0d14c8d3943640:HAN ALEX_HAN$ vim touch text_file.txt
2 files to edit

1. this is a popular linux text, code editor called vim
2.
3. there are many text editors that come with Unix -like operating system.

~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
-- INSERT --
android-4a0d14c8d3943640:HAN ALEX_HAN$

android-4a0d14c8d3943640:/ ALEX_HAN$ ls -l
total 45
drwxrwxr-x+ 46 root  admin  1564  8 Jan 08:52 Applications
drwxr-xr-x+ 61 root  wheel  2074  2 Oct 13:25 Library
drwxr-xr-x@  2 root  wheel    68 25 Feb  2016 Network
drwxr-xr-x@  4 root  wheel   136  4 Jan 12:41 System
drwxr-xr-x   9 root  admin   306  8 Jan 08:41 Users
drwxrwxrwt@  3 root  admin   102  8 Jan 11:24 Volumes
drwxr-xr-x@ 39 root  wheel  1326  4 Jan 12:41 bin
drwxrwxr-t@  2 root  admin    68 25 Feb  2016 cores
dr-xr-xr-x   3 root  wheel  4119  8 Jan 08:34 dev
lrwxr-xr-x@  1 root  wheel    11 25 Aug 17:15 etc -> private/etc
dr-xr-xr-x   2 root  wheel     1  8 Jan 08:35 home
-rw-r--r--@  1 root  wheel   313  2 Aug  2015 installer.failurerequests
dr-xr-xr-x   2 root  wheel     1  8 Jan 08:35 net
drwxr-xr-x@  6 root  wheel   204 25 Aug 17:17 private
drwxr-xr-x@ 59 root  wheel  2006  4 Jan 12:41 sbin
lrwxr-xr-x@  1 root  wheel    11 25 Aug 17:15 tmp -> private/tmp
drwxr-xr-x@ 13 root  wheel   442  2 Oct 13:26 usr
lrwxr-xr-x@  1 root  wheel    11 25 Aug 17:16 var -> private/var

android-4a0d14c8d3943640:/ ALEX_HAN$ ls -la             #hidden files
total 173
drwxr-xr-x  30 root  wheel   1088  4 Jan 12:39 .
drwxr-xr-x  30 root  wheel   1088  4 Jan 12:39 ..
-rw-rw-r--   1 root  admin      0 25 Feb  2016 .DS_Store
d--x--x--x   9 root  wheel    306  8 Jan 08:35 .DocumentRevisions-V100
drwx------   5 root  wheel    170 25 Aug 17:25 .Spotlight-V100
d-wx-wx-wt   2 root  wheel     68 25 Aug 16:31 .Trashes
----------   1 root  admin      0 25 Feb  2016 .file
drwx------  23 root  wheel    782  8 Jan 11:37 .fseventsd
-rw-------   1 root  wheel  65536 25 Aug 17:23 .hotfiles.btree
drwxr-xr-x@  2 root  wheel     68  1 Aug  2015 .vol
drwxrwxr-x+ 46 root  admin   1564  8 Jan 08:52 Applications
drwxr-xr-x+ 61 root  wheel   2074  2 Oct 13:25 Library
drwxr-xr-x@  2 root  wheel     68 25 Feb  2016 Network
drwxr-xr-x@  4 root  wheel    136  4 Jan 12:41 System
drwxr-xr-x   9 root  admin    306  8 Jan 08:41 Users
drwxrwxrwt@  3 root  admin    102  8 Jan 11:24 Volumes
drwxr-xr-x@ 39 root  wheel   1326  4 Jan 12:41 bin
drwxrwxr-t@  2 root  admin     68 25 Feb  2016 cores
dr-xr-xr-x   3 root  wheel   4119  8 Jan 08:34 dev
lrwxr-xr-x@  1 root  wheel     11 25 Aug 17:15 etc -> private/etc
dr-xr-xr-x   2 root  wheel      1  8 Jan 08:35 home
-rw-r--r--@  1 root  wheel    313  2 Aug  2015 installer.failurerequests
dr-xr-xr-x   2 root  wheel      1  8 Jan 08:35 net
drwxr-xr-x@  6 root  wheel    204 25 Aug 17:17 private
drwxr-xr-x@ 59 root  wheel   2006  4 Jan 12:41 sbin
lrwxr-xr-x@  1 root  wheel     11 25 Aug 17:15 tmp -> private/tmp
drwxr-xr-x@ 13 root  wheel    442  2 Oct 13:26 usr
lrwxr-xr-x@  1 root  wheel     11 25 Aug 17:16 var -> private/var
android-4a0d14c8d3943640:/ ALEX_HAN$

android-4a0d14c8d3943640:/ ALEX_HAN$ echo hello
hello

'''


import bpy
from vtools_golfRoyaleTools import gameField

def cb_updateSplineAreaDetail(self,value):

    cAreaLinesId = bpy.data.collections.find("AREA_LINES")
    if cAreaLinesId != -1:
        oc = bpy.data.collections[cAreaLinesId].objects
        for obj in oc:
            obj.data.resolution_u = bpy.context.scene.ct_splineAreaDetail

def duplicateObject(pObj):

    obj = pObj.copy()
    bpy.context.scene.collection.objects.link(obj)
    obj.data = obj.data.copy()

    return obj

class VTOOLS_OP_ApplyFieldModifiers(bpy.types.Operator):
    bl_idname = "camperotools.applyfieldmodifiers"
    bl_label = "Apply field modifiers"
    bl_description = "Apply field modifiers"
    bl_options = {'REGISTER', 'UNDO'}

    def createExportCollection(self):

        cID = bpy.data.collections.find("AREA_MESH")
        if cID == -1:
            gc = bpy.data.collections.new(name="AREA_MESH")
            bpy.context.scene.collection.children.link(gc)

        cID = bpy.data.collections.find("AREA_TOEXPORT")
        if cID == -1:
            gc = bpy.data.collections.new(name="AREA_TOEXPORT")
            bpy.context.scene.collection.children.link(gc)

    def duplicateAndApply(self):
        cAreaLinesId = bpy.data.collections.find("AREA_INGAME")
        if cAreaLinesId != -1:
            oc = bpy.data.collections[cAreaLinesId].objects
            for obj in oc:
                no = duplicateObject(obj)
                gameField.moveObjectToCollection(no,"AREA_MESH")

                no.select_set(state = True)
                bpy.context.view_layer.objects.active = no

                for m in no.modifiers:
                    if m.name != "wrap":

                        try:
                            bpy.ops.object.modifier_apply(apply_as='DATA',modifier=m.name)
                        except:
                            no.modifiers.remove(m)
                            #obj_name = getattr(obj, "name", "NO NAME")
                            #collect_names.append(obj_name)
                            #message_b = True
                            pass

                no.select_set(state = False)

    def joinAreaMesh(self):

        bpy.ops.object.select_all(action='DESELECT')

        cId = bpy.data.collections.find("AREA_MESH")
        if cId != -1:
            oc = bpy.data.collections[cId].objects
            for obj in oc:
                obj.select_set(state=True)
                bpy.context.view_layer.objects.active = obj

        bpy.ops.object.join()
        bpy.context.scene.ct_fieldToExport = bpy.data.objects[bpy.context.object.name]

    def execute(self, context):

        gameField.collectionHide_set("AREA_MESH", False)

        self.createExportCollection()
        self.duplicateAndApply()
        self.joinAreaMesh()

        gameField.collectionHide_set("AREA_INGAME", True)

        return {'FINISHED'}

class VTOOLS_OP_AddEditNormal(bpy.types.Operator):
    bl_idname = "camperotools.addeditnormal"
    bl_label = "Add Edit Normal Target"
    bl_description = "Add edit normal modifier"
    bl_options = {'REGISTER', 'UNDO'}

    def createVertexGroup(self, pObj, pName):

        if pObj.vertex_groups.find(pName) == -1:
            pObj.vertex_groups.new(name=pName)

    def addEditModifier(self):

        vgname = "border"
        cAreaLinesId = bpy.data.collections.find("AREA_MESH")
        if cAreaLinesId != -1:
            oc = bpy.data.collections[cAreaLinesId].objects
            for obj in oc:
                obj.data.use_auto_smooth = True
                self.createVertexGroup(obj,vgname)
                mod = obj.modifiers.new(name="normalEdit", type="NORMAL_EDIT")
                mod.target = bpy.context.scene.ct_fieldNormalTarget
                mod.mode = "DIRECTIONAL"
                mod.vertex_group = vgname

    def execute(self, context):

        self.addEditModifier()
        return {'FINISHED'}

def register():

    bpy.utils.register_class(VTOOLS_OP_ApplyFieldModifiers)
    bpy.utils.register_class(VTOOLS_OP_AddEditNormal)

    bpy.types.Scene.ct_splineAreaDetail = bpy.props.IntProperty(default = 8, min = 1, max = 64, update=cb_updateSplineAreaDetail)

    return {'FINISHED'}

def unregister():

    bpy.utils.unregister_class(VTOOLS_OP_ApplyFieldModifiers)
    bpy.utils.unregister_class(VTOOLS_OP_AddEditNormal)

    del bpy.types.Scene.ct_splineAreaDetail

    return {'FINISHED'}


# -*- coding: utf-8 -*-
"""
Created on Sat Jun 15 21:58:49 2019
Author: Francisco Javier Carrera Arias
LSTM_Model Data Preprocessing and Training Loop
"""
# Imports
import torch
import pickle
import numpy as np
import pandas as pd
from collections import Counter
from sklearn.model_selection import train_test_split
from torch.utils.data import TensorDataset, DataLoader
import torch.nn as nn
# LSTM Model import
from LSTM_Model import LSTM_Model
from utils import pad_features, prune_review_text, train_LSTM_Net, test_Best_LSTM_Model

# Read Reviews
review_data = pd.read_csv("imdb_data.csv", encoding = "latin1")
reviews = list(review_data["review"].values)
labels = list(review_data["label"].values)

# Clean the review text
clean_reviews = prune_review_text(reviews)

# Gather all the words to build a vocabulary
all_words = [word for review in clean_reviews for word in review]

wordCounts = Counter(all_words)
sortCounts = sorted(wordCounts, key=wordCounts.get, reverse=True)

## Build a dictionary that maps words to integers
int_2_vocab = {k + 1:word for k, word in enumerate(sortCounts)}
vocab_2_int = {word: k for k, word in int_2_vocab.items()}

###################################################
# Save Vocabulary for later use
with open('vocabulary_to_int.pkl', 'wb') as f:
        pickle.dump(vocab_2_int, f)
###################################################

## use the vocab_2_int dict to tokenize each review in reviews_split
## store the tokenized reviews in reviews_ints
reviews_ints = []
for k in range(len(clean_reviews)):
    reviews_ints.append([vocab_2_int[j] for j in clean_reviews[k]])

# Encode the labels
encoded_labels = np.array([1 if label == 'pos' else 0 for label in labels])
print(labels[:10])
print(encoded_labels[:10])

# Truncate and and pad very long reviews
seq_length = 200
review_features = pad_features(reviews_ints, seq_length=seq_length)

## test statements##
assert len(review_features)==len(reviews_ints), "Your features should have as many rows as reviews."
assert len(review_features[0])==seq_length, "Each feature row should contain seq_length values."

# print first 10 values of the first 50 batches
print(review_features[:50,:10])

# Split into training, validation and test sets
split_frac = 0.8
test_x, train_x, test_y, train_y = train_test_split(review_features, encoded_labels, test_size=split_frac, random_state=42)
test_x, val_x, test_y, val_y = train_test_split(test_x,test_y,test_size = 0.5,random_state = 42)
## print out the shapes of your resultant feature data
print(train_x.shape)
print(test_x.shape)
print(val_x.shape)

# Make DataLoaders
# create Tensor datasets
train_data = TensorDataset(torch.from_numpy(train_x), torch.from_numpy(train_y))
valid_data = TensorDataset(torch.from_numpy(val_x), torch.from_numpy(val_y))
test_data = TensorDataset(torch.from_numpy(test_x), torch.from_numpy(test_y))

batch_size = 50
train_loader = DataLoader(train_data, shuffle=True, batch_size=batch_size)
valid_loader = DataLoader(valid_data, shuffle=True, batch_size=batch_size)
test_loader = DataLoader(test_data, shuffle=True, batch_size=batch_size)

# Visualize a batch of training data
dataiter = iter(train_loader)
sample_x, sample_y = dataiter.next()

print('Sample input size: ', sample_x.size()) # batch_size, seq_length
print('Sample input: \n', sample_x)
print()
print('Sample label size: ', sample_y.size()) # batch_size
print('Sample label: \n', sample_y)

# GPU flag
train_on_gpu=torch.cuda.is_available()
if(train_on_gpu):
    print('Training on GPU.')
else:
    print('No GPU available, training on CPU.')

# Instantiate the neural network with hyperparameters
vocab_size = len(vocab_2_int)+1
output_size = 1
embedding_dim = 250
hidden_dim = 512
n_layers = 2

LSTM = LSTM_Model(vocab_size, output_size, embedding_dim, hidden_dim, n_layers)
print(LSTM)

# Optimizer and Loss functions
lr=0.001
criterion = nn.BCELoss()
optimizer = torch.optim.Adam(LSTM.parameters(), lr=lr)
epochs = 3
# Training Loop
train_LSTM_Net(LSTM, train_loader, valid_loader, batch_size, criterion, optimizer, epochs, train_on_gpu)

########################################################################################
# Test trained models

test_losses, num_correct = test_Best_LSTM_Model("Sentiment_Best_Model.pt", test_loader, criterion, train_on_gpu, vocab_size,
                                                output_size, embedding_dim, hidden_dim, n_layers, batch_size)

# Print test loss
print("Test loss: {:.3f}".format(np.mean(test_losses)))
# accuracy over all test data
test_acc = num_correct/len(test_loader.dataset)
print("Test accuracy: {:.3f}".format(test_acc))

Movie Sentiment RNN with Shiny App Deployment/Sentence_Cleaning_and_Training.py


import re

from storages.backends.dropbox import DropBoxStorage
from django.contrib.auth.models import User

from files_storage.models import File, FileExtension
class DropboxServices:
    reg_ex_extension = r'\.[^./\\]+$'
    storage = DropBoxStorage()

    @classmethod
    def upload_file(cls, request, file):
        old_name = file.name
        new_name = cls.storage.save(old_name, file)

        cls.save_fileinfo_db(request, file, old_name, new_name)

        return old_name, new_name

    @classmethod
    def get_file_info(cls, file):
        pass

    @classmethod
    def save_fileinfo_db(cls, request, file, old_name, new_name):
        owner: User = User.objects.get(id=request.user.id)

        try:
            extension = re.findall(cls.reg_ex_extension, file.name)[0]
            extension_inst: FileExtension = FileExtension.objects.get(name=extension)
        except FileExtension.DoesNotExist:
            extension_inst: FileExtension = FileExtension.objects.get(id=1)

        type_inst = extension_inst.type

        File.objects.create(
            owner=owner,
            file_type=type_inst,
            file_extension=extension_inst,
            file_name=old_name,
            dropbox_file_name=new_name
        )


from setuptools import setup, find_packages

with open("README.md", "r") as readme:
   user_manual = readme.read()

setup(
   name="covid19_dashboard_lbiragnet",
   version="0.0.2",
   author="Luc Biragnet",
   author_email="lucbiragnet@gmail.com",
   description="Covid-19 dashboard with access to live data and news articles",
   long_description=user_manual,
   long_description_content_type="text/markdown",
   url="https://github.com/lbiragnet/covid_dashboard_lbiragnet",
   py_modules=["main", "covid_data_handler", "covid_news_handling", "time_calculations"],
   packages=find_packages("src"),
   packages_dir={"":"src"},
   package_data={"src":["config/*.json", "datafiles/*.json", "*.csv"]},
   include_package_data=True,
   license="MIT",
   classifiers=[
      "Programming Language :: Python :: 3",
      "License :: OSI Approved :: MIT License",
      "Operating System :: OS Independent",
   ],
   python_requires=">=3.8",
)