import os
import torch
import adam_upd_cuda  # requires pre-build adam
## online installation as follows
# from torch.utils.cpp_extension import load

# parent_dir = os.path.dirname(os.path.abspath(__file__))
# sources = ['cuda/adam_upd.cpp', 'cuda/adam_upd_kernel.cu']
# print("Loading masked adam.")
# adam_upd_cuda = load(
#         name='adam_upd_cuda',
#         sources=[os.path.join(parent_dir, path) for path in sources],
#         verbose=False)
# print("CUDA support for masked adam loaded.")

''' Extend Adam optimizer
1. support per-voxel learning rate
2. masked update (ignore zero grad) which speeduping training
'''
class MaskedAdam(torch.optim.Optimizer):

    def __init__(self, params, lr=1e-3, betas=(0.9, 0.99), eps=1e-8):
        if not 0.0 <= lr:
            raise ValueError("Invalid learning rate: {}".format(lr))
        if not 0.0 <= eps:
            raise ValueError("Invalid epsilon value: {}".format(eps))
        if not 0.0 <= betas[0] < 1.0:
            raise ValueError("Invalid beta parameter at index 0: {}".format(betas[0]))
        if not 0.0 <= betas[1] < 1.0:
            raise ValueError("Invalid beta parameter at index 1: {}".format(betas[1]))
        defaults = dict(lr=lr, betas=betas, eps=eps)
        self.per_lr = None
        super(MaskedAdam, self).__init__(params, defaults)

    def __setstate__(self, state):
        super(MaskedAdam, self).__setstate__(state)

    def set_pervoxel_lr(self, count):
        assert self.param_groups[0]['params'][0].shape == count.shape
        self.per_lr = count.float() / count.max()

    @torch.no_grad()
    def step(self):
        for group in self.param_groups:
            lr = group['lr']
            beta1, beta2 = group['betas']
            eps = group['eps']
            skip_zero_grad = group['skip_zero_grad']

            for param in group['params']:
                if param.grad is not None:
                    state = self.state[param]
                    # Lazy state initialization
                    if len(state) == 0:
                        state['step'] = 0
                        # Exponential moving average of gradient values
                        state['exp_avg'] = torch.zeros_like(param, memory_format=torch.preserve_format)
                        # Exponential moving average of squared gradient values
                        state['exp_avg_sq'] = torch.zeros_like(param, memory_format=torch.preserve_format)

                    state['step'] += 1

                    if self.per_lr is not None and param.shape == self.per_lr.shape:
                        adam_upd_cuda.adam_upd_with_perlr(
                                param, param.grad, state['exp_avg'], state['exp_avg_sq'], self.per_lr,
                                state['step'], beta1, beta2, lr, eps)
                    elif skip_zero_grad:
                        adam_upd_cuda.masked_adam_upd(
                                param, param.grad, state['exp_avg'], state['exp_avg_sq'],
                                state['step'], beta1, beta2, lr, eps)
                    else:
                        adam_upd_cuda.adam_upd(
                                param, param.grad, state['exp_avg'], state['exp_avg_sq'],
                                state['step'], beta1, beta2, lr, eps)

if __name__=='__main__':
    a = torch.nn.Linear(3, 4)
    optim = MaskedAdam(a.parameters())
    print("Testing masked adam optimizer finished!")


#! /usr/bin/env python
# -*- coding: UTF-8 -*-
#
# Mont Bego - (c) 1999-2008 LDLP (Laboratoire Départemental de Prehistoire du Lazaret)
# http://lazaret.unice.fr/opensource/ - opensource@lazaret.unice.fr
#
# You're welcome to redistribute this software under the
# terms of the GNU General Public Licence version 2
#
# You can read the complete GNU GPL in the file COPYING
# which should come along with this software, or visit
# the Free Software Foundation's WEB site http://www.fsf.org
#

import os
import string
import urllib
import begoconf
import begodata
import afficheclefs

class Zone(begodata.Data):
    # le nom de la table
    __tablename__ = "zone"
    __new_record__ = "Nouvelle"
    #
    # tous les champs de la table proprietaire
    __champs__ = {
                "secteur"     :{"type": "text",    "default": "", "mandatory": 0},
                "zone"        :{"type": "decimal", "default": 0,  "mandatory": 1},
                "groupes"     :{"type": "decimal", "default": 0,  "mandatory": 0},
                "remarquable" :{"type": "text",    "default": "", "mandatory": 0},
                }
    #
    # liste des seuls champs que l'on veut pouvoir modifier
    __listechamps__ = ("secteur", "zone", "groupes")
    #
    # liste des tables enfants
    __listenfants__ = ("roche", "face", "figure", "historique", "association")
    __listeclefs__ = ("zone",)
    #
    # liste des champs dans leur ordre de saisie
    __ordrechamps__ = ("secteur", "zone", "groupes", "remarquable")
    __orderby__ = " ORDER BY zone ASC;"
    __vraiparent__ = None
    #
    # liste des formulaires supplementaires
    __formsupp__ = ("zone_param",)

    def zone_verify(self, value):
        if value == '':
            return -1
        else:
            return 0

    def secteur_base_to_form(self, enreg, penreg=None):
        self.__doc__.push()
        self.__doc__.tr()
        self.__doc__.push()
        self.__doc__.td(align="right", valign="middle")
        self.__doc__.font(size=begoconf.font_size)
        self.__doc__.insert_text("Secteur")
        secteurs = ("Merveilles", "Fontanalba", "Vallaurette", "Valmasque", "Sainte Marie", "Vei del Bouc", "Sabion")
        listesecteurs = {}
        for s in secteurs:
            listesecteurs[s] = s
        afficheclefs.liste_deroulante(self.__doc__, "secteur", listesecteurs, enreg)
        self.__doc__.pop()

    def zone_base_to_form(self, enreg, penreg=None):
        afficheclefs.display_zone(self, enreg, penreg)
        self.__doc__.pop()

    def groupes_base_to_form(self, enreg, penreg=None):
        self.__doc__.push()
        self.__doc__.tr()
        self.__doc__.push()
        self.__doc__.td(align="left", valign="middle", border="2")
        self.__doc__.font(size=begoconf.font_size)
        self.__doc__.insert_text("Nombre de groupes : ")
        listegroupes = {}
        for i in range(0, 11):
            listegroupes[i] = i
        if penreg and penreg.has_key("groupes"):
            afficheclefs.liste_deroulante(self.__doc__, "groupes", listegroupes, penreg, dontchange=0)
        else:
            afficheclefs.liste_deroulante(self.__doc__, "groupes", listegroupes, enreg, dontchange=0)
        self.__doc__.pop()
        self.__doc__.pop()

    def remarquable_base_to_form(self, enreg, penreg=None):
        if enreg != None:
            z = self.__db__.quote(enreg["zone"], "decimal")
            query = "SELECT groupe,roche FROM roche WHERE zone = %s and remarquable = 't' ;" % (z)
            res = self.__db__.query(query).dictresult()
            self.__doc__.tr()
            self.__doc__.td(colspan=2)
            if len(res):
                champs = ("groupe", "roche")
                self.__doc__.push()
                self.__doc__.table(border=1, width="100%")
                self.__doc__.push()
                self.__doc__.tr()
                self.__doc__.caption("Liste des roches remarquables")
                self.__doc__.push()
                self.__doc__.tr()
                for c in champs:
                    self.__doc__.th(string.capitalize(c), align="center", valign="middle", bgcolor=begoconf.basform_bgcolorbottom)
                self.__doc__.pop()
                for roche in res:
                    self.__doc__.push()
                    self.__doc__.tr()
                    for c in champs:
                        val = roche[c]
                        self.__doc__.push()
                        self.__doc__.td(align="center", valign="middle")
                        if c == "roche" :
                            dico = {"action": "Chercher", "zone": enreg["zone"], "roche": val}
                            self.__doc__.a(val, href=begoconf.script_location("modroche") + '?' + urllib.urlencode(dico))
                        else :
                            self.__doc__.insert_text(val)
                        self.__doc__.pop()
                    self.__doc__.pop()
                self.__doc__.pop()
                self.__doc__.pop()
            else:
                self.__doc__.push()
                self.__doc__.table(border=0, width="100%")
                self.__doc__.tr()
                self.__doc__.td(align="center")
                self.__doc__.font(color="red", size=begoconf.font_size)
                self.__doc__.insert_text("Aucune roche remarquable")
                self.__doc__.pop()

################################################################################################################
#                                               LISTE ZONE_PARAM
################################################################################################################
    def liste_zone(self, enreg, param):
        # liste des param appartenant a la zone
        z = self.__db__.quote(enreg["zone"], "decimal")
        where = " WHERE zone = %s " % (z)
        query = "SELECT " + param + " FROM " + param + " WHERE id" + param + " IN ("
        qassoc = "SELECT id" + param + " FROM zone_" + param  + where
        query = query + qassoc + ");"                # on recupere la liste des param de la zone
        res = self.__db__.query(query).dictresult()
        if len(res):
            self.__doc__.push()
            self.__doc__.table(border=5, width="100%")
            self.__doc__.push()
            self.__doc__.tr()
            self.__doc__.th(string.capitalize(param), align="center", valign="middle", bgcolor=begoconf.basform_bgcolorbottom)
            self.__doc__.pop()
            for ligne in res:
                self.__doc__.push()
                self.__doc__.tr()
                val = ligne[param]
                if not val:
                    val = " "
                self.__doc__.td(val, align="center", valign="middle")
                self.__doc__.pop()
            self.__doc__.pop()
        else:
            self.__doc__.push()
            self.__doc__.p()
            self.__doc__.font(size=begoconf.font_size)
            if param in ("tourbiere", "moraine", "vegetation"):
                self.__doc__.font("Aucune "+ param +" dans la zone", color="red")
            else:
                self.__doc__.font("Aucun "+ param +" dans la zone", color="red")
            self.__doc__.pop()

    def zone_param(self, enreg, penreg=None):
        if enreg != None:
            liste = ("acces", "sentier", "sommet", "col", "lac", "torrent", "tourbiere", "eboulis", "moraine", "glacier", "vegetation")
            for i in liste:
                self.__doc__.push()
                self.__doc__.tr()
                self.__doc__.form(method="POST", action=begoconf.script_location("modzone_acces"))
                self.__doc__.push()
                self.__doc__.td(bgcolor=begoconf.basform_bgcolormiddle)
                self.__doc__.hidden(name="zone", value=enreg["zone"])
                self.__doc__.hidden(name="param", value=i)
                self.__doc__.font(size=begoconf.font_size)
                self.__doc__.div(align="center")
                self.liste_zone(enreg, i)
                self.__doc__.pop()
                self.__doc__.td(align="center", valign="middle", bgcolor=begoconf.basform_bgcolormiddle)
                self.__doc__.submit(name="action", value="Modifier")
                self.__doc__.pop()

############################################################################################################################
#                                               METHODES
############################################################################################################################

    def modifier(self) :
        """Met a jour la zone courante"""
        self.__db__.query(self.make_update_query(self.__listeclefs__))
        return 0

    def supprimer(self):
        # s'il existe des roches ou des photos pour cette zone on refuse la suppression
        if self.exist(self.__listeclefs__, table="roche") or self.exist(self.__listeclefs__, table="photozone") :
            return -1
        else:
            z = "Z" + self.__form__["zone"].value
            rz = begoconf.image_fullname(z)
            try :
                if os.path.isdir(rz):
                    os.rmdir(rz)
            except:
                begoconf.fatalerror_message("Impossible de supprimer le repertoire [%s]" % rz)
                # ces repertoires ne sont pas forcement vides, alors on essaie de les supprimer
                # mais si on ne réussit pas ce n'est pas grave
                try:
                    if os.path.isdir(rz):
                        os.rmdir(rz)
                except:
                    pass
                # on efface la roche
                self.delete_records(self.__listeclefs__)
                return 0

    def creer(self):
        # si la roche n'existe pas déjà alors on la crée, sinon on refuse
        if self.exist(self.__listeclefs__):
            primarykeys = {"zone" : None}
            return (-1, primarykeys)
        else:
            # on insère maintenant la roche dans la base
            z = self.__form__["zone"].value
            self.__db__.query(self.make_insert_query({ }))
            primarykeys = {"zone": z}
            return (0, primarykeys)


import os
from PIL import Image
import requests

def download_challenge7_image(img_path):
    if not os.path.exists(img_path):
        image_req = requests.get('http://www.pythonchallenge.com/pc/def/oxygen.png', stream=True)

        with open(img_path, 'wb') as img_file:
            for chunk in image_req.iter_content(chunk_size=1024):
                if chunk:  # ignore keep-alive chunks
                    img_file.write(chunk)

def main_func():
    #  Fetch the image file from the challenge page
    download_challenge7_image('../files/oxygen.png')

    img_path = '../files/oxygen.png'
    im = Image.open(open(img_path, 'rb'))
    pix = im.load()

    result = [chr(pix[i*7, 47][0]) for i in range(87)] # iterate over each gray bar area,

    print(''.join(result))  # result = smart guy, you made it. the next level is [105, 110, 116, 101, 103, 114, 105, 116, 121]

if __name__ == '__main__':
    main_func()


import sys
input = sys.stdin.readline

n = int(input())
lst = list(map(int, input().split()))
d = [0] * (n+1)

for i in range(1, n+1):
    d[i] = d[i-1] + min(lst)
    lst.remove(min(lst))
print(sum(d))


from birthday import BirthdayManager
from mail import MailManager

# Instances
bd_manager = BirthdayManager()
mail = MailManager()

# check if birthdays today and send wishes
bd_today = bd_manager.to_send()

if len(bd_today):
    mail.send_birtday_wishes(bd_today)


class Solution:
    def longestPalindrome(self, s: str) -> str:
        """
        result: TLE
        naive solution: checking every substring if its a palindrome
        runtime: O(n^3), space: O(1)
        """
#         def is_pal(l, r) -> bool:
#             #helper function that checks if a string is a palindrome
#             while l < r:
#                 if s[l] != s[r]:
#                     return False
#                 l += 1
#                 r -= 1
#             return True

#         Max = 0
#         start = 0
#         for i in range(len(s)):
#             for j in range(len(s)):
#                 if is_pal(i, j):
#                     if j - i + 1 > Max:
#                         start, Max = i, j - i + 1
#         return s[start:start+Max]

        """
        result: Accepted
        DP solution: construct 2D graph where dp[i][j] means s[i:j]
        to check if a string is a palindrome
        dp[i][j] = True if dp[i+1][j-1] and s[i] == s[j]
        In order to use this pattern, we need to construct the dictionary in a way that utilizes previous results
        runtime: O(n^2), space: O(len(s)^2)
        """

#         mem = [[False for _ in range(len(s))] for _ in range(len(s))]
#         start = 0
#         Max = 0
#         for i in range(len(s)-1, -1, -1):
#             for j in range(i, len(s)):
#                 mem[i][j] = s[i] == s[j] and (j - i <= 1 or mem[i+1][j-1]) #swaping and statement determines if the solution gets accepted or not
#                 if mem[i][j] and j-i+1 > Max:
#                     start = i
#                     Max = j-i+1
#         return s[start:start+Max]

        """
        result: Accepted
        improved naive solution:
        traverse the string, each index acts as a pivot (middle point) of a word
        we start at each index, and expand both ways to check if the string is still
        a palindrome or not
        runtime: O(n^2), space: O(1)
        """
        self.max, self.start = 1, 0
        def helper(l,r):
            while l >= 0 and r < len(s) and s[l] == s[r]:
                l -= 1
                r += 1
            if r - l - 1 > self.max:
                self.max = r - l - 1
                self.start = l + 1
        for i in range(len(s)-1):
            helper(i, i)
            helper(i, i+1)
        return s[self.start:self.start+self.max]


'''
Compare two version numbers version1 and version2.
If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0.

You may assume that the version strings are non-empty and contain only digits and the . character.
The . character does not represent a decimal point and is used to separate number sequences.
For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision.

Here is an example of version numbers ordering:

0.1 < 1.1 < 1.2 < 13.37
'''
class Solution(object):
    def compareVersion(self, version1, version2):
        """
        :type version1: str
        :type version2: str
        :rtype: int
        """
        res = 0
        version1 = version1.split(".")
        version2 = version2.split(".")
        while version1 and int(version1[-1]) == 0:
            del version1[-1]
        while version2 and int(version2[-1]) == 0:
            del version2[-1]
        itera = min(len(version1),len(version2))
        for i in xrange(itera):
            if int(version1[i]) > int(version2[i]):
                return 1
            elif int(version1[i]) < int(version2[i]):
                return -1
        if itera > 0 and i == itera-1:
            if len(version1) == len(version2):
                res = 0
            else:
                res = 1 if len(version1) > len(version2) else -1
        else:
            if len(version1) == len(version2):
                res = 0
            else:
                res = 1 if len(version1) > len(version2) else -1
        return res


import argparse
import os
import sys
import warnings

import mrcfile
import numpy as np
import numpy.fft as fft
import pandas as pd
from FilterUtil import rad_avg, rot_kernel
from constants.config import Config

def match_spectrum(tomo, target_spectrum, cutoff=None, smooth=0):
    """
    Adjust a tomogram's amplitude spectrum to match the extracted spectrum of another tomogram.
    Arguments:
        tomo: the input tomogram as a 3D numpy array.
        target_spectrum: the target spectrum as a 1D numpy array.
        cutoff: apply a cutoff at this frequency (default: no cutoff)
        smooth: smoothen the cutoff into a sigmoid. Value roughly resembles width of sigmoid.
    """

    # Normalize tomogram
    target_spectrum = target_spectrum.copy()
    tomo -= tomo.min()
    tomo /= tomo.max()

    # Do FFT
    t = fft.fftn(tomo)
    t = fft.fftshift(t)

    del tomo

    # Get input tomogram's radially averaged amplitude spectrum, get equalization vector
    input_spectrum = rad_avg(np.abs(t))
    target_spectrum.resize(len(input_spectrum))
    equal_v = target_spectrum / input_spectrum

    if cutoff:
        if smooth:
            slope = len(equal_v) / smooth
            offset = 2 * slope * ((cutoff - len(equal_v) / 2) / len(equal_v))

            cutoff_v = 1 / (1 + np.exp(np.linspace(-slope, slope, len(equal_v)) - offset))

        else:
            cutoff_v = np.ones_like(equal_v)
            try:
                equal_v[cutoff:] = 0
            except IndexError:
                warnings.warn("Flat cutoff is higher than maximum frequency")

        equal_v *= cutoff_v

    # Create and apply equalization kernel
    equal_kernel = rot_kernel(equal_v, t.shape)

    t *= equal_kernel
    del equal_kernel

    # Inverse FFT
    t = fft.ifftn(t)
    t = np.abs(t).astype("f4")

    return t

def main():
    parser = get_cli()
    args = parser.parse_args()
    pythonpath = args.pythonpath
    sys.path.append(pythonpath)
    # gpu = args.gpu
    # if gpu is None:
    #     print("No CUDA_VISIBLE_DEVICES passed...")
    #     if torch.cuda.is_available():
    #         os.environ["CUDA_VISIBLE_DEVICES"] = "0"
    # else:
    #     os.environ["CUDA_VISIBLE_DEVICES"] = gpu

    config_file = args.config_file
    config = Config(user_config_file=config_file)
    df = pd.read_csv(config.dataset_table, dtype={"tomo_name": str})
    df.set_index('tomo_name', inplace=True)
    tomo_name = args.tomo_name
    input_tomo = df[config.processing_tomo][tomo_name]
    target_tomo = os.path.join(config.work_dir, tomo_name)
    target_tomo = os.path.join(target_tomo, "match_spectrum_filtered.mrc")
    with mrcfile.open(input_tomo, permissive=True) as m:
        tomo = m.data.astype("f4")
        tomo_h = m.header

    target_spectrum = pd.read_csv(target_tomo, sep="\t")["intensity"].values

    filtered_tomo = match_spectrum(tomo, target_spectrum, config.cutoff, config.smoothen)

    m = mrcfile.new(args.output, overwrite=True)
    m.set_data(filtered_tomo)
    m.set_extended_header(tomo_h)
    m.close()

def get_cli():
    parser = argparse.ArgumentParser()
    parser.add_argument("-pythonpath", "--pythonpath", type=str)
    parser.add_argument("-tomo_name", "--tomo_name", type=str)
    parser.add_argument("-fold", "--fold", type=str, default="None")
    parser.add_argument("-config_file", "--config_file", help="yaml_file", type=str)
    return parser

if __name__ == "__main__":
    main()


"""Train OT-Flow on two-dimensional toy data using the JKO scheme.

OT-Flow is trained for a predetermined number of steps. After each step,
the target is updated to the pushforward of the learned density.
"""
import argparse
import copy
import logging
import math
import os
import pathlib
from pprint import pprint
import sys

from adabelief_pytorch import AdaBelief
import matplotlib.pyplot as plt
import numpy as np
import proplot as pplt
import torch

sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
import cnflows as cnf

import plotting
from utils import get_torch_device_mps
from utils import Monitor
from utils import ScriptManager

pplt.rc["grid"] = False
pplt.rc["cycle"] = "538"
pplt.rc["cmap.discrete"] = False
pplt.rc["cmap.sequential"] = "viridis"

# Parse command line arguments
# --------------------------------------------------------------------------------------
parser = argparse.ArgumentParser("ot-flow")

parser.add_argument("--save", type=int, default=1)
parser.add_argument("--outdir", type=str, default="./data_output/")
parser.add_argument("--data", type=str, default="2spirals")
parser.add_argument("--precision", type=str, default="single", choices=["single", "double"])
parser.add_argument("--gpu", type=int, default=0)

parser.add_argument("--m", type=int, default=16)
parser.add_argument("--n_layers", type=int, default=2)
parser.add_argument("--alpha_L", type=float, default=1.0)
parser.add_argument("--alpha_C", type=float, default=10.0)
parser.add_argument("--alpha_R", type=float, default=1.0)

parser.add_argument("--data_size", type=int, default=int(1.00e05))
parser.add_argument("--batch_size", type=int, default=2000)
parser.add_argument("--nt", type=int, default=8)
parser.add_argument("--seed", type=int, default=0)

parser.add_argument("--val_nt", type=int, default=8)

parser.add_argument("--n_steps", type=int, default=5)
parser.add_argument("--n_epochs", type=int, default=40)

parser.add_argument("--optim", type=str, default="adam", choices=["adam", "adabelief"])
parser.add_argument("--lr", type=float, default=1.00e-02)
parser.add_argument("--min_lr", type=float, default=1.00e-03)
parser.add_argument("--lr_drop", type=float, default=0.5)
parser.add_argument("--lr_patience", type=int, default=5)

parser.add_argument("--vis_freq", type=int, default=2)
parser.add_argument("--vis_n_points", type=int, default=int(10.00e+04))
parser.add_argument("--vis_n_bins", type=int, default=100)
parser.add_argument("--vis_cmap", type=str, default="viridis")

args = parser.parse_args()

# Settings
# --------------------------------------------------------------------------------------
device = get_torch_device_mps(gpu=args.gpu)

precision = torch.float32
if args.precision == "double":
    precision = torch.float64
torch.set_default_dtype(precision)

cvt = lambda x: x.type(precision).to(device, non_blocking=True)

man = ScriptManager(outdir=args.outdir, path=pathlib.Path(__file__))
man.save_script_copy()
pprint(man.get_info())

logger = man.get_logger(save=args.save, print=True, filename="log.txt")
for key, val in man.get_info().items():
    logger.info(f"{key}: {val}")
logger.info(args)

# Load training data.
# --------------------------------------------------------------------------------------

def get_data(size):
    data = cnf.utils.gen_toy_data(name=args.data, size=size)
    data = cvt(torch.from_numpy(data))
    return data

data = get_data(args.data_size)
dataset = torch.utils.data.TensorDataset(data)
data_loader = torch.utils.data.DataLoader(
    dataset=dataset, batch_size=args.batch_size, shuffle=False
)

val_data = get_data(args.data_size)
val_dataset = torch.utils.data.TensorDataset(val_data)
val_data_loader = torch.utils.data.DataLoader(
    dataset=val_dataset, batch_size=val_data.shape[0], shuffle=False
)

# Model
# --------------------------------------------------------------------------------------
d = 2
m = args.m
n_layers = args.n_layers
alpha = [args.alpha_L, args.alpha_C, args.alpha_R]

base_dist = cnf.distributions.DiagGaussian(d, trainable=False)
nfm = cnf.OTFlow(d=d, m=m, n_layers=n_layers, alpha=alpha, base_dist=base_dist)
nfm = nfm.to(precision).to(device)

logger.info("")
logger.info("Model")
logger.info("--------------------------------------------------------------------------")
logger.info(f"Number of trainable parameters = {nfm.get_n_params()}")
logger.info("")
for key, value in nfm.state_dict().items():
    logger.info(key)
    logger.info(value)
    logger.info("")

# Optimizer
# --------------------------------------------------------------------------------------

optimizer = None
if args.optim == "adam":
    optimizer = torch.optim.Adam(
        nfm.parameters(),
        lr=args.lr,
        weight_decay=0.0,
        betas=(0.9, 0.999),
        eps=1.00e-08,
        amsgrad=True,
        foreach=None,
        maximize=False,
        capturable=False,
        differentiable=False,
        fused=None,
    )
elif args.optim == "adabelief":
    from adabelief_pytorch import AdaBelief

    optimizer = AdaBelief(
        nfm.parameters(),
        lr=args.lr,
        eps=1.00e-16,
        betas=(0.9, 0.999),
        weight_decouple=True,
        rectify=False,
    )

lr_scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(
    optimizer,
    mode="min",
    factor=args.lr_drop,
    patience=args.lr_patience,
    threshold=0.001,
    threshold_mode="rel",
    min_lr=args.min_lr,
    verbose=False,
)

logger.info("")
logger.info("Optimizer")
logger.info("--------------------------------------------------------------------------")
logger.info(optimizer)

# Diagnostics
# --------------------------------------------------------------------------------------

def save_figure(filename, step=0, iteration=None, ext="png", verbose=True, **kwargs):
    filename = f"{filename}_{step:02.0f}"
    if iteration is not None:
        filename = f"{filename}_{iteration:05.0f}"
    filename = man.get_filename(filename)
    filename = f"{filename}.{ext}"
    kwargs.setdefault("dpi", 250)
    if verbose:
        print(f"Saving file {filename}")
    plt.savefig(filename, **kwargs)
    plt.close()

# Training loop
# --------------------------------------------------------------------------------------

def pushforward_data(data_loader=None, nfm=None, nt=None):
    x_new = torch.zeros(1)
    with torch.no_grad():
        for (x,) in data_loader:
            x_temp, _, _, _ = nfm.forward(x, nt=nt)
            if x_new.shape[0] == 1:
                x_new = x_temp
            else:
                x_new = torch.cat((x_new, x_temp), dim=0)
    dataset = torch.utils.data.TensorDataset(x_new)
    data_loader = torch.utils.data.DataLoader(
        dataset=dataset,
        batch_size=data_loader.batch_size,
        shuffle=False,
    )
    return data_loader

state_dicts = []

for step in range(args.n_steps):
    print(f"step={step}")

    best_avg_loss = best_avg_vloss = float("inf")
    best_state_dict = nfm.state_dict()

    for param_group in optimizer.param_groups:
        param_group["lr"] = args.lr
    lr_scheduler.num_bad_epochs = 0

    monitor = Monitor(filename=man.get_filename(f"history_{step:02.0f}.dat"))
    nfm.to(device)
    nfm.train()
    iteration = 0

    for epoch in range(args.n_epochs):
        running_loss = 0.0
        for batch_index, (x,) in enumerate(data_loader):
            x = cvt(x)
            optimizer.zero_grad()
            loss, costs = nfm.forward_kld(x, nt=args.nt, return_costs=True)
            loss.backward()
            optimizer.step()
            monitor.action(
                loss=loss.item(),
                loss_L=costs[0].item(),
                loss_C=costs[1].item(),
                loss_R=costs[2].item(),
                lr=optimizer.param_groups[0]["lr"],
            )
            running_loss += loss
            iteration += 1
        avg_loss = running_loss / (batch_index + 1)

        nfm.eval()
        with torch.no_grad():
            running_vloss = 0.0
            for batch_index, (x,) in enumerate(val_data_loader):
                x = cvt(x)
                vloss = nfm.forward_kld(x, nt=args.val_nt)
                running_vloss += vloss
        avg_vloss = running_vloss / (batch_index + 1)

        if avg_loss < best_avg_loss:
            best_avg_loss = avg_loss
        if avg_vloss < best_avg_vloss:
            best_avg_vloss = avg_vloss
            best_state_dict = nfm.state_dict()

        lr_scheduler.step(avg_loss)

        print(
            "Epoch {}: avg_loss={:.02e} avg_vloss={:.02e}".format(
                epoch,
                avg_loss,
                avg_vloss,
            )
        )

        if (epoch % args.vis_freq == 0) or (epoch == args.n_epochs - 1):
            with torch.no_grad():
                nfm.eval()
                current_state_dict = nfm.state_dict()
                nfm.load_state_dict(best_state_dict)

                # Plot samples.
                x = val_data[: args.vis_n_points, :]
                plotting.plot_samples(
                    x,
                    nfm,
                    nt=args.val_nt,
                    xmax=4.5,
                    bins=args.vis_n_bins,
                    cmap=args.vis_cmap,
                )
                save_figure("fig_samples", step=step, iteration=iteration)

                # Plot loss history.
                history = monitor.get_data()
                fig, ax = pplt.subplots()
                ax.plot(history["iteration"], history["loss"], color="black")
                ax.format(xlabel="Iteration", ylabel="Loss")
                save_figure("fig__loss", step=step)
                for log in [True, False]:
                    fig, ax = pplt.subplots()
                    for key in ["loss_C", "loss_L", "loss_R"]:
                        ax.plot(history["iteration"], history[key], label=key)
                    if log:
                        ax.format(yscale="log")
                    ax.legend(loc="r", ncols=1, framealpha=0.0)
                    ax.format(xlabel="Iteration", ylabel="Loss")
                    name = "fig__loss_terms_log" if log else "fig__loss_terms"
                    save_figure(name, step=step)

                # Plot learning rate history.
                fig, ax = pplt.subplots()
                ax.plot(history["iteration"], history["lr"], color="black")
                ax.format(xlabel="Iteration", ylabel="Learning rate")
                save_figure("fig__lr", step=step)

                nfm.load_state_dict(current_state_dict)
                nfm.train()

    # Flow forward.
    print("Updating target")
    nfm.load_state_dict(best_state_dict)
    data_loader = pushforward_data(data_loader, nfm, args.nt)
    val_data_loader = pushforward_data(val_data_loader, nfm, args.nt)
    val_data = next(iter(val_data_loader))[0]

    # Save the model.
    print("Saving model")
    state_dict = copy.deepcopy(nfm.state_dict())
    state_dicts.append(state_dict)
    state = {
        "state_dict": state_dict,
        "d": d,
        "m": m,
        "alpha": alpha,
        "n_layers": n_layers,
        "base_dist": nfm.base_dist,
    }
    filename = man.get_filename(f"checkpoint_{step:02.0f}.pth")
    torch.save(state, filename)

    # Evaluate the chained models.
    print("Plotting")
    with torch.no_grad():
        current_state_dict = nfm.state_dict()
        nfm.eval()

        x = get_data(args.vis_n_points)
        plotting.plot_samples_chained(
            x,
            nfm=nfm,
            state_dicts=state_dicts,
            nt=args.val_nt,
            bins=args.vis_n_bins,
            cmap=args.vis_cmap,
        )
        save_figure("fig_samples_chained", step=step)

        nfm.load_state_dict(current_state_dict)
        nfm.train()


#!/usr/bin/env python
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals

AUTHOR = u'Mappy'
SITENAME = u'Mappy Labs'
SITEURL = 'https://techblog.mappy.com'

TIMEZONE = 'Europe/Paris'

DEFAULT_LANG = u'en'

THEME = 'theme/mappy'

# Feed generation is usually not desired when developing
FEED_ALL_ATOM = 'feeds/rss.xml'
CATEGORY_FEED_ATOM = 'feeds/%s/rss.xml'
TRANSLATION_FEED_ATOM = None

PLUGIN_PATHS = ["plugins"]
PLUGINS = ["tag_cloud"]

# Blogroll
LINKS =  (('Mappy', 'https://www.mappy.com/'),
          ('Appli Android', 'https://play.google.com/store/apps/details?id=com.mappy.app'),
          ('Appli iOS', 'https://itunes.apple.com/fr/app/mappy-itineraire-et-recherche/id313834655?mt=8'),
          ('Blog Mappy', 'http://corporate.mappy.com'),
          ('API Mappy', 'http://corporate.mappy.com/faq/integrez-mappy/'),
         )

# Social widget
#SOCIAL = (('Twitter', 'https://twitter.com/Mappy'),
#          )

DEFAULT_PAGINATION = 10

# Uncomment following line if you want document-relative URLs when developing
RELATIVE_URLS = True

STATIC_PATHS = ['images','resources']

TWITTER_URL = 'https://twitter.com/Mappy'
GITHUB_URL = 'https://github.com/Mappy'
FACEBOOK_URL = 'https://www.facebook.com/MappyOnline'


from datetime import datetime
from hashlib import sha256

class Block:
    def __init__(self, index: int, data, previous_hash: str):
        self.index = index
        self.timestamp = int(datetime.timestamp(datetime.utcnow()))
        self.data = data
        self.previous_hash = previous_hash
        self.nonce = 0
        self.hash = self.hash_block()

    def hash_block(self) -> str:
        block_as_list = self.to_list()
        hash_sha256 = sha256(str(block_as_list).encode("utf-8"))
        return hash_sha256.hexdigest()

    def mine_block(self, difficulty: int):
        print("Mining...")
        while self.hash[:difficulty] != "0" * difficulty:
            current_timestamp = int(datetime.timestamp(datetime.utcnow()))
            if self.timestamp != current_timestamp:
                self.timestamp = current_timestamp
                self.nonce = 0
            self.nonce += 1
            if self.nonce > 1000000000:
                print("Failed to mine block")
                return False
            self.hash = self.hash_block()
        return self

    def is_valid(self, difficulty: int) -> bool:
        if self.hash[:difficulty] != "0" * difficulty:
            return False
        elif self.hash != self.hash_block():
            return False
        return True

    def to_list(self, include_hash: bool = False) -> list:
        block_as_list = [
            str(self.index),
            str(self.timestamp),
            str(self.data),
            str(self.previous_hash),
            str(self.nonce),
        ]
        if include_hash:
            block_as_list.append(self.hash)
        return block_as_list

    def populate_from_list(self, block_as_list: list):
        self.index = int(block_as_list[0])
        self.timestamp = int(block_as_list[1])
        self.data = block_as_list[2]
        self.previous_hash = block_as_list[3]
        self.nonce = int(block_as_list[4])
        self.hash = self.hash_block()
        return self

    def __repr__(self):
        return "Block<Hash: {}, Nonce: {}>".format(self.hash, self.nonce)

    def __str__(self):
        str_block = ""
        str_block += str(self.index) + "\t"
        str_block += str(datetime.utcfromtimestamp(self.timestamp)) + "\t"
        if len(self.data) > 16:
            str_block += str(self.data[:16]) + "..."
        else:
            str_block += str(self.data).ljust(16)
        str_block += "\t"
        str_block += str(self.previous_hash)[:16] + "...\t"
        str_block += str(self.nonce).ljust(16) + "\t"
        str_block += str(self.hash)[:16] + "..."
        return str_block


"""
WHAT TO WRITE IN VIEWS TESTS:
------------------------------
1- USE THE DJANGO TEST CLIENT
2- CHECK THE TEMPLATE USED AND THEN CHECK EACH ITEM
   IN CONTEXT
3- CHECK THAT ANY OBJECTS ARE THE RIGHT ONES, OR
   QUERYSETS HAVE THE CORRECT ITEMS
4- CHECK THAT ANY FORMS ARE OF THE RIGHT CLASS
5- THINK ABOUT TESTING TEMPLATE LOGIC: ANY FOR/IF
   MIGHT DESERVE A MINIMAL TEST
6- FOR POST REQUESTS, MAKE SURE YOU TEST FOR BOTH
   VALID AND INVALID CASES
7- CHECK THAT FORM IS RENDERED AND ERRORS ARE DISPLAYED
"""
from django.test import TestCase
from django.utils.html import escape

from ..models import Item, List
from ..forms import (ItemForm, EMPTY_ITEM_ERROR,
                     ExistingListItemForm, DUPLICATE_ITEM_ERROR)

class HomePageTest(TestCase):
    def test_uses_home_template(self):
        response = self.client.get('/')
        self.assertTemplateUsed(response, 'home.html')

    def test_home_page_uses_item_form(self):
        response = self.client.get('/')
        self.assertIsInstance(response.context['form'], ItemForm)

class ListViewTest(TestCase):

    def test_uses_list_template(self):
        list_ = List.objects.create()
        """
        USE THE DJANGO TEST CLIENT
        """
        response = self.client.get('/lists/' + str(list_.id) + '/')
        """
        CHECK THE TEMPLATE USED AND THEN CHECK EACH ITEM
        IN CONTEXT
        """
        self.assertTemplateUsed(response, "list.html")

    def test_passes_context_list_to_templates(self):
        List.objects.create()
        correct_list = List.objects.create()

        response = self.client.get('/lists/' + str(correct_list.id) + '/')
        """
        CHECK THAT ANY OBJECTS ARE THE RIGHT ONES, OR
        QUERYSETS HAVE THE CORRECT ITEMS
        """
        self.assertEqual(response.context['list'], correct_list)

    def test_displays_item_form(self):
        list_ = List.objects.create()
        response = self.client.get('/lists/' + str(list_.id) + '/')
        """
        CHECK THAT ANY FORMS ARE OF THE RIGHT CLASS
        """
        self.assertIsInstance(response.context['form'], ExistingListItemForm)
        self.assertContains(response, 'name="text"')

    def test_displays_only_items_for_that_list(self):
        correct_list = List.objects.create()
        Item.objects.create(text="item 1", list=correct_list)
        Item.objects.create(text="item 2", list=correct_list)

        other_list = List.objects.create()
        Item.objects.create(text="Other item 1", list=other_list)
        Item.objects.create(text="Other item 2", list=other_list)
        """
        THINK ABOUT TESTING TEMPLATE LOGIC: ANY FOR/IF
        MIGHT DESERVE A MINIMAL TEST
        """
        response = self.client.get('/lists/' + str(correct_list.id) + '/')
        self.assertContains(response, "item 1")
        self.assertContains(response, "item 2")
        self.assertNotContains(response, "Other item 1")
        self.assertNotContains(response, "Other item 2")

    """
    FOR POST REQUESTS, MAKE SURE YOU TEST FOR BOTH
    VALID AND INVALID CASES
    """

    def test_can_save_a_POST_request_to_an_existing_list(self):
        List.objects.create()
        correct_list = List.objects.create()

        self.client.post('/lists/' + str(correct_list.id) + '/',
                         data={'text': "A new item for an existing list"})
        self.assertEqual(Item.objects.count(), 1)

        new_item = Item.objects.first()
        self.assertEqual(new_item.text, 'A new item for an existing list')
        self.assertEqual(new_item.list, correct_list)

    def test_POST_redirects_to_list_view(self):
        correct_list = List.objects.create()
        List.objects.create()

        response = self.client.post(('/lists/' +
                                     str(correct_list.id) + '/'),
                                    data={'text':
                                          'A new item for an existing list'})

        self.assertRedirects(response, '/lists/' + str(correct_list.id) + '/')

    def post_invalid_input(self):
        list_ = List.objects.create()
        return self.client.post(
            '/lists/' + str(list_.id) + '/', data={'text': ''})

    def test_for_invalid_input_nothing_saved_to_db(self):
        self.post_invalid_input()
        self.assertEqual(Item.objects.count(), 0)

    def test_for_invalid_input_renders_list_template(self):
        response = self.post_invalid_input()
        self.assertTemplateUsed(response, "list.html")
        self.assertEqual(response.status_code, 200)

    def test_for_invalid_input_passes_form_to_template(self):
        response = self.post_invalid_input()
        self.assertIsInstance(response.context['form'], ExistingListItemForm)

    def test_for_invalid_input_shows_errors_on_page(self):
        """
        CHECK THAT FORM IS RENDERED AND ERRORS ARE DISPLAYED
        """
        response = self.post_invalid_input()
        self.assertContains(response, escape(EMPTY_ITEM_ERROR))

    def test_duplicate_item_validation_errors_end_up_on_lists_page(self):
        list_ = List.objects.create()
        Item.objects.create(list=list_, text="hey john")
        response = self.client.post(
            '/lists/' + str(list_.id) + '/',
            data={"text": "hey john"}
        )
        expected_error = escape(DUPLICATE_ITEM_ERROR)
        self.assertContains(response, expected_error)
        self.assertTemplateUsed(response, "list.html")
        self.assertEqual(Item.objects.count(), 1)

class NewListTest(TestCase):

    def test_invalid_list_items_arent_saved(self):
        self.client.post('/lists/new', data={'text': ''})
        self.assertEqual(List.objects.count(), 0)
        self.assertEqual(Item.objects.count(), 0)

    def test_for_invalid_input_renders_home_template(self):
        response = self.client.post('/lists/new', data={"text": ""})
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, "home.html")

    def test_validation_errors_are_shown_on_home_page(self):
        response = self.client.post('/lists/new', data={"text": ""})
        self.assertContains(response, escape(EMPTY_ITEM_ERROR))

    def test_for_invalid_input_passes_form_to_template(self):
        response = self.client.post('/lists/new', data={"text": ""})
        self.assertIsInstance(response.context['form'], ItemForm)

    def test_can_save_a_POST_request(self):
        self.client.post('/lists/new', data={"text": "A new list item"})
        self.assertEqual(Item.objects.count(), 1)
        new_item = Item.objects.first()
        self.assertEqual(new_item.text, "A new list item")

    def test_redirects_after_POST(self):
        response = self.client.post(
            '/lists/new', data={"text": "A new list item"})
        new_list = List.objects.first()
        self.assertEqual(response.status_code, 302)
        self.assertRedirects(response, '/lists/' + str(new_list.id) + '/')


from math import sqrt

def is_prime(n):
    if n == 1:
        return False
    for i in range(2, int(sqrt(n)) + 1):
        if n % i == 0:
            return False
    return True

def find_monisen(n):
    if n == 1:
        return 2, 3
    p = 2
    count = 0
    while True:
        if is_prime(p):
            m = 2**p - 1
            if is_prime(m):
                count += 1
                if count == n:
                    return p, m
        p += 1

if __name__ == "__main__":
    n = eval(input())
    print(f"p={find_monisen(n)[0]} m={find_monisen(n)[1]}")


from app.db_config import get_config, get_firebaseapi
import pyrebase, requests

pb_set = get_config()
firebase = pyrebase.initialize_app(pb_set)

auth = firebase.auth()
db = firebase.database()

def get_user_info(currentToken):
    firebase_api = get_firebaseapi()

    url = f"https://identitytoolkit.googleapis.com/v1/accounts:lookup?key={firebase_api}"
    headers = {'Content-Type': 'application/json'}
    data = {"idToken": currentToken}
    response = requests.post(url, headers=headers, json=data)
    user_info = response.json()['users'][0]

    return user_info

from . import auth
from . import db


import glob
import json
import os
import re
import sys
import time

def set_env_var(env_var, value, overwrite_existing=False):
    """
    Sets the specified environment variable.

    If overwrite_existing is False, it will only set the new env var value
    if the environment variable is not already set.

    If overwrite_existing is True, the environment variable will always be
    set to the specified value.
    """
    if overwrite_existing or not os.environ.get(env_var):
        os.environ[env_var] = str(value)

class BaseModelInitializer(object):

    def __init__(self, args, custom_args=[], platform_util=None):
        self.args = args
        self.custom_args = custom_args
        self.platform_util = platform_util

        # Set default values for TCMalloc and convert string value to a boolean
        if self.args.disable_tcmalloc is None:
            # Set to False for int8 and True for other precisions
            self.args.disable_tcmalloc = self.args.precision != "int8"
        elif isinstance(self.args.disable_tcmalloc, str):
            self.args.disable_tcmalloc = self.args.disable_tcmalloc == "True"

        # Ensure that we are using the proper version of python to run the benchmarking script
        self.python_exe = os.environ["PYTHON_EXE"]

        if not platform_util:
            raise ValueError("Did not find any platform info.")

        # use case: bare-metal with openmpi, horovod and multi-node
        if os.environ["MPI_HOSTNAMES"] != "None" and ("DOCKER" not in os.environ or os.environ["DOCKER"] == "False"):
            if os.environ["MPI_NUM_PROCESSES"] != "None":
                try:
                    # slots per host calculation using MPI_NUM_PROCESSES and number of hosts
                    host_names = os.environ["MPI_HOSTNAMES"]
                    number_of_hosts = len(host_names.split(','))
                    slots_per_host = int(int(os.environ["MPI_NUM_PROCESSES"]) / number_of_hosts)
                    host_names = ",".join([host + ":" + str(slots_per_host) for host in host_names.split(',')])
                    # see the [examples](https://horovod.readthedocs.io/en/latest/mpirun.html) for the mca flags
                    self.python_exe = "mpirun " + " -x LD_LIBRARY_PATH " + " -x PYTHONPATH " \
                        + " --allow-run-as-root -n " + os.environ["MPI_NUM_PROCESSES"] + " -H " + host_names \
                        + " -mca pml ob1 -mca btl ^openib -mca btl_tcp_if_exclude " \
                          "lo,docker0 --bind-to none --map-by slot " \
                        + self.python_exe
                except Exception as exception:
                    raise ValueError("Caught exception calculating slots per host {}".format(str(exception)))
            else:
                raise ValueError("MPI_NUM_PROCESSES is required for MPI_HOSTNAMES and will be split evenly across the "
                                 "hosts.")
        # use case: docker with openmpi, single-node, multi-instance
        elif os.environ["MPI_NUM_PROCESSES"] != "None":
            if os.environ["MPI_NUM_PROCESSES_PER_SOCKET"] == "1":
                # Map by socket using OpenMPI by default (PPS=1).
                self.python_exe = "mpirun --allow-run-as-root -n " + os.environ["MPI_NUM_PROCESSES"] \
                    + " --map-by socket " + self.python_exe
            else:
                # number of processes per socket (pps)
                pps = int(os.environ["MPI_NUM_PROCESSES_PER_SOCKET"])
                split_a_socket = str(platform_util.num_cores_per_socket // pps)
                # Launch pps MPI processes over one socket
                self.python_exe = "mpirun --allow-run-as-root -n " + os.environ["MPI_NUM_PROCESSES"] \
                    + " --map-by ppr:" + str(pps) + ":socket:pe=" + split_a_socket + " --cpus-per-proc " \
                    + split_a_socket + " " + self.python_exe

    def run_command(self, cmd, replace_unique_output_dir=None):
        """
        Prints debug messages when verbose is enabled, and then runs the
        specified command.

        If the replace_unique_output_dir arg is set, multi-instance runs will
        swap out that path for a path with the instance number in the folder name
        so that each instance uses a unique output folder.
        """
        if self.args.verbose:
            print("Received these standard args: {}".format(self.args))
            print("Received these custom args: {}".format(self.custom_args))
            print("Current directory: {}".format(os.getcwd()))

        if self.args.numa_cores_per_instance:
            num_numas = self.platform_util.num_numa_nodes

            if not num_numas:
                print("Warning: Unable to run multiple instances using numactl, "
                      "because no numa nodes were found.")
            elif not self.platform_util.cpu_core_list:
                print("Warning: Unable to run multiple instances using numactl, "
                      "the list of cpu nodes could not be retrieved. Please ensure "
                      "that your system has numa nodes and numactl is installed.")
            else:
                self.run_numactl_multi_instance(
                    cmd, replace_unique_output_dir=replace_unique_output_dir)
        else:
            if self.args.verbose:
                print("Running: {}".format(str(cmd)))

            os.system(cmd)

    def group_cores(self, cpu_cores_list, cores_per_instance):
        """
        Group cores based on the number of cores we want per instance.
        Returns a 2D array with the list of cores for each instance.
        """
        list_of_groups = zip(*(iter(cpu_cores_list),) * cores_per_instance)
        end_list = [list(i) for i in list_of_groups]
        count = len(cpu_cores_list) % cores_per_instance
        end_list.append(cpu_cores_list[-count:]) if count != 0 else end_list
        return end_list

    def run_numactl_multi_instance(self, cmd, replace_unique_output_dir=None):
        """
        Generates a series of commands that call the specified cmd with multiple
        instances, where each instance uses the a specified number of cores. The
        number of cores used per instance is specified by args.numa_cores_per_instance.

        The command for each instance uses numactl and the --physcpubind arg with
        the appropriate core list. Each instance writes output to it's own log file,
        and a combined log file is created after everything has executed.

        If the replace_unique_output_dir arg is set, multi-instance runs will
        swap out that path for a path with the instance number in the folder name
        so that each instance uses a unique output folder.
        """

        # Find LD_PRELOAD vars, remove them from the cmd, and save them to add on to the prefix
        ld_preload_strs = re.findall(r'\bLD_PRELOAD=\S*', cmd)
        ld_preload_prefix = ""
        for ld_preload_str in ld_preload_strs:
            cmd = cmd.replace(ld_preload_str, "")
            ld_preload_prefix += ld_preload_str + " "

        # Remove leading/trailing whitespace
        cmd = cmd.strip()

        if self.args.numa_cores_per_instance != "socket":
            # Get the cores list and group them according to the number of cores per instance
            cores_per_instance = int(self.args.numa_cores_per_instance)
            cpu_cores_list = self.platform_util.cpu_core_list

            if self.args.socket_id != -1:
                # If it's specified to just use a single socket, then only use the cores from that socket
                if len(cpu_cores_list) > self.args.socket_id:
                    cpu_cores_list = cpu_cores_list[self.args.socket_id]
                else:
                    raise ValueError("Error while trying to get the core list for socket {0}. "
                                     "The core list does not have cores for socket {0}.\n "
                                     "Core list: {1}\n".format(self.args.socket_id, str(cpu_cores_list)))
            else:
                # Using cores from all sockets
                combined_core_list = []
                for socket_cores in cpu_cores_list:
                    combined_core_list += socket_cores
                cpu_cores_list = combined_core_list

            instance_cores_list = self.group_cores(cpu_cores_list, cores_per_instance)
        else:
            instance_cores_list = []
            cores_per_instance = "socket"
            # Cores should be grouped based on the cores for each socket
            if self.args.socket_id != -1:
                # Only using cores from one socket
                instance_cores_list[0] = self.platform_util.cpu_core_list[self.args.socket_id]
            else:
                # Get the cores for each socket
                instance_cores_list = self.platform_util.cpu_core_list

        # Setup the log file name with the model name, precision, mode, batch size (if there is one),
        # number of cores per instance. An extra {} is intentionally left in the log_filename_format
        # string, because this value is filled in with the instance number later on.
        batch_size = ""
        if self.args.batch_size and self.args.batch_size > 0:
            batch_size = "bs{}_".format(self.args.batch_size)
        log_filename_format = os.path.join(
            self.args.output_dir, "{}_{}_{}_{}cores{}_".format(
                self.args.model_name, self.args.precision, self.args.mode, batch_size, cores_per_instance))
        log_filename_format += "{}.log"
        instance_logfiles = []

        # Loop through each instance and add that instance's command to a string
        multi_instance_command = ""
        for instance_num, core_list in enumerate(instance_cores_list):
            if cores_per_instance != "socket" and len(core_list) < int(cores_per_instance):
                print("NOTE: Skipping remainder of {} cores for instance {}"
                      .format(len(core_list), instance_num))
                continue

            if len(core_list) == 0:
                continue

            prefix = ("{0}OMP_NUM_THREADS={1} "
                      "numactl --localalloc --physcpubind={2}").format(
                ld_preload_prefix, len(core_list), ",".join(core_list))
            instance_logfile = log_filename_format.format("instance" + str(instance_num))

            unique_command = cmd
            if replace_unique_output_dir:
                # Swap out the output dir for a unique dir
                unique_dir = os.path.join(replace_unique_output_dir,
                                          "instance_{}".format(instance_num))
                unique_command = unique_command.replace(replace_unique_output_dir, unique_dir)

            instance_command = "{} {}".format(prefix, unique_command)
            multi_instance_command += "{} >> {} 2>&1 & \\\n".format(
                instance_command, instance_logfile)
            instance_logfiles.append(instance_logfile)

            # write the command to the instance's log file
            with open(instance_logfile, "w") as log:
                log.write(instance_command)
                log.write("\n\n")

        multi_instance_command += "wait"

        # Run the multi-instance command
        print("\nMulti-instance run:\n" + multi_instance_command)
        sys.stdout.flush()
        os.system(multi_instance_command)

        # Wait to ensure that log files have been written
        max_retries = 20
        retry_counter = 0
        while retry_counter < max_retries:
            if all([os.path.exists(log) for log in instance_logfiles]):
                break
            retry_counter += 1
            if retry_counter >= max_retries:
                print("Warning: Log files for all instances were not found after "
                      "rechecking and waiting for {} seconds. The combined log file "
                      "may not have output from all instances.".format(retry_counter))
                break
            time.sleep(1)

        # Generate the combined log file
        all_instance_log = log_filename_format.format("all_instances")
        os.environ["LOG_FILENAME"] = os.path.basename(all_instance_log)
        with open(all_instance_log, mode="w") as combined_file:
            for instance_logfile in instance_logfiles:
                if not os.path.exists(instance_logfile):
                    print("Skipping {} when generating the combined log file, because "
                          "it doesn't exist".format(os.path.basename(instance_logfile)))
                    continue

                with open(instance_logfile) as individual_file:
                    for line in individual_file:
                        combined_file.write(line)

        # Print out lists of log files
        print("\nThe following log files were saved to the output directory:")
        print("\n".join([os.path.basename(log_path) for log_path in instance_logfiles
                         if os.path.exists(log_path)]))
        if os.path.exists(all_instance_log):
            print("\nA combined log file was saved to the output directory:\n"
                  "{}\n".format(os.path.basename(all_instance_log)))

    def get_command_prefix(self, socket_id, numactl=True):
        """
        Returns the command prefix with:
         - LD_PRELOAD for int8 models (if tcmalloc is not disabled)
         - The numactl command with --cpunodebind and --membind set to the specified socket_id (if numactl=True)

        Should be used only for single instance.
        """
        command = ""
        ld_preload = ""

        if not self.args.disable_tcmalloc:
            # Try to find the TCMalloc library file
            matches = glob.glob("/usr/lib/libtcmalloc.so*")

            if len(matches) == 0:
                matches = glob.glob("/usr/lib64/libtcmalloc.so*")

            if len(matches) == 0:
                matches = glob.glob("/usr/lib/*/libtcmalloc.so*")

            if len(matches) == 0:
                matches = glob.glob("/usr/lib64/*/libtcmalloc.so*")

            if len(matches) > 0:
                ld_preload += "LD_PRELOAD={} ".format(matches[0])
            else:
                # Unable to find the TCMalloc library file
                print("Warning: Unable to find the TCMalloc library file (libtcmalloc.so) in /usr/lib, /usr/lib64, "
                      "/usr/lib/*, or /usr/lib64/* so the LD_PRELOAD environment variable will not be set.")

        num_numas = self.platform_util.num_numa_nodes
        if num_numas and socket_id != -1 and numactl and not self.args.numa_cores_per_instance:
            if self.args.num_cores == -1:
                # Running on the whole socket
                command += "numactl --cpunodebind={0} --membind={0} ".format(
                    str(socket_id))
            else:
                # Running on specific number of cores
                first_physical_core = self.platform_util.cpuset_cpus[0][0]
                num_sockets = len(self.platform_util.cpuset_cpus.keys())
                num_cores_in_socket0 = len(self.platform_util.cpuset_cpus[0])
                for i in range(num_sockets):
                    if num_cores_in_socket0 != len(
                            self.platform_util.cpuset_cpus[i]):
                        raise ValueError(
                            "Error: Identifying logical core id assumes all sockets have same number of cores"
                        )
                first_logical_core = num_cores_in_socket0 * num_sockets
                if self.platform_util.num_threads_per_core == 1:
                    # HT is off
                    cpus_range = "{0}-{1}".format(
                        first_physical_core,
                        first_physical_core + self.args.num_cores - 1)
                else:
                    # HT is on.
                    cpus_range = "{0}-{1},{2}-{3}".format(
                        first_physical_core,
                        first_physical_core + self.args.num_cores - 1,
                        first_logical_core,
                        first_logical_core + self.args.num_cores - 1)
                command += "numactl -C{0} --membind=0 ".format(cpus_range)

        # Add LD_PRELOAD to the front of the command
        command = ld_preload + command

        return command

    def add_args_to_command(self, command, arg_list):
        """
        Add args that are specified in the arg list to the command.  batch_size
        is a special case, where it's not added if it's set to -1 (undefined).
        Returns the command string with args.
        """
        for arg in vars(self.args):
            arg_value = getattr(self.args, arg)
            if arg == "batch_size" and arg_value == -1:
                continue
            if arg_value and (arg in arg_list):
                command = "{cmd} --{param}={value}".format(
                    cmd=command, param=arg, value=arg_value)
        return command

    def set_num_inter_intra_threads(self, num_inter_threads=None, num_intra_threads=None):
        """
        Sets default values for self.args.num_inter_threads and
        self.args.num_intra_threads, only if they are not already set.

        If num_inter_threads and/or num_intra_threads are specified, then those
        are the values that will be used. Otherwise, if they are None, then the
        following criteria applies:

        If multiple instances are being used (specified with numa_cores_per_instance),
        then each instance should have:
        * num_inter_threads = 1
        * num_intra_threads = number of cores per instance

        If a single socket is being used:
         * num_inter_threads = 1
         * num_intra_threads = The number of cores on a single socket, or
           self.args.num_cores if a specific number of cores was defined.

        If all sockets are being used:
         * num_inter_threads = The number of sockets
         * num_intra_threads = The total number of cores across all sockets, or
           self.args.num_cores if a specific number of cores was defined.
         * in case MPI_NUM_PROCESSES is used
           * num_inter_threads = 1
           * num_intra_threads = the number of cores on a single socket minus 2
        """
        # if num_inter_threads is specified, use that value as long as the arg isn't set
        if num_inter_threads and not self.args.num_inter_threads:
            self.args.num_inter_threads = num_inter_threads

        # if num_intra_threads is specified, use that value as long as the arg isn't set
        if num_intra_threads and not self.args.num_intra_threads:
            self.args.num_intra_threads = num_intra_threads

        if self.args.numa_cores_per_instance:
            # Set default num inter/intra threads if the user didn't provide specific values
            if self.args.numa_cores_per_instance == "socket":
                if self.args.socket_id != -1:
                    inter_threads = len(self.platform_util.cpu_core_list[self.args.socket_id])
                else:
                    # since we can only have one value for inter threads and the number of cores
                    # per socket can vary, if the cpuset is limited, get the lowest core count
                    # per socket and use that as the num inter threads
                    inter_threads = min([len(i) for i in self.platform_util.cpu_core_list if len(i) > 0])
            else:
                inter_threads = self.args.numa_cores_per_instance

            if not self.args.num_inter_threads:
                self.args.num_inter_threads = 1
            if not self.args.num_intra_threads:
                self.args.num_intra_threads = inter_threads
            if not self.args.data_num_inter_threads:
                self.args.data_num_inter_threads = 1
            if not self.args.data_num_intra_threads:
                self.args.data_num_intra_threads = inter_threads
        elif self.args.socket_id != -1:
            if not self.args.num_inter_threads:
                self.args.num_inter_threads = 1
            if not self.args.num_intra_threads:
                if self.args.num_cores != -1:
                    self.args.num_intra_threads = self.args.num_cores
                elif self.platform_util.cpuset_cpus and \
                        self.args.socket_id in self.platform_util.cpuset_cpus.keys():
                    self.args.num_intra_threads = len(self.platform_util.cpuset_cpus[self.args.socket_id])
                else:
                    self.args.num_intra_threads = self.platform_util.num_cores_per_socket
        else:
            if not self.args.num_inter_threads:
                self.args.num_inter_threads = self.platform_util.num_cpu_sockets
                if os.environ["MPI_NUM_PROCESSES"] != "None":
                    self.args.num_inter_threads = 1
            if not self.args.num_intra_threads:
                if self.args.num_cores == -1:
                    if self.platform_util.cpuset_cpus and len(self.platform_util.cpuset_cpus.keys()) > 0:
                        # Total up the number of cores in the cpuset
                        self.args.num_intra_threads = sum([len(self.platform_util.cpuset_cpus[socket_id])
                                                           for socket_id in self.platform_util.cpuset_cpus.keys()])
                    else:
                        self.args.num_intra_threads = \
                            int(self.platform_util.num_cores_per_socket *
                                self.platform_util.num_cpu_sockets)
                    if os.environ["MPI_NUM_PROCESSES"] != "None":
                        self.args.num_intra_threads = self.platform_util.num_cores_per_socket - 2
                else:
                    self.args.num_intra_threads = self.args.num_cores

        if self.args.verbose:
            print("num_inter_threads: {}\nnum_intra_threads: {}".format(
                self.args.num_inter_threads, self.args.num_intra_threads))

    def set_kmp_vars(self, config_file_path, kmp_settings=None, kmp_blocktime=None, kmp_affinity=None):
        """
        Sets KMP_* environment variables to the specified value, if the environment variable has not already been set.
        The default values in the json file are the best known settings for the model.
        """
        if os.path.exists(config_file_path):
            with open(config_file_path, 'r') as config:
                config_object = json.load(config)

            # First sets default from config file
            for param in config_object.keys():
                for env in config_object[param].keys():
                    set_env_var(env, config_object[param][env])

        else:
            print("Warning: File {} does not exist and \
            cannot be used to set KMP environment variables".format(config_file_path))

        # Override user provided envs
        if kmp_settings:
            set_env_var("KMP_SETTINGS", kmp_settings, overwrite_existing=True)
        if kmp_blocktime:
            set_env_var("KMP_BLOCKTIME", kmp_blocktime, overwrite_existing=True)
        if kmp_affinity:
            set_env_var("KMP_AFFINITY", kmp_affinity, overwrite_existing=True)


from flask import Flask
from flask import request, redirect, render_template
from fastai.learner import load_learner
import pathlib
from fastai.vision.core import PILImage
import platform

application = Flask(__name__)
application.config['MAX_CONTENT_LENGTH'] = 12 * 1024 * 1024
MIN_STANDARD = 0.9

# Workaround pytorch issue with models developed on linux being used on Windows
if platform.system() == 'Windows':
    pathlib.PosixPath = pathlib.WindowsPath

ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}

learn_inf = load_learner('flag_export.pkl', cpu=True)

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@application.route("/upload-image/", methods=["GET", "POST"])
def upload_image():
    if request.method == "POST":
        if request.files:
            image = request.files["image"]
            if allowed_file(image.filename):
                pred, pred_idx, probs = learn_inf.predict(PILImage.create(image))
                pred = pred.replace('_', ' ').title()
                if probs[pred_idx] > MIN_STANDARD:
                    return render_template("public/upload_image.html",
                                           messages=f"I think it is a {pred} flag; Probability: {probs[pred_idx]:.04f}")
                else:
                    return render_template("public/upload_image.html",
                                           messages=f"I can't recognise this one." +
                                                    f" But if had to guess, " +
                                                    f"I would say it was the flag of {pred}; Probability: {probs[pred_idx]:.04f}")
            else:
                return render_template("public/upload_image.html", messages=f"Sorry, invalid image type: Must be a: {ALLOWED_EXTENSIONS}")

    return render_template("public/upload_image.html", messages="")

@application.route('/')
def go_to_upload():
    return redirect("upload-image/")

if __name__ == '__main__':
    application.run()


#https://www.blog.pythonlibrary.org/2010/03/08/a-simple-step-by-step-reportlab-tutorial/

import time
from reportlab.lib.enums import TA_JUSTIFY
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch
from reportlab.lib.colors import HexColor
import os as os

from tools import logger

#import os as os

def generatePdfForPerson(person):
	#path = os.path.dirname(os.path.realpath(__file__))
	#path = "/".join(path.split("/")[:-1]) # remove characters after last "/"" in filepath
	#doc = SimpleDocTemplate(path + '/form.pdf', rightMarge=72, leftMargin=72, topMargin=10, bottomMargin=18)
	doc = SimpleDocTemplate('Workout_App_Data\\form.pdf', rightMarge=72, leftMargin=72, topMargin=10, bottomMargin=18)
	Story=[]
	#logo = path + '/pdf/MSWLogo.jpg'

	logger.log("opening: " + str(os.path.dirname(os.path.realpath(__file__)) + '\\' + 'MSWLogo.jpg'))
	logo = os.path.dirname(os.path.realpath(__file__)) + '\\' + 'MSWLogo.jpg'

	im = Image(logo, 2*inch, 2*inch)
	im.hAlign = 'LEFT'
	Story.append(im)

	styles = getSampleStyleSheet()
	styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY, borderWidth=1, borderColor=HexColor('#800020'), borderPadding=3))
	ptext = ""
	ptext = ptext + 'Name: %s
' % person.name
	ptext = ptext + 'Test Date: %s
' % person.testDate
	ptext = ptext + '
'
	ptext = ptext + 'Heart Rate: %s
' % person.restHR
	ptext = ptext + 'Blood Pressure: %s
' % person.restBP
	ptext = ptext + 'Height (cm): %s
' % person.height
	ptext = ptext + 'Weight (kg): %s
' % person.weight
	Story.append(Paragraph(ptext, styles["Justify"]))
	Story.append(Spacer(1, 12))

	if "BMIframe" in person.framesChecked:
		ptext = 'BMI: %s
' % str(person.getBMI())
		Story.append(Paragraph(ptext, styles["Justify"]))
		Story.append(Spacer(1, 12))

	if "Circumference" in person.framesChecked:
		ptext = 'Circumference:
'
		ptext = ptext + 'Hip Circ (cm):%s
' % str(person.hipCirc)
		ptext = ptext + 'Waist Circ (cm):%s
' % str(person.waistCirc)
		ptext = ptext + 'Arm Circ (cm):%s
' % str(person.armCirc)
		ptext = ptext + 'Thigh Circ (cm):%s
' % str(person.thighCirc)
		Story.append(Paragraph(ptext, styles["Justify"]))

		Story.append(Spacer(1, 12))

	if "ThreeSiteSkinfold" in person.framesChecked:
		ptext = 'Three Site Skinfold:
'

		if (person.threeSiteFemaleSupra.strip() != "" and person.threeSiteFemaleTricep.strip() != "" and person.threeSiteFemaleThigh.strip() != ""):
			ptext = ptext + 'Body Density: %s
' % str(person.getThreeSiteMale())

			ptext = ptext + 'Body Fat %%: %s
' % str(person.getBodyFatThreeMale())

		if (person.threeSiteMaleChest.strip() != "" and person.threeSiteMaleAb.strip() != "" and person.threeSiteMaleThigh.strip() != ""):
			ptext = ptext + 'Body Density: %s
' % str(person.getThreeSiteFemale())

			ptext = ptext + 'Body Fat %%: %s
' % str(person.getBodyFatThreeFemale())

		Story.append(Paragraph(ptext, styles["Justify"]))
		Story.append(Spacer(1, 12))

	if "SvnSiteSkinfold" in person.framesChecked:
		ptext = 'Seven Site Skinfold:
'

		ptext = ptext + 'Body Density: %s
' % str(person.getSevenSiteDensity())

		ptext = ptext + 'Body Fat %%: %s
' % str(person.getBodyFatSeven())
		Story.append(Paragraph(ptext, styles["Justify"]))

		Story.append(Spacer(1, 12))

	if "Coopers" in person.framesChecked:
		ptext = 'Coopers Run Test:
'

		ptext = ptext + 'VO2max (ml/kg/min):%s
' % str(person.getCooperAerobic())
		Story.append(Paragraph(ptext, styles["Justify"]))

		Story.append(Spacer(1, 12))

	if "ModAst" in person.framesChecked:
		ptext = 'Modified Astrand Cycle Test:
'

		ptext = ptext + 'VO2max(ml/kg/min): %s
' % str(person.modAstAerobic)
		Story.append(Paragraph(ptext, styles["Justify"]))

		Story.append(Spacer(1, 12))

	if "Ebelling" in person.framesChecked:
		ptext = 'Ebelling Treadmill Test:
'

		ptext = ptext + 'VO2max (ml/kg/min): %s
' % str(person.getEbellingAerobic())
		Story.append(Paragraph(ptext, styles["Justify"]))

		Story.append(Spacer(1, 12))

	if "Rockport" in person.framesChecked:
		ptext = 'Rockport 1 Mile Walk Test:
'

		ptext = ptext + 'VO2max(ml/kg/min): %s
' % str(person.getRockportAerobic())
		Story.append(Paragraph(ptext, styles["Justify"]))

		Story.append(Spacer(1, 12))

	if "MBtoss" in person.framesChecked:
		ptext = 'Med. Ball Toss Distance(cm): %s' % str(person.seatMBDist)
		Story.append(Paragraph(ptext, styles["Justify"]))
		Story.append(Spacer(1, 12))

	if "VertJump" in person.framesChecked:
		ptext = 'Vertical Jump Test:
'

		ptext = ptext + 'Stand and Reach(cm): %s
' % str(person.vertJumpSR)

		ptext = ptext + 'Best Jump(cm): %s
' % str(person.getVertJumpBest())

		ptext = ptext + 'Peak Power(W): %s
' % str(person.getVertJumpPower())
		Story.append(Paragraph(ptext, styles["Justify"]))

		Story.append(Spacer(1, 12))

	if "RMtest" in person.framesChecked:
		ptext = '1 Rep Max (Tested):
'

		if (person.RMTestExA.strip() != "" and person.RMTestExAWeight.strip() != ""):
			ptext = ptext + 'Exercise: %s
' % str(person.RMTestExA)

			ptext = ptext + '1 Rep Max Weight: %s
' % str(person.RMTestExAWeight)

		if (person.RMTestExB.strip() != "" and person.RMTestExBWeight.strip() != ""):
			ptext = ptext + 'Exercise: %s
' % str(person.RMTestExB)

			ptext = ptext + '1 Rep Max Weight: %s
' % str(person.RMTestExBWeight)

		Story.append(Paragraph(ptext, styles["Justify"]))
		Story.append(Spacer(1, 12))

	if "RMpredict" in person.framesChecked:
		ptext = '1 Rep Max (Predicted)
'

		ptext = ptext + 'Exercise: %s
' % str(person.RMPredictEx)

		ptext = ptext + '1 Rep Max Weight: %s
' % str(person.getRepMaxPredict())
		Story.append(Paragraph(ptext, styles["Justify"]))

		Story.append(Spacer(1, 12))

	if "GripStrength" in person.framesChecked:
		ptext = 'GripStrength:
'

		ptext = ptext + 'Left Hand(kg): %s
' % str(person.gripStrengthLeft)

		ptext = ptext + 'Right Hand(kg): %s
' % str(person.gripStrengthRight)
		Story.append(Paragraph(ptext, styles["Justify"]))

		Story.append(Spacer(1, 12))

	if "PushUps" in person.framesChecked:
		ptext = 'Push Ups: %s' % str(person.pushUpNum)
		Story.append(Paragraph(ptext, styles["Justify"]))
		Story.append(Spacer(1, 12))

	if "CurlUps" in person.framesChecked:
		ptext = 'Curl Ups: %s' % str(person.curlUpNum)
		Story.append(Paragraph(ptext, styles["Justify"]))
		Story.append(Spacer(1, 12))

	if "PlankEnd" in person.framesChecked:
		ptext = 'Front Plank Time(sec.): %s' % str(person.plankTime)
		Story.append(Paragraph(ptext, styles["Justify"]))
		Story.append(Spacer(1, 12))

	if "WallSit" in person.framesChecked:
		ptext = 'Wall Sit Time(sec.): %s' % str(person.wallSitTime)
		Story.append(Paragraph(ptext, styles["Justify"]))
		Story.append(Spacer(1, 12))

	if "FlexTests" in person.framesChecked:
		ptext = 'Sit & Reach Distance(cm): %s' % str(person.sitReachDist)
		Story.append(Paragraph(ptext, styles["Justify"]))
		Story.append(Spacer(1, 12))

	if "SLstance" in person.framesChecked:
		ptext = 'Single Leg Stance Test:
'

		ptext = ptext + 'Left Leg Eyes Open Time(sec.): %s
' % str(person.SLOpenLeft)

		ptext = ptext + 'Right Leg Eyes Open Time(sec.): %s
' % str(person.SLOpenRight)

		ptext = ptext + 'Left Leg Eyes Closed Time(sec.): %s
' % str(person.SLCloseLeft)

		ptext = ptext + 'Right Leg Eyes Closed Time(sec.): %s
' % str(person.SLCloseRight)
		Story.append(Paragraph(ptext, styles["Justify"]))

		Story.append(Spacer(1, 12))

	if "DeepSquat" in person.framesChecked:
		ptext = 'Deep Squat Assessment Rating(0-3): %s' % str(person.deepSquatRate)
		Story.append(Paragraph(ptext, styles["Justify"]))
		Story.append(Spacer(1, 12))

	if "WallSlide" in person.framesChecked:
		ptext = ' Wall Slide Assessment Rating(0-3):%s' % str(person.wallSlideRate)
		Story.append(Paragraph(ptext, styles["Justify"]))
		Story.append(Spacer(1, 12))

	if "HipHinge" in person.framesChecked:
		ptext = 'Hip Hinge Assessment Rating(0-3): %s' % str(person.hipHingeRate)
		Story.append(Paragraph(ptext, styles["Justify"]))
		Story.append(Spacer(1, 12))

	if "FrontPlank" in person.framesChecked:
		ptext = 'Front Plank Assessment Rating(0-3): %s' % str(person.frontPlankRate)
		Story.append(Paragraph(ptext, styles["Justify"]))
		Story.append(Spacer(1, 12))

	doc.build(Story)
	print("PDF created")


import os
from collections import defaultdict

from .schemas import validate_rta_mapping
from .utils import load_etc_dump, save_etc_dump, get_path

RTA_DIR = get_path("rta")

class RtaMappings(object):
    """Rta-mapping helper class."""

    def __init__(self):
        """Rta-mapping validation and prep."""
        self.mapping = load_etc_dump('rule-mapping.yml')  # type: dict
        self.validate()

        self._rta_mapping = defaultdict(list)
        self._remote_rta_mapping = {}
        self._rule_mappings = {}

    def validate(self):
        """Validate mapping against schema."""
        for k, v in self.mapping.items():
            validate_rta_mapping(v)

    def add_rule_to_mapping_file(self, rule, rta_name, count=0, *sources):
        """Insert a rule mapping into the mapping file."""
        mapping = self.mapping
        rule_map = {
            'count': count,
            'rta_name': rta_name,
            'rule_name': rule.name,
        }

        if sources:
            rule_map['sources'] = list(sources)

        mapping[rule.id] = rule_map
        self.mapping = dict(sorted(mapping.items()))
        save_etc_dump(self.mapping, 'rule-mapping.yml')
        return rule_map

    def get_rta_mapping(self):
        """Build the rule<-->rta mapping based off the mapping file."""
        if not self._rta_mapping:
            self._rta_mapping = self.mapping.copy()

        return self._rta_mapping

    def get_rta_files(self, rta_list=None, rule_ids=None):
        """Get the full paths to RTA files, given a list of names or rule ids."""
        full_rta_mapping = self.get_rta_mapping()
        rta_files = set()
        rta_list = set(rta_list or [])

        if rule_ids:
            for rule_id, rta_map in full_rta_mapping.items():
                if rule_id in rule_ids:
                    rta_list.update(rta_map)

        for rta_name in rta_list:
            # rip off the extension and add .py
            rta_name, _ = os.path.splitext(os.path.basename(rta_name))
            rta_path = os.path.abspath(os.path.join(RTA_DIR, rta_name + ".py"))
            if os.path.exists(rta_path):
                rta_files.add(rta_path)

        return list(sorted(rta_files))


x = 0
while x < 5:
    print("Not there yet, x=" + str(x))
    x = x + 1

# >>> x = 0
# >>> while x < 5:
# ...     print("Not there yet, x=" + str(x))
# ...     x = x + 1
# ...
# Not there yet, x=0
# Not there yet, x=1
# Not there yet, x=2
# Not there yet, x=3
# Not there yet, x=4
# >>> print("x=" + str(x))
# x=5

def attempts(n):
    x = 1
    while x <= n:
        print("Attempt " + str(x))
        x += 1
    print("Done")

# >>> def attempts(n):
# ...     x = 1
# ...     while x <= n:
# ...         print("Attempt " + str(x))
# ...         x += 1
# ...     print("Done")
# ...
# >>> attempts(5)
# Attempt 1
# Attempt 2
# Attempt 3
# Attempt 4
# Attempt 5
# Done

# >>> while my_variable < 10:
# ...     print("Hello")
# ...     my_variable += 1
# ...
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# NameError: name 'my_variable' is not defined

# >>> my_variable = 5
# >>> while my_variable < 10:
# ...     print("Hello")
# ...     my_variable += 1
# ...
# Hello
# Hello
# Hello
# Hello
# Hello

x = 1
sum = 0
while x < 10:
  sum += x
  x += 1

product = 1
while x < 10:
  product = product * x
  x += 1

# >>> x = 1
# >>> sum = 0
# >>> while x < 10:
# ...     sum = sum + x
# ...     x = x + 1
# ...
# >>> product = 1
# >>> while x < 10:
# ...     product = product * x
# ...     x = x + 1
# ...
# >>> print(sum, product)
# 45 1

# >>> for x in range(5):
# ...     print(x)
# ...
# 0
# 1
# 2
# 3
# 4

# >>> product = 1
# >>> for n in range(1,10):
# ...     product = product * n
# ...
# >>> print(product)
# 362880

def to_celsius(x):
  return (x-32)*5/9

for x in range(0,101,10):
  print(x, to_celsius(x))

# >>> def to_celsius(x):
# ...     return (x-32)*5/9
# ...
# >>> for x in range(0,101,10):
# ...     print(x, to_celsius(x))
# ...
# 0 -17.77777777777778
# 10 -12.222222222222221
# 20 -6.666666666666667
# 30 -1.1111111111111112
# 40 4.444444444444445
# 50 10.0
# 60 15.555555555555555
# 70 21.11111111111111
# 80 26.666666666666668
# 90 32.22222222222222
# 100 37.77777777777778

# >>> for left in range(7):
# ...     for right in range(left, 7):
# ...         print("[" + str(left) + "|" + str(right) + "]", end=" ")
# ...     print()
# ...
# [0|0] [0|1] [0|2] [0|3] [0|4] [0|5] [0|6]
# [1|1] [1|2] [1|3] [1|4] [1|5] [1|6]
# [2|2] [2|3] [2|4] [2|5] [2|6]
# [3|3] [3|4] [3|5] [3|6]
# [4|4] [4|5] [4|6]
# [5|5] [5|6]
# [6|6]

teams = [ 'Dragons', 'Wolves', 'Pandas', 'Unicorns']

# Interactive code snippet
# >>> teams = [ 'Dragons', 'Wolves', 'Pandas', 'Unicorns']
# >>> for home_team in teams:
# ...     for away_team in teams:
# ...         if home_team != away_team:
# ...             print(home_team + " vs " + away_team)
# ...
# Dragons vs Wolves
# Dragons vs Pandas
# Dragons vs Unicorns
# Wolves vs Dragons
# Wolves vs Pandas
# Wolves vs Squirrels
# Pandas vs Dragons
# Pandas vs Wolves
# Pandas vs Squirrels
# Unicorns vs Dragons
# Unicorns vs Wolves
# Unicorns vs Pandas

# >>> for x in 25:
# ...     print(x)
# ...
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: 'int' object is not iterable
#
# >>> for x in range(25):
# ...     print(x)
# ...
#
# >>> for x in [25]:
# ...     print(x)
# ...
# 25

def greet_friends(friends):
    for friend in friends:
        print("Hi " + friend)

greet_friends(['Taylor', 'Luisa', 'Jamaal', 'Eli'])

# >>> def greet_friends(friends):
# ...     for friend in friends:
# ...         print("Hi " + friend)
# ...
# >>> greet_friends("Berry")
# Hi B
# Hi e
# Hi r
# Hi r
# Hi y

def factorial(n):
    print("Factorial called with " + str(n))
    if n < 2:
        print("Returning 1")
        return 1
    result = n * factorial(n-1)
    print("Returning " + str(result) + " for factorial of " + str(n))
    return result

# >>> def factorial(n):
# ...     print("Factorial called with " + str(n))
# ...     if n < 2:
# ...         print("Returning 1")
# ...         return 1
# ...     result = n * factorial(n-1)
# ...     print("Returning " + str(result) + " for factorial of " + str(n))
# ...     return result
# ...
# >>> print(factorial(4))
# Factorial called with 4
# Factorial called with 3
# Factorial called with 2
# Factorial called with 1
# Returning 1
# Returning 2 for factorial of 2
# Returning 6 for factorial of 3
# Returning 24 for factorial of 4
# 24

def factorial(n):
    if n < 2:
        return 1
    return n * factorial(n-1)

# >>> def factorial(n):
# ...     if n < 2:
# ...         return 1
# ...     return n * factorial(n-1)
# ...
# >>> factorial(1000)
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
#   File "<stdin>", line 4, in factorial
#   File "<stdin>", line 4, in factorial
#   File "<stdin>", line 4, in factorial
#   [Previous line repeated 994 more times]
#   File "<stdin>", line 2, in factorial
# RecursionError: maximum recursion depth exceeded in comparison


# import sys
#
# sys.stdin = open("in1.txt", "rt")

n = int(input())
arr = [[0] + list(map(int, input().split())) + [0] for _ in range(n)]
arr.insert(0, [0] * (n + 2))
arr.append([0] * (n + 2))

res = 0

def is_this_peak(a, i, j):
    middle_num = a[i][j]
    if a[i - 1][j] < middle_num and a[i][j - 1] < middle_num and a[i][j + 1] < middle_num and a[i + 1][j] < middle_num:
        return True
    else:
        return False

for i in range(1, n + 1):
    for j in range(1, n + 1):
        if is_this_peak(arr, i, j):
            res += 1

print(res)


from django.shortcuts import get_object_or_404
from rest_framework import serializers
from .models import Vendor
from accounts.models import User, UserProfile
from menu.models import Category, FoodItem
from marketplace.models import Cart

class Vendor_Serializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'first_name', 'last_name', 'username', 'email', 'phone_number']

class Customer_Serializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'first_name', 'last_name', 'username', 'email', 'phone_number']

class UserSerializer(serializers.Serializer):

    role = serializers.SerializerMethodField()

    def get_role(self, obj):
        role_value = obj.role
        if role_value == 1:
            user_role = 'Vendor'
            serializer = Vendor_Serializer(obj)  # Replace with your actual Vendor_Serializer
        elif role_value == 2:
            user_role = 'Customer'
            serializer = Customer_Serializer(obj)  # Replace with your actual Customer_Serializer
        else:
            user_role = 'Unknown'
            serializer = None

        if serializer is not None:
            return {
                'role': user_role,
                'data': serializer.data
            }
        else:
            return {
                'role': user_role
            }

    class Meta:
        model = User
        fields = ['id', 'first_name', 'last_name', 'username', 'email', 'password', 'phone_number', 'role']
        extra_kwargs = {"password": {"write_only": True, "required": True}}

    # def to_representation(self, instance):
    #     serializer = self.get_role_serializer(instance)
    #     return serializer.data

    # def get_role_serializer(self, instance):
    #     role_value = instance.role
    #     if role_value == 1:
    #         serializer = Vendor_Serializer(instance)
    #     elif role_value == 2:
    #         serializer = Customer_Serializer(instance)
    #     else:
    #         raise serializers.ValidationError("Invalid user role.")
    #     return serializer

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta:
      model = UserProfile
      fields = ['profile_picture', 'cover_photo', 'address', 'country', 'state', 'city', 'zip_code','latitude', 'longitude']
      read_only_fields = ['user']

    def validate(self,attrs):
        attrs['user'] = self.context['request'].user
        return attrs
    # To show the details of user (Overwriting)
    def to_representation(self, instance):
        response = super().to_representation(instance)
        response['user'] = UserSerializer(instance.user).data
        print(instance.user.role)
        return response

class FoodItemSerializer(serializers.ModelSerializer):
    class Meta:
      model = FoodItem
      fields = ['vendor', 'category', 'food_title', 'description', 'price', 'image', 'is_available']

    # def __init__(self, *arg, **kwargs):
    #     super(FoodItemSerializer, self).__init__(*arg, **kwargs)
    #     self.Meta.depth = 1

class CategorySerializer(serializers.ModelSerializer):
    fooditems = FoodItemSerializer(many=True, read_only=True)
    class Meta:
      model = Category
      fields = ['vendor', 'category_name', 'description', 'fooditems']

class VendorSerializer(serializers.ModelSerializer):
    categories = CategorySerializer(many=True, read_only=True)
    userprofile = UserProfileSerializer()
    class Meta:
      model = Vendor
      fields = ['categories', 'user', 'userprofile', 'vendor_name', 'vendor_slug', 'vendor_license', 'is_approved', 'created_at', 'modified_at']

class CartSerializer(serializers.ModelSerializer):
    user = UserSerializer()
    fooditem = FoodItemSerializer()

    class Meta:
        model = Cart
        fields = ['id', 'user', 'fooditem', 'quantity', 'created_at', 'updated_at']

# class AddToCartSerializer(serializers.Serializer):
#     status = serializers.CharField()
#     message = serializers.CharField()
#     cart_counter = serializers.IntegerField()
#     qty = serializers.IntegerField()
#     cart_amount = serializers.FloatField()

    # def to_representation(self, instance):
    #     cart_count = instance.get('cart_count', 0)
    #     subtotal = instance.get('subtotal', 0)
    #     tax = instance.get('tax', 0)
    #     grand_total = instance.get('grand_total', 0)

    #     representation = super(AddToCartSerializer, self).to_representation(instance)
    #     representation['cart_counter'] = cart_count
    #     representation['cart_amount'] = grand_total
    #     return representation