#################################################
### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
#################################################
# file to edit: ./nb/common.ipynb
from functools import partial
import os
exp_dir_name = 'xs_lib'
working_dir_tag = 'nb'

def write_env_if_not_exists(env_name, value,):
    """
    允许外部环境变量覆盖代码内的环境变量，特别是CUDA_VISIBLE_DEVICES
    """
    if env_name not in os.environ or os.environ[env_name] == "":
        print(f"xsthunder write_env_if_not_exists: set env %s=%s"%(env_name, value))
        os.environ[env_name] = value
    return os.environ[env_name]

import subprocess
from typing import List
def system_call(l : List[str]):
    """
    执行命令，打印并返回命令输出
    """
    return subprocess.check_output(l).decode("utf-8").strip()

def print_system_call(l : List[str], print_console=True):
    """
    执行命令，打印并返回命令输出
    """
    s = system_call(l)
    if print_console:
        print("print_system_call : ", ' '.join(l))
        ss = s.split('\n')
        ss = list(map(lambda x:"print_system_call: "+x, ss))
        print('\n'.join(ss))
    return s

def print_cuda_version (print_console=True):
    l = ["nvcc",  "--version"]
    s = system_call(l)
    s = s.split('\n')[3]
    if print_console:
        print("print_system_call: ", ' '.join(l))
        print("print_system_call: ", s)
    return s
print_gpu_list = partial(print_system_call, ["nvidia-smi", "-L"])

#https://stackoverflow.com/questions/15411967/how-can-i-check-if-code-is-executed-in-the-ipython-notebook
def isnotebook():
    try:
        shell = get_ipython().__class__.__name__
        if shell == 'ZMQInteractiveShell':
            return True   # Jupyter notebook or qtconsole
        elif shell == 'TerminalInteractiveShell':
            return False  # Terminal running IPython
        else:
            return False  # Other type (?)
    except NameError:
        return False      # Probably standard Python interpreter
IN_JUPYTER = isnotebook()

IN_TRAVIS=(os.getenv('TRAVIS', False) == 'true')
CLI_TEST=(os.getenv('CLI_TEST', False) == 'true')
def read_env_var(env_name, current_value):
    """
    从环境变量读值，覆盖代码内的值，如果是true, false，转换成布尔值
    """
    if env_name not in os.environ:
        return current_value
    env_var = os.getenv(env_name)
    p=partial(print, "read_env_var:")
    p(f"overwriting var by env {env_name} from {current_value} to {env_var}")
    if env_var == "true":
        p(f"convert true to bool True")
        env_var = True
    if env_var == "false":
        p(f"convert false to bool False")
        env_var = False
    return env_var

IN_TRAVIS=read_env_var("IN_TRAVIS", IN_TRAVIS)
IN_JUPYTER =read_env_var("IN_JUPYTER", IN_JUPYTER)

import os
print(IN_TRAVIS,'IN_TRAVIS' )
print(IN_JUPYTER , 'IN_JUPYTER ')
print(CLI_TEST , 'CLI_TEST ')

class _simple_tqdm:
    """
    for travis
    """
    def __init__(self, g):
        self.g = g
        try:
            l = len(g)
        except TypeError:
            l = '?'
        self.l = l

    def __iter__(self):
        for i,x in enumerate(self.g):
            print(f"({i}/{self.l})", end='')
            yield x

    def __len__(self):
        return self.l
try:
    if IN_JUPYTER:
        from tqdm.notebook import tqdm as notebook_tqdm
        tqdm = notebook_tqdm
    else :
        from tqdm import _tqdm
        tqdm = _tqdm.tqdm
except:
    tqdm = _simple_tqdm


for i in _simple_tqdm(range(10)):
    pass
for i in tqdm(range(10)):
    pass

def ex_sh_cmd(code):
    ip = get_ipython()
    # this depends on the environment where jupyter launchs
    ip.run_cell(code)

# todo
# 支持多级结构import, output，但可能不会用到
import json,re
from pathlib import Path
import io
import os
import os.path

class NBExporter:
    """
    single notebook exporter
    """
    def __init__(self, tag='export', prefix=''):
        self.tag = tag
        self.prefix = prefix

    def is_export(self, cell, ):
        tag = self.tag
        if cell['cell_type'] != 'code': return False
        src = cell['source']
        if len(src) == 0 or len(src[0]) < 7: return False
        #import pdb; pdb.set_trace()
        reg = f'^\s*#\s*{tag}\s*$'
        reg = re.compile(reg, re.IGNORECASE,)
        return re.match(reg, src[0], ) is not None


    def __call__(self, fname, to='../exp'):
        "Finds cells starting with `#export` and puts them into a new module"
        fname = Path(fname)
        to = Path(to)
        if(os.path.isdir(to)):
            # overwrite the defulat filename
            fname_out = f'{fname.stem.split(".")[0]}.py'
            fname_out = f'{self.prefix}{fname_out}'
            output_path = to/fname_out

        elif(str(to.absolute())[-3:]==".py"):
            output_path = to
        else:
            print("ERR a dir or a file ends with .py is needed")
            exit(1)

        if(os.path.exists(output_path)):print(f"overwriting {output_path}")

        main_dic = json.load(open(fname,'r',encoding="utf-8"))
        code_cells = [c for c in main_dic['cells'] if self.is_export(c)]
        module = f'''#################################################
### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
#################################################
# file to edit: ./nb/{fname.name}
'''

#         import pdb; pdb.set_trace()
        for cell in code_cells: module += ''.join(cell['source'][1:]) + '\n\n'
        # remove trailing spaces
        module = re.sub(r' +$', '', module, flags=re.MULTILINE)


        with io.open(output_path, "w", encoding="utf-8") as f:
            f.write(module[:-2])
        print(f"Converted {fname} to {output_path}")



class Export_notebook:
    """
    export notebook in a project
    """
    def __init__(self, dst, working_dir_tag = 'nb'):
        self.export_model = NBExporter()
        self.export_test = NBExporter('(test_)?export', prefix='test_')
        self.dst = dst
        self.working_dir_tag = working_dir_tag

    def sub_path(self, dst):
        rv = lambda s:s[::-1] # revserse string
        current = os.getcwd()
        tag = self.working_dir_tag
        assert tag in current, f"{tag, current}"

        current = rv(current)
        dst = rv(dst)
        tag = rv(tag)
        current = current.replace(tag, dst, 1)
        current = rv(current)

        return current

    def __call__(self, name,):
        assert IN_JUPYTER

        save_notebook()
        NOTEBOOK_EXTEND_NAME='.ipynb'
        if NOTEBOOK_EXTEND_NAME not in name:
            name += NOTEBOOK_EXTEND_NAME
        time.sleep(1)

        test_path = self.sub_path('tests')
        exp_path = self.sub_path(self.dst)

        # support import complie
        self.export_model(name, to=exp_path)
        self.export_test(name, to=test_path)

        save_notebook() # for exitting




# use those only in jupyter
import time

def save_notebook():
    ex_js_cmd('IPython.notebook.save_checkpoint();')

def restart_kernel():
    ex_js_cmd('IPython.notebook.kernel.restart();')

def kill_kernel():
    ex_js_cmd('IPython.notebook.kernel.kill();')

def ex_js_cmd(cmd):
    from IPython.display import display, Javascript
    display(Javascript(cmd))

save_and_export_notebook = Export_notebook(exp_dir_name, working_dir_tag = working_dir_tag )


def cli_main(fname, dst='./'):
    """
    cli interface to convert ipynb to py

    Examples:
        nb2py ./nb/common.ipynb ./ # export to ./common.py and ./test_common.py
        nb2py ./nb/common.ipynb ./common.export.test.py # export #export tag only
    Argument:
        fname: required. ipynb file to convert.
        dst: default to `./`. where to put the exported py file.  export both #test_export and #export cell if a dir is provided. export #export only if a file is provided.
    """
    assert fname[-6:]==".ipynb"

    export_model = NBExporter()
    export_test = NBExporter('(test_)?export', prefix='test_')
    if(os.path.isdir(dst)):
        export_model(fname, dst)
        export_test(fname, dst)
    else:
        export_model(fname, dst)

def fire_main():
    import fire
    fire.Fire(cli_main)


if __name__ == '__main__':
    if CLI_TEST:
        fire_main()
    elif IN_JUPYTER or IN_TRAVIS:
        pass
    else:
        fire_main()
#################################################
### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
#################################################
# file to edit: ./nb/common.ipynb
from functools import partial
import os
exp_dir_name = 'xs_lib'
working_dir_tag = 'nb'

def write_env_if_not_exists(env_name, value,):
    """
    允许外部环境变量覆盖代码内的环境变量，特别是CUDA_VISIBLE_DEVICES
    """
    if env_name not in os.environ or os.environ[env_name] == "":
        print(f"xsthunder write_env_if_not_exists: set env %s=%s"%(env_name, value))
        os.environ[env_name] = value
    return os.environ[env_name]

import subprocess
from typing import List
def system_call(l : List[str]):
    """
    执行命令，打印并返回命令输出
    """
    return subprocess.check_output(l).decode("utf-8").strip()

def print_system_call(l : List[str], print_console=True):
    """
    执行命令，打印并返回命令输出
    """
    s = system_call(l)
    if print_console:
        print("print_system_call : ", ' '.join(l))
        ss = s.split('\n')
        ss = list(map(lambda x:"print_system_call: "+x, ss))
        print('\n'.join(ss))
    return s

def print_cuda_version (print_console=True):
    l = ["nvcc",  "--version"]
    s = system_call(l)
    s = s.split('\n')[3]
    if print_console:
        print("print_system_call: ", ' '.join(l))
        print("print_system_call: ", s)
    return s
print_gpu_list = partial(print_system_call, ["nvidia-smi", "-L"])

#https://stackoverflow.com/questions/15411967/how-can-i-check-if-code-is-executed-in-the-ipython-notebook
def isnotebook():
    try:
        shell = get_ipython().__class__.__name__
        if shell == 'ZMQInteractiveShell':
            return True   # Jupyter notebook or qtconsole
        elif shell == 'TerminalInteractiveShell':
            return False  # Terminal running IPython
        else:
            return False  # Other type (?)
    except NameError:
        return False      # Probably standard Python interpreter
IN_JUPYTER = isnotebook()

IN_TRAVIS=(os.getenv('TRAVIS', False) == 'true')
CLI_TEST=(os.getenv('CLI_TEST', False) == 'true')
def read_env_var(env_name, current_value):
    """
    从环境变量读值，覆盖代码内的值，如果是true, false，转换成布尔值
    """
    if env_name not in os.environ:
        return current_value
    env_var = os.getenv(env_name)
    p=partial(print, "read_env_var:")
    p(f"overwriting var by env {env_name} from {current_value} to {env_var}")
    if env_var == "true":
        p(f"convert true to bool True")
        env_var = True
    if env_var == "false":
        p(f"convert false to bool False")
        env_var = False
    return env_var

IN_TRAVIS=read_env_var("IN_TRAVIS", IN_TRAVIS)
IN_JUPYTER =read_env_var("IN_JUPYTER", IN_JUPYTER)

import os
print(IN_TRAVIS,'IN_TRAVIS' )
print(IN_JUPYTER , 'IN_JUPYTER ')
print(CLI_TEST , 'CLI_TEST ')

class _simple_tqdm:
    """
    for travis
    """
    def __init__(self, g):
        self.g = g
        try:
            l = len(g)
        except TypeError:
            l = '?'
        self.l = l

    def __iter__(self):
        for i,x in enumerate(self.g):
            print(f"({i}/{self.l})", end='')
            yield x

    def __len__(self):
        return self.l
try:
    if IN_JUPYTER:
        from tqdm.notebook import tqdm as notebook_tqdm
        tqdm = notebook_tqdm
    else :
        from tqdm import _tqdm
        tqdm = _tqdm.tqdm
except:
    tqdm = _simple_tqdm


for i in _simple_tqdm(range(10)):
    pass
for i in tqdm(range(10)):
    pass

def ex_sh_cmd(code):
    ip = get_ipython()
    # this depends on the environment where jupyter launchs
    ip.run_cell(code)

# todo
# 支持多级结构import, output，但可能不会用到
import json,re
from pathlib import Path
import io
import os
import os.path

class NBExporter:
    """
    single notebook exporter
    """
    def __init__(self, tag='export', prefix=''):
        self.tag = tag
        self.prefix = prefix

    def is_export(self, cell, ):
        tag = self.tag
        if cell['cell_type'] != 'code': return False
        src = cell['source']
        if len(src) == 0 or len(src[0]) < 7: return False
        #import pdb; pdb.set_trace()
        reg = f'^\s*#\s*{tag}\s*$'
        reg = re.compile(reg, re.IGNORECASE,)
        return re.match(reg, src[0], ) is not None


    def __call__(self, fname, to='../exp'):
        "Finds cells starting with `#export` and puts them into a new module"
        fname = Path(fname)
        to = Path(to)
        if(os.path.isdir(to)):
            # overwrite the defulat filename
            fname_out = f'{fname.stem.split(".")[0]}.py'
            fname_out = f'{self.prefix}{fname_out}'
            output_path = to/fname_out

        elif(str(to.absolute())[-3:]==".py"):
            output_path = to
        else:
            print("ERR a dir or a file ends with .py is needed")
            exit(1)

        if(os.path.exists(output_path)):print(f"overwriting {output_path}")

        main_dic = json.load(open(fname,'r',encoding="utf-8"))
        code_cells = [c for c in main_dic['cells'] if self.is_export(c)]
        module = f'''#################################################
### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
#################################################
# file to edit: ./nb/{fname.name}
'''

#         import pdb; pdb.set_trace()
        for cell in code_cells: module += ''.join(cell['source'][1:]) + '\n\n'
        # remove trailing spaces
        module = re.sub(r' +$', '', module, flags=re.MULTILINE)


        with io.open(output_path, "w", encoding="utf-8") as f:
            f.write(module[:-2])
        print(f"Converted {fname} to {output_path}")



class Export_notebook:
    """
    export notebook in a project
    """
    def __init__(self, dst, working_dir_tag = 'nb'):
        self.export_model = NBExporter()
        self.export_test = NBExporter('(test_)?export', prefix='test_')
        self.dst = dst
        self.working_dir_tag = working_dir_tag

    def sub_path(self, dst):
        rv = lambda s:s[::-1] # revserse string
        current = os.getcwd()
        tag = self.working_dir_tag
        assert tag in current, f"{tag, current}"

        current = rv(current)
        dst = rv(dst)
        tag = rv(tag)
        current = current.replace(tag, dst, 1)
        current = rv(current)

        return current

    def __call__(self, name,):
        assert IN_JUPYTER

        save_notebook()
        NOTEBOOK_EXTEND_NAME='.ipynb'
        if NOTEBOOK_EXTEND_NAME not in name:
            name += NOTEBOOK_EXTEND_NAME
        time.sleep(1)

        test_path = self.sub_path('tests')
        exp_path = self.sub_path(self.dst)

        # support import complie
        self.export_model(name, to=exp_path)
        self.export_test(name, to=test_path)

        save_notebook() # for exitting




# use those only in jupyter
import time

def save_notebook():
    ex_js_cmd('IPython.notebook.save_checkpoint();')

def restart_kernel():
    ex_js_cmd('IPython.notebook.kernel.restart();')

def kill_kernel():
    ex_js_cmd('IPython.notebook.kernel.kill();')

def ex_js_cmd(cmd):
    from IPython.display import display, Javascript
    display(Javascript(cmd))

save_and_export_notebook = Export_notebook(exp_dir_name, working_dir_tag = working_dir_tag )


def cli_main(fname, dst='./'):
    """
    cli interface to convert ipynb to py

    Examples:
        nb2py ./nb/common.ipynb ./ # export to ./common.py and ./test_common.py
        nb2py ./nb/common.ipynb ./common.export.test.py # export #export tag only
    Argument:
        fname: required. ipynb file to convert.
        dst: default to `./`. where to put the exported py file.  export both #test_export and #export cell if a dir is provided. export #export only if a file is provided.
    """
    assert fname[-6:]==".ipynb"

    export_model = NBExporter()
    export_test = NBExporter('(test_)?export', prefix='test_')
    if(os.path.isdir(dst)):
        export_model(fname, dst)
        export_test(fname, dst)
    else:
        export_model(fname, dst)

def fire_main():
    import fire
    fire.Fire(cli_main)


if __name__ == '__main__':
    if CLI_TEST:
        fire_main()
    elif IN_JUPYTER or IN_TRAVIS:
        pass
    else:
        fire_main()
################################################# ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ### ################################################# # file to edit: ./nb/common.ipynb 允许外部环境变量覆盖代码内的环境变量，特别是CUDA_VISIBLE_DEVICES 执行命令，打印并返回命令输出 执行命令，打印并返回命令输出 #https://stackoverflow.com/questions/15411967/how-can-i-check-if-code-is-executed-in-the-ipython-notebook # Jupyter notebook or qtconsole # Terminal running IPython # Other type (?) # Probably standard Python interpreter 从环境变量读值，覆盖代码内的值，如果是true, false，转换成布尔值 for travis # this depends on the environment where jupyter launchs # todo # 支持多级结构import, output，但可能不会用到 single notebook exporter #import pdb; pdb.set_trace() #\s*{tag}\s*$' #export` and puts them into a new module" # overwrite the defulat filename ################################################# ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ### ################################################# # file to edit: ./nb/{fname.name} #         import pdb; pdb.set_trace() # remove trailing spaces export notebook in a project # revserse string # support import complie # for exitting # use those only in jupyter cli interface to convert ipynb to py      Examples:         nb2py ./nb/common.ipynb ./ # export to ./common.py and ./test_common.py         nb2py ./nb/common.ipynb ./common.export.test.py # export #export tag only     Argument:         fname: required. ipynb file to convert.         dst: default to `./`. where to put the exported py file.  export both #test_export and #export cell if a dir is provided. export #export only if a file is provided.