"""Provide tests for functions."""

# Authors: Federico Raimondo <f.raimondo@fz-juelich.de>
#          Leonard Sasse <l.sasse@fz-juelich.de>
#          Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL

import logging
import stat
from pathlib import Path
from typing import List, Tuple, Union

import pytest
from ruamel.yaml import YAML

import junifer.testing.registry  # noqa: F401
from junifer.api.functions import collect, queue, run
from junifer.datagrabber.base import BaseDataGrabber
from junifer.pipeline.registry import build

# Configure YAML class
yaml = YAML()
yaml.default_flow_style = False
yaml.allow_unicode = True
yaml.indent(mapping=2, sequence=4, offset=2)

# Define datagrabber
datagrabber = {
    "kind": "OasisVBMTestingDataGrabber",
}

# Define markers
markers = [
    {
        "name": "Schaefer1000x7_Mean",
        "kind": "ParcelAggregation",
        "parcellation": "Schaefer1000x7",
        "method": "mean",
    },
    {
        "name": "Schaefer1000x7_Std",
        "kind": "ParcelAggregation",
        "parcellation": "Schaefer1000x7",
        "method": "std",
    },
]

# Define storage
storage = {
    "kind": "SQLiteFeatureStorage",
}

def test_run_single_element(tmp_path: Path) -> None:
    """Test run function with single element.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.

    """
    # Create working directory
    workdir = tmp_path / "workdir_single"
    workdir.mkdir()
    # Create output directory
    outdir = tmp_path / "out"
    outdir.mkdir()
    # Create storage
    uri = outdir / "test.sqlite"
    storage["uri"] = uri  # type: ignore
    # Run operations
    run(
        workdir=workdir,
        datagrabber=datagrabber,
        markers=markers,
        storage=storage,
        elements=["sub-01"],
    )
    # Check files
    files = list(outdir.glob("*.sqlite"))
    assert len(files) == 1

def test_run_single_element_with_preprocessing(tmp_path: Path) -> None:
    """Test run function with single element and pre-processing.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.

    """
    # Create working directory
    workdir = tmp_path / "workdir_single_with_preprocess"
    workdir.mkdir()
    # Create output directory
    outdir = tmp_path / "out"
    outdir.mkdir()
    # Create storage
    uri = outdir / "test.sqlite"
    storage["uri"] = uri  # type: ignore
    # Run operations
    run(
        workdir=workdir,
        datagrabber={
            "kind": "PartlyCloudyTestingDataGrabber",
            "reduce_confounds": False,
        },
        markers=[
            {
                "name": "Schaefer100x17_mean_FC",
                "kind": "FunctionalConnectivityParcels",
                "parcellation": "Schaefer100x17",
                "agg_method": "mean",
            }
        ],
        storage=storage,
        preprocessors=[
            {
                "kind": "fMRIPrepConfoundRemover",
            }
        ],
        elements=["sub-01"],
    )
    # Check files
    files = list(outdir.glob("*.sqlite"))
    assert len(files) == 1

def test_run_multi_element(tmp_path: Path) -> None:
    """Test run function with multi element.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.

    """
    # Create working directory
    workdir = tmp_path / "workdir_multi"
    workdir.mkdir()
    # Create output directory
    outdir = tmp_path / "out"
    outdir.mkdir()
    # Create storage
    uri = outdir / "test.sqlite"
    storage["uri"] = uri  # type: ignore
    storage["single_output"] = False  # type: ignore
    # Run operations
    run(
        workdir=workdir,
        datagrabber=datagrabber,
        markers=markers,
        storage=storage,
        elements=["sub-01", "sub-03"],
    )
    # Check files
    files = list(outdir.glob("*.sqlite"))
    assert len(files) == 2

def test_run_multi_element_single_output(tmp_path: Path) -> None:
    """Test run function with multi element.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.

    """
    # Create working directory
    workdir = tmp_path / "workdir_multi"
    workdir.mkdir()
    # Create output directory
    outdir = tmp_path / "out"
    outdir.mkdir()
    # Create storage
    uri = outdir / "test.sqlite"
    storage["uri"] = uri  # type: ignore
    storage["single_output"] = True  # type: ignore
    # Run operations
    run(
        workdir=workdir,
        datagrabber=datagrabber,
        markers=markers,
        storage=storage,
        elements=["sub-01", "sub-03"],
    )
    # Check files
    files = list(outdir.glob("*.sqlite"))
    assert len(files) == 1
    assert files[0].name == "test.sqlite"

def test_run_and_collect(tmp_path: Path) -> None:
    """Test run and collect functions.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.

    """
    # Create working directory
    workdir = tmp_path / "workdir"
    workdir.mkdir()
    # Create output directory
    outdir = tmp_path / "out"
    outdir.mkdir()
    # Create storage
    uri = outdir / "test.sqlite"
    storage["uri"] = uri  # type: ignore
    storage["single_output"] = False  # type: ignore
    # Run operations
    run(
        workdir=workdir,
        datagrabber=datagrabber,
        markers=markers,
        storage=storage,
    )
    # Get datagrabber
    dg = build(
        step="datagrabber", name=datagrabber["kind"], baseclass=BaseDataGrabber
    )
    elements = dg.get_elements()  # type: ignore
    # This should create 10 files
    files = list(outdir.glob("*.sqlite"))
    assert len(files) == len(elements)
    # But the test.sqlite file should not exist
    assert not uri.exists()
    # Collect in storage
    collect(storage)
    # Now the file exists
    assert uri.exists()

def test_queue_correct_yaml_config(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
    caplog: pytest.LogCaptureFixture,
) -> None:
    """Test proper YAML config generation for queueing.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.
    monkeypatch : pytest.MonkeyPatch
        The pytest.MonkeyPatch object.
    caplog : pytest.LogCaptureFixture
        The pytest.LogCaptureFixture object.

    """
    with monkeypatch.context() as m:
        m.chdir(tmp_path)
        with caplog.at_level(logging.INFO):
            queue(
                config={
                    "with": "junifer.testing.registry",
                    "workdir": str(tmp_path.resolve()),
                    "datagrabber": datagrabber,
                    "markers": markers,
                    "storage": {"kind": "SQLiteFeatureStorage"},
                    "env": {
                        "kind": "conda",
                        "name": "junifer",
                    },
                    "mem": "8G",
                },
                kind="HTCondor",
                jobname="yaml_config_gen_check",
            )
            assert "Creating job in" in caplog.text
            assert "Writing YAML config to" in caplog.text
            assert "Queue done" in caplog.text

        generated_config_yaml_path = Path(
            tmp_path / "junifer_jobs" / "yaml_config_gen_check" / "config.yaml"
        )
        yaml_config = yaml.load(generated_config_yaml_path)
        # Check for correct YAML config generation
        assert all(
            key in yaml_config.keys()
            for key in [
                "with",
                "workdir",
                "datagrabber",
                "markers",
                "storage",
                "env",
                "mem",
            ]
        )
        assert "queue" not in yaml_config.keys()

def test_queue_invalid_job_queue(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    """Test queue function for invalid job queue.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.
    monkeypatch : pytest.MonkeyPatch
        The pytest.MonkeyPatch object.

    """
    with pytest.raises(ValueError, match="Unknown queue kind"):
        with monkeypatch.context() as m:
            m.chdir(tmp_path)
            queue(
                config={"elements": ["sub-001"]},
                kind="ABC",
            )

def test_queue_assets_disallow_overwrite(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    """Test overwrite prevention of queue files.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.
    monkeypatch : pytest.MonkeyPatch
        The pytest.MonkeyPatch object.

    """
    with pytest.raises(ValueError, match="Either delete the directory"):
        with monkeypatch.context() as m:
            m.chdir(tmp_path)
            # First generate assets
            queue(
                config={"elements": ["sub-001"]},
                kind="HTCondor",
                jobname="prevent_overwrite",
            )
            # Re-run to trigger error
            queue(
                config={"elements": ["sub-001"]},
                kind="HTCondor",
                jobname="prevent_overwrite",
            )

def test_queue_assets_allow_overwrite(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
    caplog: pytest.LogCaptureFixture,
) -> None:
    """Test overwriting of queue files.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.
    monkeypatch : pytest.MonkeyPatch
        The pytest.MonkeyPatch object.
    caplog : pytest.LogCaptureFixture
        The pytest.LogCaptureFixture object.

    """
    with monkeypatch.context() as m:
        m.chdir(tmp_path)
        # First generate assets
        queue(
            config={"elements": ["sub-001"]},
            kind="HTCondor",
            jobname="allow_overwrite",
        )
        with caplog.at_level(logging.INFO):
            # Re-run to overwrite
            queue(
                config={"elements": ["sub-001"]},
                kind="HTCondor",
                jobname="allow_overwrite",
                overwrite=True,
            )
            assert "Deleting existing job directory" in caplog.text

@pytest.mark.parametrize(
    "with_",
    [
        "a.py",
        ["a.py"],
        ["a.py", "b"],
    ],
)
def test_queue_with_imports(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
    caplog: pytest.LogCaptureFixture,
    with_: Union[str, List[str]],
) -> None:
    """Test queue with `with` imports.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.
    monkeypatch : pytest.MonkeyPatch
        The pytest.MonkeyPatch object.
    caplog : pytest.LogCaptureFixture
        The pytest.LogCaptureFixture object.
    with_ : str or list of str
        The parametrized imports.

    """
    with monkeypatch.context() as m:
        m.chdir(tmp_path)
        # Create test file, keeping it simple without conditionals
        (tmp_path / "a.py").touch()
        with caplog.at_level(logging.DEBUG):
            queue(
                config={"with": with_},
                kind="HTCondor",
                jobname="with_import_check",
                elements="sub-001",
            )
            assert "Copying" in caplog.text
            assert "Queue done" in caplog.text

        # Check that file is copied
        assert Path(
            tmp_path / "junifer_jobs" / "with_import_check" / "a.py"
        ).is_file()

@pytest.mark.parametrize(
    "elements",
    [
        "sub-001",
        ["sub-001"],
        ["sub-001", "sub-002"],
        ("sub-001", "ses-001"),
        [("sub-001", "ses-001")],
        [("sub-001", "ses-001"), ("sub-001", "ses-002")],
    ],
)
def test_queue_with_elements(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
    caplog: pytest.LogCaptureFixture,
    elements: Union[str, List[Union[str, Tuple[str]]], Tuple[str]],
) -> None:
    """Test queue with elements.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.
    monkeypatch : pytest.MonkeyPatch
        The pytest.MonkeyPatch object.
    caplog : pytest.LogCaptureFixture
        The pytest.LogCaptureFixture object.
    elements : str of list of str
        The parametrized elements for the queue.

    """
    with monkeypatch.context() as m:
        m.chdir(tmp_path)
        with caplog.at_level(logging.INFO):
            queue(
                config={},
                kind="HTCondor",
                elements=elements,
            )
            assert "Queue done" in caplog.text

def test_queue_without_elements(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
    caplog: pytest.LogCaptureFixture,
) -> None:
    """Test queue without elements.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.
    monkeypatch : pytest.MonkeyPatch
        The pytest.MonkeyPatch object.
    caplog : pytest.LogCaptureFixture
        The pytest.LogCaptureFixture object.

    """
    with monkeypatch.context() as m:
        m.chdir(tmp_path)
        with caplog.at_level(logging.INFO):
            queue(
                config={"datagrabber": datagrabber},
                kind="SLURM",
            )
            assert "Queue done" in caplog.text

def test_queue_condor_invalid_python_env(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    """Test invalid Python environment check for HTCondor.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.
    monkeypatch : pytest.MonkeyPatch
        The pytest.MonkeyPatch object.

    """
    with pytest.raises(ValueError, match="Unknown env kind"):
        with monkeypatch.context() as m:
            m.chdir(tmp_path)
            queue(
                config={"elements": "sub-001"},
                kind="HTCondor",
                env={"kind": "galaxy"},
            )

def test_queue_condor_conda_python(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
    caplog: pytest.LogCaptureFixture,
) -> None:
    """Test conda Python environment check for HTCondor.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.
    monkeypatch : pytest.MonkeyPatch
        The pytest.MonkeyPatch object.
    caplog : pytest.LogCaptureFixture
        The pytest.LogCaptureFixture object.

    """
    with monkeypatch.context() as m:
        m.chdir(tmp_path)
        with caplog.at_level(logging.INFO):
            queue(
                config={"elements": "sub-001"},
                kind="HTCondor",
                jobname="conda_env_check",
                env={"kind": "conda", "name": "conda-env"},
            )
            assert "Copying" in caplog.text
            fname = (
                tmp_path / "junifer_jobs" / "conda_env_check" / "run_conda.sh"
            )
            assert fname.is_file()
            assert stat.S_IMODE(fname.stat().st_mode) & stat.S_IEXEC != 0

def test_queue_condor_conda_pre_run_python(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
    caplog: pytest.LogCaptureFixture,
) -> None:
    """Test conda Python environment check for HTCondor.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.
    monkeypatch : pytest.MonkeyPatch
        The pytest.MonkeyPatch object.
    caplog : pytest.LogCaptureFixture
        The pytest.LogCaptureFixture object.

    """
    with monkeypatch.context() as m:
        m.chdir(tmp_path)
        with caplog.at_level(logging.INFO):
            queue(
                config={"elements": "sub-001"},
                kind="HTCondor",
                jobname="conda_env_check",
                env={"kind": "conda", "name": "conda-env"},
                pre_run="echo testing",
            )
            assert "Copying" in caplog.text

            fname = (
                tmp_path / "junifer_jobs" / "conda_env_check" / "run_conda.sh"
            )
            assert fname.is_file()
            assert stat.S_IMODE(fname.stat().st_mode) & stat.S_IEXEC != 0

            fname = (
                tmp_path / "junifer_jobs" / "conda_env_check" / "pre_run.sh"
            )
            assert fname.is_file()
            assert stat.S_IMODE(fname.stat().st_mode) & stat.S_IEXEC != 0

def test_queue_condor_venv_python(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
    caplog: pytest.LogCaptureFixture,
) -> None:
    """Test venv Python environment check for HTCondor.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.
    monkeypatch : pytest.MonkeyPatch
        The pytest.MonkeyPatch object.
    caplog : pytest.LogCaptureFixture
        The pytest.LogCaptureFixture object.

    """
    with monkeypatch.context() as m:
        m.chdir(tmp_path)
        with caplog.at_level(logging.INFO):
            queue(
                config={"elements": "sub-001"},
                kind="HTCondor",
                env={"kind": "venv", "name": "venv-env"},
            )
            # TODO: needs implementation for testing

@pytest.mark.parametrize(
    "elements, env, mem, cpus, disk, collect",
    [
        (
            ["sub-001"],
            {"kind": "conda", "name": "conda-env"},
            "4G",
            4,
            "4G",
            "yes",
        ),
        (
            ["sub-001"],
            {"kind": "conda", "name": "conda-env"},
            "4G",
            4,
            "4G",
            "on_success_only",
        ),
        (
            ["sub-001"],
            {"kind": "venv", "name": "venv-env"},
            "8G",
            8,
            "8G",
            "no",
        ),
        (["sub-001"], {"kind": "local"}, "12G", 12, "12G", "yes"),
    ],
)
def test_queue_condor_assets_generation(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
    caplog: pytest.LogCaptureFixture,
    elements: str,
    env: str,
    mem: str,
    cpus: int,
    disk: str,
    collect: str,
) -> None:
    """Test HTCondor generated assets.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.
    monkeypatch : pytest.MonkeyPatch
        The pytest.MonkeyPatch object.
    caplog : pytest.LogCaptureFixture
        The pytest.LogCaptureFixture object.
    elements : str
        The parametrized element names.
    env : dict
        The parametrized env names.
    mem : str
        The parametrized memory size.
    cpus : int
        The parametrized CPUs.
    disk : str
        The parametrized disk size.
    collect : str
        The parametrized collect option.

    """
    jobname = "condor_assets_gen_check"
    with monkeypatch.context() as m:
        m.chdir(tmp_path)
        with caplog.at_level(logging.INFO):
            queue(
                config={"elements": elements},
                kind="HTCondor",
                jobname=jobname,
                env=env,
                mem=mem,
                cpus=cpus,
                disk=disk,
                collect=collect,
            )

            # Check log directory creation
            assert Path(tmp_path / "junifer_jobs" / jobname / "logs").is_dir()

            run_submit_file_path = Path(
                tmp_path / "junifer_jobs" / jobname / f"run_{jobname}.submit"
            )
            # Check junifer run submit file
            assert run_submit_file_path.is_file()
            # Read run submit file to check if resources are correct
            with open(run_submit_file_path) as f:
                for line in f.read().splitlines():
                    if "request_cpus" in line:
                        assert int(line.split("=")[1].strip()) == cpus
                    if "request_memory" in line:
                        assert line.split("=")[1].strip() == mem
                    if "request_disk" in line:
                        assert line.split("=")[1].strip() == disk

            # Check junifer collect submit file
            assert Path(
                tmp_path
                / "junifer_jobs"
                / jobname
                / f"collect_{jobname}.submit"
            ).is_file()

            dag_file_path = Path(
                tmp_path / "junifer_jobs" / jobname / f"{jobname}.dag"
            )
            # Check junifer dag file
            assert dag_file_path.is_file()
            # Read dag file to check if collect job is found
            element_count = 0
            has_collect_job = False
            has_final_collect_job = False
            with open(dag_file_path) as f:
                for line in f.read().splitlines():
                    if "JOB" in line:
                        element_count += 1
                    if "collect" in line:
                        has_collect_job = True
                    if "FINAL" in line:
                        has_final_collect_job = True

            if collect == "yes":
                assert len(elements) == element_count
                assert has_collect_job is True
                assert has_final_collect_job is True
            elif collect == "on_success_only":
                assert len(elements) == element_count - 1
                assert has_collect_job is True
                assert has_final_collect_job is False
            else:
                assert len(elements) == element_count
                assert has_collect_job is False

            if has_final_collect_job is True:
                pre_collect_fname = Path(
                    tmp_path / "junifer_jobs" / jobname / "collect_pre.sh"
                )
                assert pre_collect_fname.exists()
                assert (
                    stat.S_IMODE(pre_collect_fname.stat().st_mode)
                    & stat.S_IEXEC
                    != 0
                )

            # Check submit log
            assert (
                "HTCondor job files created, to submit the job, run"
                in caplog.text
            )

def test_queue_condor_extra_preamble(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    """Test HTCondor extra preamble addition.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.
    monkeypatch : pytest.MonkeyPatch
        The pytest.MonkeyPatch object.

    """
    jobname = "condor_extra_preamble_check"
    extra_preamble = "FOO = BAR"
    with monkeypatch.context() as m:
        m.chdir(tmp_path)
        queue(
            config={"elements": ["sub-001"]},
            kind="HTCondor",
            jobname=jobname,
            extra_preamble=extra_preamble,
        )

        # Check extra preamble in run submit file
        run_submit_file_path = Path(
            tmp_path / "junifer_jobs" / jobname / f"run_{jobname}.submit"
        )
        with open(run_submit_file_path) as f:
            for line in f.read().splitlines():
                if "FOO" in line:
                    assert line.strip() == extra_preamble

        # Check extra preamble in collect submit file
        collect_submit_file_path = Path(
            tmp_path / "junifer_jobs" / jobname / f"collect_{jobname}.submit"
        )
        with open(collect_submit_file_path) as f:
            for line in f.read().splitlines():
                if "FOO" in line:
                    assert line.strip() == extra_preamble

def test_queue_condor_submission_fail(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
    caplog: pytest.LogCaptureFixture,
) -> None:
    """Test HTCondor job submission failure.

    Parameters
    ----------
    tmp_path : pathlib.Path
        The path to the test directory.
    monkeypatch : pytest.MonkeyPatch
        The pytest.MonkeyPatch object.
    caplog : pytest.LogCaptureFixture
        The pytest.LogCaptureFixture object.

    """
    with pytest.raises(
        FileNotFoundError,
        match="No such file or directory: 'condor_submit_dag'",
    ):
        with monkeypatch.context() as m:
            m.chdir(tmp_path)
            with caplog.at_level(logging.INFO):
                queue(
                    config={"elements": ["sub-001"]},
                    kind="HTCondor",
                    jobname="condor_job_submission_fail",
                    submit=True,
                )
            # Check submit log
            assert "Submitting HTCondor job" in caplog.text

@pytest.mark.skip(reason="SLURM not installed on system.")
def test_queue_slurm() -> None:
    """Test job queueing in SLURM."""
    pass


__author__ = "Norman Fomferra, Brockmann Consult GmbH"
__copyright__ = "Copyright 2015 Brockmann Consult GmbH"
__license__ = "Apache 2.0"
__version__ = "0.9-SNAPSHOT"

import sys
import os
import os.path
import platform
import subprocess
import shutil
import glob

import ez_setup
ez_setup.use_setuptools()

from setuptools import setup
from setuptools.extension import Extension
from distutils import log

base_dir = os.path.dirname(os.path.abspath(__file__))
src_main_c_dir = os.path.join(base_dir, 'src', 'main', 'c')
src_test_py_dir = os.path.join(base_dir, 'src', 'test', 'python')

import jpyutil

print('Using ' + jpyutil.__file__)

do_maven = False
if '--maven' in sys.argv:
    do_maven = True
    sys.argv.remove('--maven')
else:
    print('Note that you can use non-standard global option [--maven] '
          'to force a Java Maven build for the jpy Java API')

sources = [
    os.path.join(src_main_c_dir, 'jpy_module.c'),
    os.path.join(src_main_c_dir, 'jpy_diag.c'),
    os.path.join(src_main_c_dir, 'jpy_conv.c'),
    os.path.join(src_main_c_dir, 'jpy_compat.c'),
    os.path.join(src_main_c_dir, 'jpy_jtype.c'),
    os.path.join(src_main_c_dir, 'jpy_jarray.c'),
    os.path.join(src_main_c_dir, 'jpy_jobj.c'),
    os.path.join(src_main_c_dir, 'jpy_jmethod.c'),
    os.path.join(src_main_c_dir, 'jpy_jfield.c'),
    os.path.join(src_main_c_dir, 'jni/org_jpy_PyLib.c'),
]

headers = [
    os.path.join(src_main_c_dir, 'jpy_module.h'),
    os.path.join(src_main_c_dir, 'jpy_diag.h'),
    os.path.join(src_main_c_dir, 'jpy_conv.h'),
    os.path.join(src_main_c_dir, 'jpy_compat.h'),
    os.path.join(src_main_c_dir, 'jpy_jtype.h'),
    os.path.join(src_main_c_dir, 'jpy_jarray.h'),
    os.path.join(src_main_c_dir, 'jpy_jobj.h'),
    os.path.join(src_main_c_dir, 'jpy_jmethod.h'),
    os.path.join(src_main_c_dir, 'jpy_jfield.h'),
    os.path.join(src_main_c_dir, 'jni/org_jpy_PyLib.h'),
]

# Python unit tests that just use Java runtime classes (rt.jar)
python_java_rt_tests = [
    os.path.join(src_test_py_dir, 'jpy_rt_test.py'),
    os.path.join(src_test_py_dir, 'jpy_mt_test.py'),
    os.path.join(src_test_py_dir, 'jpy_diag_test.py'),
    # os.path.join(src_test_py_dir, 'jpy_perf_test.py'),
]

# Python unit tests that require jpy test fixture classes to be accessible
# via JRE system property '-Djava.class.path=target/test-classes'
python_java_jpy_tests = [
    os.path.join(src_test_py_dir, 'jpy_array_test.py'),
    os.path.join(src_test_py_dir, 'jpy_field_test.py'),
    os.path.join(src_test_py_dir, 'jpy_retval_test.py'),
    os.path.join(src_test_py_dir, 'jpy_exception_test.py'),
    os.path.join(src_test_py_dir, 'jpy_overload_test.py'),
    os.path.join(src_test_py_dir, 'jpy_typeconv_test.py'),
    os.path.join(src_test_py_dir, 'jpy_typeres_test.py'),
    os.path.join(src_test_py_dir, 'jpy_modretparam_test.py'),
    os.path.join(src_test_py_dir, 'jpy_gettype_test.py'),
]

# e.g. jdk_home_dir = '/home/marta/jdk1.7.0_15'
jdk_home_dir = jpyutil.find_jdk_home_dir()
if jdk_home_dir is None:
    log.error('Error: environment variable "JAVA_HOME" must be set to a JDK (>= v1.7) installation directory')
    exit(1)

log.info('Building a %s-bit library for a %s system with JDK at %s' % (
    '64' if jpyutil.PYTHON_64BIT else '32', platform.system(), jdk_home_dir))

jvm_dll_file = jpyutil.find_jvm_dll_file(jdk_home_dir)
if not jvm_dll_file:
    log.error('Error: Cannot find any JVM shared library')
    exit(1)

lib_dir = os.path.join(base_dir, 'lib')
jpy_jar_file = os.path.join(lib_dir, 'jpy.jar')

if do_maven:

    #
    # Java packaging with Maven
    #

    if not os.getenv('JAVA_HOME'):
        # make sure Maven uses the same JDK which we have used to compile and link the C-code
        os.environ['JAVA_HOME'] = jdk_home_dir

    mvn_goal = 'package'
    log.info("Executing Maven goal '" + mvn_goal + "'")
    code = subprocess.call(['mvn', 'clean', mvn_goal, '-DskipTests'], shell=platform.system() == 'Windows')
    if code:
        exit(code)

    #
    # Copy JAR results to lib/*.jar
    #

    if not os.path.exists(lib_dir):
        os.mkdir(lib_dir)
    target_dir = os.path.join(base_dir, 'target')
    jar_files = glob.glob(os.path.join(target_dir, '*.jar'))
    jar_files = [f for f in jar_files if not (f.endswith('-sources.jar') or f.endswith('-javadoc.jar'))]
    if not jar_files:
        log.error('Maven did not generate any JAR artifacts')
        exit(1)
    for jar_file in jar_files:
        log.info("Copying " + jar_file + " -> " + lib_dir + "")
        shutil.copy(jar_file, lib_dir)

#
# Prepare setup arguments and call setup
#

jvm_dll_dir = os.path.dirname(jvm_dll_file)

include_dirs = [src_main_c_dir, os.path.join(jdk_home_dir, 'include')]
library_dirs = [jvm_dll_dir]
libraries = [jpyutil.JVM_LIB_NAME]
define_macros = []
extra_link_args = []
extra_compile_args = []

if platform.system() == 'Windows':
    define_macros += [('WIN32', '1')]
    include_dirs += [os.path.join(jdk_home_dir, 'include', 'win32')]
    library_dirs += [os.path.join(jdk_home_dir, 'lib')]
elif platform.system() == 'Linux':
    include_dirs += [os.path.join(jdk_home_dir, 'include', 'linux')]
    libraries += ['dl']
    extra_link_args += ['-Xlinker', '-rpath', jvm_dll_dir]
elif platform.system() == 'Darwin':
    include_dirs += [os.path.join(jdk_home_dir, 'include', 'darwin')]
    library_dirs += [os.path.join(sys.exec_prefix, 'lib')]
    extra_link_args += ['-Xlinker', '-rpath', jvm_dll_dir]

with open('README.rst') as file:
    long_description = file.read()

with open('CHANGES.txt') as file:
    changelog = file.read()

dist = setup(name='jpy',
             description='Bi-directional Python-Java bridge',
             long_description=long_description + '\n\n' + changelog,
             version=__version__,
             platforms='Windows, Linux, Darwin',
             author=__author__,
             author_email='norman.fomferra@brockmann-consult.de',
             maintainer='Brockmann Consult GmbH',
             maintainer_email='norman.fomferra@brockmann-consult.de',
             license=__license__,
             url='https://github.com/bcdev/jpy',
             download_url='https://pypi.python.org/pypi/jpy/' + __version__,
             py_modules=['jpyutil'],
             package_data={'': [jpy_jar_file]},
             ext_modules=[Extension('jpy',
                                    sources=sources,
                                    depends=headers,
                                    include_dirs=include_dirs,
                                    library_dirs=library_dirs,
                                    libraries=libraries,
                                    extra_link_args=extra_link_args,
                                    extra_compile_args=extra_compile_args,
                                    define_macros=define_macros),
                          Extension('jdl',
                                    sources=[os.path.join(src_main_c_dir, 'jni/org_jpy_DL.c')],
                                    depends=[os.path.join(src_main_c_dir, 'jni/org_jpy_DL.h')],
                                    include_dirs=include_dirs,
                                    library_dirs=library_dirs,
                                    libraries=libraries,
                                    extra_link_args=extra_link_args,
                                    extra_compile_args=extra_compile_args,
                                    define_macros=define_macros),
                          ],
             classifiers=[
                 # How mature is this project? Common values are
                 #   3 - Alpha
                 #   4 - Beta
                 #   5 - Production/Stable
                 'Development Status :: 4 - Beta',

                 # Indicate who your project is intended for
                 'Intended Audience :: Developers',

                 # Pick your license as you wish (should match "license" above)
                 'License :: OSI Approved :: Apache 2 License',

                 # Specify the Python versions you support here. In particular, ensure
                 # that you indicate whether you support Python 2, Python 3 or both.
                 'Programming Language :: Python :: 2',
                 'Programming Language :: Python :: 2.7',
                 'Programming Language :: Python :: 3',
                 'Programming Language :: Python :: 3.3',
                 'Programming Language :: Python :: 3.4',
             ]
             )

#import pprint
#pprint.pprint(dist)
#pprint.pprint(dist.__dict__)
#pprint.pprint(dist.commands)
#pprint.pprint(dist.command_obj)
#pprint.pprint(dist.command_obj['build'].__dict__)
#pprint.pprint(dist.command_obj['install'].__dict__)
#pprint.pprint(dist.command_obj['install_lib'].__dict__)
#pprint.pprint(dist.command_obj['bdist_egg'].__dict__)
#pprint.pprint(dist.command_obj['egg_info'].__dict__)

#
# Continue with custom setup if 'build' step is included in commands
#

if dist.commands and len(dist.commands) > 0 \
        and dist.command_obj and len(dist.command_obj) > 0 \
        and 'clean' not in dist.command_obj \
        and 'build' in dist.command_obj:

    #
    # Get build directory (whose content we'll zip and in which we test)
    #

    build_dir = dist.command_obj['build'].build_lib
    if not os.path.exists(build_dir):
        log.error("Missing build directory '" + build_dir + "'")
        exit(1)

    #
    # Get install directory
    #

    install_dir = None
    if 'install' in dist.command_obj:
        install_dir = dist.command_obj['install'].install_lib
        if not os.path.exists(install_dir):
            log.warn("Missing install directory '" + install_dir + "'")
            install_dir = None

    #
    # Get egg (archive/directory) name
    #

    egg_name = None
    if 'bdist_egg' in dist.command_obj:
        egg_output = dist.command_obj['bdist_egg'].egg_output
        if egg_output:
            egg_name = os.path.basename(dist.command_obj['bdist_egg'].egg_output)

    #
    # Write jpy configuration files to target directories
    #

    def _write_jpy_config(target_dir, jvm_dll_file, jdk_home_dir):
        log.info('Writing jpy configuration to ' + target_dir)
        return subprocess.call([sys.executable,
                                os.path.join(target_dir, 'jpyutil.py'),
                                '--jvm_dll', jvm_dll_file,
                                '--java_home', jdk_home_dir,
                                '--log_level', 'DEBUG',
                                '--req_java',
                                '--req_py'])

    code = _write_jpy_config(build_dir, jvm_dll_file, jdk_home_dir)
    if code != 0:
        exit(code)
    if install_dir and install_dir != build_dir:
        if egg_name:
            egg_dir = os.path.join(install_dir, egg_name)
            if os.path.exists(os.path.join(egg_dir, 'jpyutil.py')):
                code = _write_jpy_config(egg_dir, jvm_dll_file, jdk_home_dir)
                if code != 0:
                    exit(code)
        else:
            if os.path.exists(os.path.join(install_dir, 'jpyutil.py')):
                code = _write_jpy_config(install_dir, jvm_dll_file, jdk_home_dir)
                if code != 0:
                    exit(code)

    #
    # Ensure that the build directory is on Python's 'sys.path' when invoking
    # Python via subprocess.call([sys.executable, ...]) from this script.
    #

    class EnvVar:
        def __init__(self, name):
            self.name = name
            self.changed = False
            self.saved_value = self.get_value()

        def __del__(self):
            self.restore()

        def get_value(self):
            return os.environ.get(self.name)

        def set_value(self, value):
            self._set_value(value)
            self.changed = True

        def _set_value(self, value):
            log.info("setting environment variable '" + self.name + "' to " + repr(value))
            if value:
                os.environ[self.name] = value
            else:
                os.environ.pop(self.name)

        def prepend_path(self, path):
            old_value = self.get_value()
            new_value = os.pathsep.join([path, old_value]) if old_value else path
            self.set_value(new_value)

        def restore(self):
            if self.changed:
                self._set_value(self.saved_value)
                self.changed = False

    pp = EnvVar('PYTHONPATH')

    #
    # Python unit tests with Java runtime classes
    #

    log.info('Executing Python unit tests (against Java runtime classes)...')
    pp.prepend_path(build_dir)
    fails = jpyutil._execute_python_scripts(python_java_rt_tests)
    pp.restore()
    if fails > 0:
        log.error(str(fails) + ' Python unit test(s) failed. Installation is likely broken.')
        exit(1)

    if do_maven:

        #
        # Python unit tests with jpy test classes built by Maven
        #

        log.info('Executing Python unit tests (against jpy test classes)...')
        pp.prepend_path(build_dir)
        fails = jpyutil._execute_python_scripts(python_java_jpy_tests)
        pp.restore()
        if fails > 0:
            log.error(str(fails) + ' Python unit test(s) failed. Installation is likely broken.')
            exit(1)

        #
        # Java install or test with Maven. Goal 'package' has already been achieved.
        #

        if 'install' in dist.commands:
            mvn_goal = 'install'
        else:
            mvn_goal = 'test'
        mvn_args = '-DargLine=-Xmx512m -Djpy.config=' + os.path.join(build_dir,
                                                                     'jpyconfig.properties') + ' -Djpy.debug=true'
        log.info("Executing Maven goal " + repr(mvn_goal) + " with arg line " + repr(mvn_args))
        code = subprocess.call(['mvn', mvn_goal, mvn_args], shell=platform.system() == 'Windows')
        if code:
            exit(code)

    if install_dir:
        log.info("")
        log.info("jpy has been successfully installed into '" + install_dir + "'.")
        log.info("To configure jpy with respect to given JDK/JRE please use the jpyutil tool/module.")


def get_even_list(nums = []):
    new_list = []
    for index,item in enumerate(nums):
        if item % 2 == 0:
            # print(item)
            new_list.append(item)
    return new_list

even_list = get_even_list([1, 2, 5, -10, 9, 6])

if set(even_list) == set([2, -10, 6]):
    print("Your function is correct")
else:
    print("Ooops, bugs detected")


import re
import random
from itertools import islice

# Leitura dos Dados
# ----------------------------------------------------------------------

# Função utilizada para abrir um aquivo, ler e retornar as informações de digits e labels
def read_data(digits, labels, filename='digits.data'):

    with open('digits.data', 'r') as file_opened:
        file = file_opened.read()

    pixels = []
    pixel = ''
    count = 0

    is_digit = True
    label = ''

    file = iter(file)
    for n in file:

        if is_digit:
            if n==' ' or n=='\n':
                pixels.append(pixel)
                pixel=''
                count += 1
            else:
                pixel += n
                next(islice(file, 4, 5), '')

            if count == 256:
                digit = pixels
                pixels = []
                count = 0
                is_digit = False

        else:
            if count == 20:
                label = re.sub(' ', '', label)
                count = 0
                is_digit = True
            else:
                label += n
                count += 1

        if n == '\n':
            digits.append(digit)
            digit = []

            labels.append(label)
            label = ''

# Interpreta e exibe no terminal os dígitos, somente para facilitar a visualização
def show_digit(data, height=16, width=16):
    i = 0
    for h in range(height):
        for w in range(width):
            if data[i]=='1' or data[i]==1:
                print('#', end='')
            else:
                print('.', end='')
            i+=1
        print()

# Interpreta o valor de label
def show_label(label):
    i = label.index('1')
    print('label: ', i)
    return i

# Preparação dos Dados
# ----------------------------------------------------------------------

# Separa os dados e labels em conjuntos de treinamento e teste
def train_test_split(X, Y, test_size=0.2, shuffle=True):

    if shuffle:
        c = list(zip(X, Y))
        random.shuffle(c)
        _x, _y = zip(*c)
    else:
        _x = X
        _y = Y

    index = int(len(_y)*test_size)

    x_test = _x[:index]
    y_test = _y[:index]

    x_train = _x[index:]
    y_train = _y[index:]

    return x_train, x_test, y_train, y_test

# Cálculo Adicionais
# ----------------------------------------------------------------------

# Calcula a acurácia da previsão

def accuracy(real, predicted):

    V = 0
    F = 0

    for r, p in zip(real, predicted):
        if r==p:
            V += 0
        else:
            F += 0

    return V/(V+F)


"""Creating VideoModel routers in api/v1/videos"""
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session

from api_playlist.shared.database import get_session
from api_playlist.shared.exceptions import NotFound
from api_playlist.video.models.schemas import (
    VideoListModel,
    VideoRequestModel,
    VideoResponseModel,
)
from api_playlist.video.models.video_model import Video

router = APIRouter(prefix='/api/v1/videos')

@router.get('', response_model=VideoListModel, status_code=200)
def list_videos(
    db: Session = Depends(get_session),
) -> VideoListModel:
    videos = db.query(Video).all()
    return {'videos': videos}

@router.get('/{video_id}', response_model=VideoResponseModel, status_code=200)
def get_video(
    video_id: int, db: Session = Depends(get_session)
) -> VideoResponseModel:
    return search_video_by_id(video_id, db)

@router.post('', response_model=VideoResponseModel, status_code=201)
def create_video(
    video_request: VideoRequestModel, db: Session = Depends(get_session)
) -> VideoResponseModel:

    video = Video(**video_request.model_dump())

    db.add(video)
    db.commit()
    db.refresh(video)
    return video

@router.put('/{video_id}', response_model=VideoResponseModel, status_code=200)
def update_video(
    video_id: int,
    video_request: VideoRequestModel,
    db: Session = Depends(get_session),
) -> VideoResponseModel:
    video = search_video_by_id(video_id, db)
    video.title = video_request.title
    video.description = video_request.description
    video.url = video_request.url

    db.add(video)
    db.commit()
    db.refresh(video)
    return video

@router.delete('/{video_id}', status_code=204)
def delete_video(video_id: int, db: Session = Depends(get_session)) -> None:
    video = search_video_by_id(video_id, db)
    db.delete(video)
    db.commit()

def search_video_by_id(
    video_id: int, db: Session = Depends(get_session)
) -> VideoResponseModel:
    video = db.query(Video).get(video_id)

    if video is None:
        raise NotFound('Video')

    return video


import tensorflow as tf
import tensorflow.contrib.slim as slim

from tensorflow.contrib.layers.python.layers.initializers import variance_scaling_initializer

def InfoGenerator(x,
                  c,
                is_training=True,
                reuse=False,
                name="info_generator"):
    """
    3D inference module. 3 MLP layers (last is the output)
    With dropout  on first 2.
    Input:
    - x: N x [|img_feat|, |3D_param|]
    - reuse: bool

    Outputs:
    - 3D params: N x num_output
      if orthogonal:
           either 85: (3 + 24*3 + 10) or 109 (3 + 24*4 + 10) for factored axis-angle representation
      if perspective:
          86: (f, tx, ty, tz) + 24*3 + 10, or 110 for factored axis-angle.
    - variables: tf variables
    """
    batch_size=x.shape[0].value
    x_nc=x.shape[-1].value

    def UpBlock(input,is_training,name=None,reuse=False):
        height,width,nc=input.shape[1],input.shape[2],input.shape[3]
        with tf.variable_scope(name, reuse=reuse) as scope:
            input=tf.image.resize_bilinear(input,[height*2,width*2])
            input=slim.conv2d(input,nc*2,kernel_size=3,stride=1)
            input=slim.batch_norm(input,is_training=is_training)
            return input[:,:,:,:nc]*tf.nn.sigmoid(input[:,:,:,nc:])

    def ResBlock(input,is_training,name=None,reuse=False):
        height,width,nc=input.shape[1].value,input.shape[2].value,input.shape[3].value

        with tf.variable_scope(name, reuse=reuse) as scope:
            input_2=slim.conv2d(input,2*nc,kernel_size=3)
            input_2=slim.batch_norm(input_2,is_training=is_training)
            input_2=input_2[:,:,:,:nc]*tf.nn.sigmoid(input_2[:,:,:,nc:])
            input_2 = slim.conv2d(input_2, nc,kernel_size=3)
            input_2 = slim.batch_norm(input_2,is_training=is_training)
            return input+input_2

    if reuse:
        print('Reuse is on!')
    with tf.variable_scope(name, reuse=reuse) as scope:
        #GLU
        c=slim.fully_connected(c,num_outputs=64*4*4*2)
        c=slim.batch_norm(c,is_training=is_training)
        c=c[:,:64*4*4]*tf.nn.sigmoid(c[:,64*4*4:])
        c=tf.reshape(c,[batch_size,4,4,64])
        #size 8x8
        c=UpBlock(c,is_training=is_training,name='UpBlock_0')
        c = UpBlock(c, is_training=is_training, name='UpBlock_1')
        c = UpBlock(c, is_training=is_training, name='UpBlock_2')
        c = UpBlock(c, is_training=is_training, name='UpBlock_3')
        #size 64x64

        #resize x
        x=tf.image.resize_bilinear(x,[256,256])
        x=slim.conv2d(x,x_nc*2,kernel_size=3,stride=2)
        x=slim.batch_norm(x,is_training=is_training)
        x = slim.conv2d(x, x_nc * 4, kernel_size=3, stride=2)
        x = slim.batch_norm(x,is_training=is_training)

        x_and_c=tf.concat([x,c],-1)
        for i in range(3):
            x_and_c=ResBlock(x_and_c,is_training=is_training,name='resblock_%d'%i)

        out=slim.conv2d_transpose(x_and_c,64/2,3,2)
        out=slim.batch_norm(out,is_training=is_training)
        out = slim.conv2d_transpose(out, 64 / 4, 3, 2)
        out = slim.batch_norm(out, is_training=is_training)
        out = slim.conv2d_transpose(out,64/8,3,2)
        out = slim.batch_norm(out,is_training = is_training)

        mask_out=slim.conv2d(out,1,3,activation_fn=slim.nn.sigmoid)
        fore_out=slim.conv2d(out,3,3,activation_fn=slim.nn.tanh)

    variables = tf.contrib.framework.get_variables(scope)
    return mask_out,fore_out, variables


from ..utilities import utils_func

def find_unit_core_depofacies(unit_index, data_list):
    codes = []
    for u in unit_index:
        code = data_list[u]["Core_depofacies"]
        codes.append(code)
    return codes

def handle_point(current_point, radius):
    current_point = int(current_point)
    if current_point == 0:
        current_point = 5
    elif radius == "0-50":
        current_point += 4
    elif radius == "50-100":
        current_point += 2
    return current_point

def similar_unit(data):
    for i in range(len(data)):
        if data[i]["Number_of_similar_units_50"] != 0 or int(data[i]["Core_depofacies"]) != utils_func.UNDEFINED:
            unit_index = data[i]["Index_of_similar_units_50"]
            idx = data[i]["Unit_index"]
            unit_index.append(idx)
            codes = find_unit_core_depofacies(unit_index, data)
            for code in codes:
                name = utils_func.map_core_depofacies_code_to_name(code)
                if name:
                    new_point = handle_point(data[i][name], "0-50")
                    data[i].update({name: new_point})

        if data[i]["Number_of_similar_units_100"] != 0:
            unit_index = data[i]["Index_of_similar_units_100"]
            codes = find_unit_core_depofacies(unit_index, data)
            for code in codes:
                name = utils_func.map_core_depofacies_code_to_name(code)
                if name:
                    new_point = handle_point(data[i][name], "50-100")
                    data[i].update({name: new_point})


import socket

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

serveraddrport = ('127.0.0.1',12345)

while True:
    ip = str(input('Send something to the UDP server:'))

    ip = ip.encode('utf-8');

    s.sendto(ip,serveraddrport)

    if(str(ip.decode('utf-8')) == 'end'):
        break

    string = s.recvfrom(1024)

    string = string[0].decode('utf-8')

    print('Client received : ' + str(string) + ' from UDP server')

s.close()


#%% [markdown]
# # Week 7: Exercise 7.2
# File: DSC540_Paulovici_Exercise_7_2.py (.ipynb)

# Name: Kevin Paulovici

# Date: 1/26/2020

# Course: DSC 540 Data Preparation (2203-1)

# Assignment: Exercise 7.2

#%%
# import needed libraries
import xlrd
import agate
from xlrd.sheet import ctype_text
import pprint
import matplotlib.pyplot as plt

#%%[markdown]
# ## Load Excel spreasheet data for assignments

#%%
# open spreadsheet and sheet of interest
wb = xlrd.open_workbook("unicef_oct_2014.xls")
wb.nsheets
sheet = wb.sheets()[0]

# get title rows
title_rows = zip(sheet.row_values(4), sheet.row_values(5))

# get title columns
titles = [t[0] + '' + t[1] for t in title_rows]
titles = [t.strip() for t in titles]

# get country rows
country_rows = [sheet.row_values(r) for r in range(6, 114)]

# print titles for reference
pprint.pprint(titles)

#%%[markdown]
# ## Importing Data – (Data Wrangling with Python, Page 219-224)
# Create a function to take an empty list, iterate over the columns and create a full list of all the column types for the dataset. Then load into agate table – make sure to clean the data if you get an error. Follow along with the example in the book on the pages listed.

#%%
# data types
text_type = agate.Text()
number_type = agate.Number()
bool_type = agate.Boolean()
date_type = agate.Date()
example_row = sheet.row(6)

# set data types based on example row
types = []
for v in example_row:
    val_type = ctype_text[v.ctype]

    if val_type == 'text':
        types.append(text_type)
    elif val_type == 'number':
        types.append(number_type)
    elif val_type == 'xldate':
        types.append(date_type)
    else:
        types.append(text_type)

# ERROR
#table = agate.Table(country_rows, titles, types)
# results in CastError - need to clean the data

"""
function to remove bad characters

@param: val (str) - character to be cleaned

return: val (str) - cleaned character
"""
def remove_bad_chars(val):
    if val == '-':
        return None
    return val

"""
function to generate new array of cleaned data

@param: old_array (list) - rows of data (dirty)
@param: fun_to_clean (function) - function to clean data

return: new_array (list) - clean data
"""
def get_new_array(old_array, fun_to_clean):
    new_array = []
    for row in old_array:
        cleaned_row = [fun_to_clean(rv) for rv in row]
        new_array.append(cleaned_row)
    return new_array

# create new array of cleaned data
cleaned_rows = get_new_array(country_rows, remove_bad_chars)

# load data into agate table & print
table = agate.Table(cleaned_rows, titles, types)
table.print_table(max_columns=7)

#%%[markdown]
# ## Exploring Table Functions – (Data Wrangling with Python, Page 225-228)

#%% [markdown]
# ### 1) Which countries have the highest rates of child labor?

#%%
high_rates = table.order_by('Total (%)', reverse=True).limit(5)

for r in high_rates.rows:
    print(r['Countries and areas'], r['Total (%)'])

#%%[markdown]
# ### 2) Which countries have the most girls working?

#%%
female_data = table.where(lambda r: r['Female'] is not None)
most_females = female_data.order_by('Female', reverse=True).limit(5)

for r in most_females.rows:
    print('{}: {}%'.format(r['Countries and areas'], r['Female']))

#%%[markdown]
# ### 3) What is the average percentage of child labor in cities?
#%%
has_poor = table.where(lambda r: r['Place of residence (%)Urban'] is not None)
avg_percent = has_poor.aggregate(agate.Mean('Place of residence (%)Urban'))

print('Average percentage of child labor in cities: {}%'.format(round(avg_percent, 2)))

#%%[markdown]
# ### 4) Find a row with more than 50% of rural child labor.
#%%
has_poor = table.where(lambda r: r['Rural'] is not None)
first_match = has_poor.find(lambda x: x['Rural'] > 50)

print('The first row with > 50% rural child labor is', first_match['Countries and areas'])

#%%[markdown]
# ### 5) Rank the worst offenders in terms of child labor percentages by country.

#%%
ranked = table.compute([('Total Child Labor Rank', agate.Rank('Total (%)', reverse=True)), ])

for row in ranked.order_by('Total (%)', reverse=True).limit(20).rows:
    print(row['Total Child Labor Rank'], '\t', row['Countries and areas'], row['Total (%)'])

#%%[markdown]
# ### 6) Calculate the percentage of children not involved in child labor.

#%%
def reverse_percent(row):
    return 100 - row['Total (%)']

ranked = table.compute([('Children not working (%)', agate.Formula(number_type, reverse_percent)),])
ranked = ranked.compute([('Total Child Labor Rank', agate.Rank('Children not working (%)')),])

percent_not_working = ranked.aggregate(agate.Mean('Children not working (%)'))
print('The total % of children not working is {}%'.format(round(percent_not_working, 2)), '\n')

print('The best countries for children not working are:')

for row in ranked.order_by('Total (%)', reverse=False).limit(20).rows:
    print(row['Countries and areas'], row['Total (%)'], row['Children not working (%)'])

#%%[markdown]
# ## Charting with matplotlib – (Data Wrangling with Python, Page 255-258)

#%%[markdown]
# ### Initial setup of data for corruption_perception_index.xls

#%%
# keep float data types as strings
def float_to_str(float):
    return str(float)

def get_table(new_arr, types, titles):
    try:
        table = agate.Table(new_arr, titles, types)
        return table
    except Exception as e:
        print(e)

# set up the data types for columns
def get_types(row):
    types = []
    for v in row:
        value_type = ctype_text[v.ctype]
        if value_type == 'text':
            types.append(text_type)
        elif value_type == 'number':
            types.append(number_type)
        elif value_type == 'xldate':
            types.append(date_type)
        else:
            types.append( text_type)
    return types

# open the spreadsheet and sheet of interest
cpi_workbook = xlrd.open_workbook('corruption_perception_index.xls')
cpi_sheet = cpi_workbook.sheets()[0]

for r in range(cpi_sheet.nrows):
    #print(r, cpi_sheet.row_values(r))
    cpi_title_rows = zip(cpi_sheet.row_values(1), cpi_sheet.row_values(2))
    cpi_titles = [t[0] + '' + t[1] for t in cpi_title_rows]
    cpi_titles = [t.strip() for t in cpi_titles]
    cpi_rows = [cpi_sheet.row_values(r) for r in range(3, cpi_sheet.nrows)]
    cpi_types = get_types(cpi_sheet.row(3))

cpi_titles[0] = cpi_titles[0] + ' Duplicate'

cpi_table = get_table(cpi_rows, cpi_types, cpi_titles)
cpi_rows = get_new_array(cpi_rows, float_to_str)
cpi_table = get_table(cpi_rows, cpi_types, cpi_titles)

cpi_and_cl = cpi_table.join(ranked, 'Country / Territory', 'Countries and areas', inner=True)

#%%[markdown]
# ### 1) Chart the perceived corruption scores compared to the child labor percentages.

#%%
plt.plot(cpi_and_cl.columns['CPI 2013 Score'], cpi_and_cl.columns['Total (%)'])
plt.xlabel('CPI Score - 2013')
plt.ylabel('Child Labor Percentage')
plt.title('CPI & Child Labor Correlation')
plt.show()

#%%[markdown]
# ### 2) Chart the perceived corruption scores compared to the child labor percentages using only the worst offenders.

#%%
# initial set-up for plotting
cl_mean = cpi_and_cl.aggregate(agate.Mean('Total (%)'))
cpi_mean = cpi_and_cl.aggregate(agate.Mean('CPI 2013 Score'))

def highest_rates(row):
    if row['Total (%)'] > cl_mean and row['CPI 2013 Score'] < cpi_mean:
        return True
    return False

highest_cpi_cl = cpi_and_cl.where(lambda x: highest_rates(x))

#%%
plt.plot(highest_cpi_cl.columns['CPI 2013 Score'], highest_cpi_cl.columns['Total (%)'])
plt.xlabel('CPI Score - 2013')
plt.ylabel('Child Labor Percentage')
plt.title('CPI & Child Labor Correlation')
plt.show()


import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold
from sklearn.model_selection import StratifiedKFold
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score
from datetime import date
import os

today = date.today()
# Reading in the data.
data = pd.read_csv('nba_scrapping_data/schedule_ratings.csv')

# Drop rows with null values, these are the rows that were pulled that the games haven't been played yet...
classifier_data = data.dropna()

# Creating a target label for regression models.
classifier_data['a_wonby'] = classifier_data['away_pts'] - classifier_data['home_pts']

# Taking the rows that were dropped to make predictions.
pred_rows = data[data['date'] >= str(today)]
pred_features = pred_rows[pred_rows.columns[5:21]]

# Selecting the columns with the stats we want to use as features
features = classifier_data[classifier_data.columns[5:21]]
class_target = classifier_data[classifier_data.columns[-2]] # This target is the discrete variable of home or away team winning.
reg_target = classifier_data[classifier_data.columns[-1]] # This target variable is how much the away team won by.

N_SPLITS = 5

# Creating pipelines
pipeline_lr = Pipeline([('scalar1', StandardScaler()),
                        ('lr_classifier', LogisticRegression(random_state=0))])

pipeline_kn = Pipeline([('scalar2', StandardScaler()),
                        ('kn_classifier', KNeighborsClassifier())])

pipeline_dt = Pipeline([('scalar3', StandardScaler()),
                        ('dt_classifier', DecisionTreeClassifier(random_state=0))])

pipeline_lda = Pipeline([('scalar3', StandardScaler()),
                        ('lda_classifier', LinearDiscriminantAnalysis())])

pipeline_svc = Pipeline([('scalar3', StandardScaler()),
                        ('svc_classifier', SVC(random_state=0))])

pipelines = [pipeline_lr, pipeline_kn, pipeline_dt, pipeline_lda, pipeline_svc]

best_accuracy = 0.0
best_classifier = 0
best_pipeline = ""

pipe_dict = {0: 'Logistic Regression',
             1: 'KNeighbors',
             2: 'Decision Tree',
             3: 'Linear Discriminant Analysis',
             4: 'Support Vector Machine'}

X_train, X_test, y_train, y_test = train_test_split(features, class_target, test_size=0.2, random_state=0)

predictions = []
for pipe in pipelines:
    pipe.fit(X_train, y_train)
    real_preds = pipe.predict(pred_features)
    predictions.append(real_preds)

# Getting the predicted winner that the most classifiers agree on.
final_predictions = []
for i in range(len(predictions[0])):
    pred_list = []

    for pred in predictions:
        pred_list.append(pred[i])
    home_count = pred_list.count('home')
    away_count = pred_list.count('away')
    if home_count > away_count:
        final_predictions.append('Home')
    elif home_count == away_count:
        final_predictions.append('Unsure')
    else:
        final_predictions.append('Away')

print(f'The classifiers predict... {final_predictions}')

# Putting the final predictions into the game rows row today.
pred_rows = pred_rows.drop('winner',axis = 1)
pred_rows['predicted_winner'] = final_predictions

site_table = pred_rows[['away','home','predicted_winner']]
class_scores = []
for i, model in enumerate(pipelines):
    m_score = model.score(X_test,y_test)
    store_score = pipe_dict[i],m_score
    class_scores.append(store_score)
    print(f'{pipe_dict[i]} Test Accuracy: {m_score}')

# Putting scores into a file for historical purposes.
# Commented out score history lines for New york trip.
# score_df = pd.DataFrame(data = class_scores, columns=['classifier','Accuracy'])
# score_df.to_csv(f'score_history/classifier_score_{today}.csv', index = False)

PATH_PARENT = os.path.dirname(os.getcwd())
path = os.path.join(PATH_PARENT,'personal-site/static/predictions')

site_table.to_csv(f'{path}/predictions.csv',index = False)

#%%
# Commented out lines are for kfold train/test splits, should implement later.
kf = KFold(n_splits=N_SPLITS)

# print(pipeline_lda.predict(X_test))
# print(y_test)

# acc_score = []

# for train_index, test_index in kf.split(features):
#     X_train, X_test = features.iloc[train_index,:], features.iloc[test_index,:]
#     y_train, y_test = classifier_data['winner'][train_index], classifier_data['winner'][test_index]
#
#     pipeline_lda.fit(X_train,y_train)
#     pred_values = pipeline_lda.predict(X_test)
#
#     acc = accuracy_score(pred_values, y_test)
#     acc_score.append(acc)
#
# avg_score = sum(acc_score) / N_SPLITS
#
# print(f'Accuracy of each fold: {acc_score}')
# print(f'Average accuracy score: {avg_score}')

#%%
# Trying Gradient Boosting Classifier
scaler = StandardScaler()
scaled_features = scaler.fit_transform(features)

gbm = GradientBoostingClassifier(random_state=1, n_estimators=120, learning_rate= 0.1, max_depth=3)
cv = StratifiedKFold(n_splits=5,random_state=1, shuffle=True)

n_scores = cross_val_score(gbm, scaled_features, y=class_target, scoring='accuracy', cv=cv, n_jobs=-1, error_score='raise')

print(f'Gradient Boosting Accuracy: {np.mean(n_scores)}, {np.std(n_scores)}')

#%%
# Creating multiple regression models.

print('NOW FOR THE REGRESSION MODELS...')
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from sklearn.tree import DecisionTreeRegressor
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error
from sklearn.metrics import r2_score

# Scaling data first

scaled_features = scaler.fit_transform(features)

X_train_reg, X_test_reg, y_train_reg, y_test_reg = train_test_split(features, reg_target, test_size=0.2, random_state=0)

lm_model = LinearRegression()

lm_model.fit(X_train_reg,y_train_reg)

# print(f'Multiple Linear Regression Score: {lm_model.score(X_test_reg,y_test_reg)}')

# Creating pipelines
pipeline_lm = Pipeline([('scalar1', StandardScaler()),
                        ('lm_classifier', LinearRegression())])

pipeline_r = Pipeline([('scalar2', StandardScaler()),
                        ('r_classifier', Ridge())])

pipeline_dtr = Pipeline([('scalar3', StandardScaler()),
                        ('dtr_classifier', DecisionTreeRegressor(random_state=0))])

pipeline_svr = Pipeline([('scalar3', StandardScaler()),
                        ('svr_classifier', SVR())])

pipelines_reg = [pipeline_lm, pipeline_r, pipeline_dtr, pipeline_svr]

pipe_dict_reg = {0: 'Linear Regression',
             1: 'Ridge',
             2: 'Decision Tree Regressor',
             3: 'Support Vector Regressor'
                 }

for pipeline in pipelines_reg:
    pipeline.fit(X_train_reg, y_train_reg)

reg_scores = []
for i, model in enumerate(pipelines_reg):
    reg_pred = model.predict(X_test_reg)
    mse_score = mean_squared_error(y_test_reg,reg_pred)
    r_score = r2_score(y_test_reg,reg_pred)
    regression_score = pipe_dict_reg[i],mse_score,r_score
    reg_scores.append(regression_score)

    print(f'{pipe_dict_reg[i]}: Mean Squared Error: {mse_score},R2:{r_score}')

# Putting scores into a file for historical purposes.
# Commented out score history lines for New York trip
# reg_score_df = pd.DataFrame(data = reg_scores, columns=['classifier','mean_squared_error','R2'])
# reg_score_df.to_csv(f'score_history/regression_score_{today}.csv', index = False)


#o programa abaixo faz a leitura de cinco nomea e
#cria um conjunto xom ate cinco nomes distintos pelo
#usuario. A cada conjunto ocorre a cada tentatuva de
#de inclusao do nome.

eacolhidos = ser()
for i in range(5):
     nome = input("digite o nome:")
     escolhidos.add(nome)
     print(escolhidos)


from collections import deque

def solution(rows, columns, queries):
    answer = []
    mapping = []
    for i in range(rows):
        tp = []
        for j in range(columns):
            tp.append(columns*i+j+1)
        mapping.append(tp)

    def rotation(mapping,lst):
        x1,y1,x2,y2 = lst
        queue = deque()
        for i in range(y1-1,y2-1):
            queue.append(mapping[x1-1][i])
        for i in range(x1-1,x2-1):
            queue.append(mapping[i][y2-1])
        for i in range(y2-1,y1-1,-1):
            queue.append(mapping[x2-1][i])
        for i in range(x2-1,x1-1,-1):
            queue.append(mapping[i][y1-1])

        ans = min(queue)
        queue.appendleft(queue.pop())

        for i in range(y1-1,y2-1):
            mapping[x1-1][i] = queue.popleft()
        for i in range(x1-1,x2-1):
            mapping[i][y2-1] = queue.popleft()
        for i in range(y2-1,y1-1,-1):
            mapping[x2-1][i] = queue.popleft()
        for i in range(x2-1,x1-1,-1):
            mapping[i][y1-1] = queue.popleft()

        return mapping,ans

    for query in queries:
        mapping,ans = rotation(mapping, query)
        answer.append(ans)

    return answer

solution(3,4,[[2, 2, 3, 3]])

pythonProject/programmers/lv2. 행렬 테두리 회전하기.py

lv2. 행렬 테두리 회전하기.py


# coding: utf-8

__author__ = ["Samuel Joshua"]

from PIL import Image

catIm = Image.open('zophie.png')

width, height = catIm.size
quartersizedIm = catIm.resize((int(width/2)), (int(height/2)))
quartersizedIm.save('quartersized.png')

saveIteIm = catIm.resize((width, height + 300))
saveIteIm.save('saveIte.png')


#!/usr/bin/env python
# encoding: utf-8

from libs.lib_file_operate.file_utils import file_is_empty, auto_make_dir

def write_title(file_path, title, encoding="utf-8", new_line=True, mode="a+"):
    auto_make_dir(file_path, is_file=True)
    # 文本文件写入表头,仅在文件不存在时,写入
    if file_is_empty(file_path) or "w" in mode:
        with open(file_path, mode=mode, encoding=encoding) as f_open:
            title = f"{title.strip()}\n" if new_line else title
            f_open.write(title)
            f_open.close()

def write_line(file_path, data_list, encoding="utf-8", new_line=True, mode="w+"):
    auto_make_dir(file_path, is_file=True)
    # 判断输入的是字符串还是列表
    data_list = [data_list] if isinstance(data_list, str) else data_list
    # 文本文件写入数据 默认追加
    with open(file_path, mode=mode, encoding=encoding) as f_open:
        data_list = [f"{data.strip()}\n" for data in data_list] if new_line else data_list
        f_open.writelines(data_list)
        f_open.close()


"""
Instructor tasks related to enrollments.
"""

import logging
from datetime import datetime
from time import time

from django.conf import settings
from django.utils.translation import ugettext as _
from pytz import UTC
from six import StringIO

from edxmako.shortcuts import render_to_string
from lms.djangoapps.courseware.courses import get_course_by_id
from lms.djangoapps.instructor.paidcourse_enrollment_report import PaidCourseEnrollmentReportProvider
from lms.djangoapps.instructor_analytics.basic import enrolled_students_features, list_may_enroll
from lms.djangoapps.instructor_analytics.csvs import format_dictlist
from lms.djangoapps.instructor_task.models import ReportStore
from student.models import CourseAccessRole, CourseEnrollment
from util.file import course_filename_prefix_generator

from .runner import TaskProgress
from .utils import tracker_emit, upload_csv_to_report_store

TASK_LOG = logging.getLogger('edx.celery.task')
FILTERED_OUT_ROLES = ['staff', 'instructor', 'finance_admin', 'sales_admin']

def upload_enrollment_report(_xmodule_instance_args, _entry_id, course_id, _task_input, action_name):
    """
    For a given `course_id`, generate a CSV file containing profile
    information for all students that are enrolled, and store using a
    `ReportStore`.
    """
    start_time = time()
    start_date = datetime.now(UTC)
    status_interval = 100
    students_in_course = CourseEnrollment.objects.enrolled_and_dropped_out_users(course_id)
    task_progress = TaskProgress(action_name, students_in_course.count(), start_time)

    fmt = u'Task: {task_id}, InstructorTask ID: {entry_id}, Course: {course_id}, Input: {task_input}'
    task_info_string = fmt.format(
        task_id=_xmodule_instance_args.get('task_id') if _xmodule_instance_args is not None else None,
        entry_id=_entry_id,
        course_id=course_id,
        task_input=_task_input
    )
    TASK_LOG.info(u'%s, Task type: %s, Starting task execution', task_info_string, action_name)

    # Loop over all our students and build our CSV lists in memory
    rows = []
    header = None
    current_step = {'step': 'Gathering Profile Information'}
    enrollment_report_provider = PaidCourseEnrollmentReportProvider()
    total_students = students_in_course.count()
    student_counter = 0
    TASK_LOG.info(
        u'%s, Task type: %s, Current step: %s, generating detailed enrollment report for total students: %s',
        task_info_string,
        action_name,
        current_step,
        total_students
    )

    for student in students_in_course:
        # Periodically update task status (this is a cache write)
        if task_progress.attempted % status_interval == 0:
            task_progress.update_task_state(extra_meta=current_step)
        task_progress.attempted += 1

        # Now add a log entry after certain intervals to get a hint that task is in progress
        student_counter += 1
        if student_counter % 100 == 0:
            TASK_LOG.info(
                u'%s, Task type: %s, Current step: %s, gathering enrollment profile for students in progress: %s/%s',
                task_info_string,
                action_name,
                current_step,
                student_counter,
                total_students
            )

        user_data = enrollment_report_provider.get_user_profile(student.id)
        course_enrollment_data = enrollment_report_provider.get_enrollment_info(student, course_id)
        payment_data = enrollment_report_provider.get_payment_info(student, course_id)

        # display name map for the column headers
        enrollment_report_headers = {
            'User ID': _('User ID'),
            'Username': _('Username'),
            'Full Name': _('Full Name'),
            'First Name': _('First Name'),
            'Last Name': _('Last Name'),
            'Company Name': _('Company Name'),
            'Title': _('Title'),
            'Language': _('Language'),
            'Year of Birth': _('Year of Birth'),
            'Gender': _('Gender'),
            'Level of Education': _('Level of Education'),
            'Mailing Address': _('Mailing Address'),
            'Goals': _('Goals'),
            'City': _('City'),
            'Country': _('Country'),
            'Enrollment Date': _('Enrollment Date'),
            'Currently Enrolled': _('Currently Enrolled'),
            'Enrollment Source': _('Enrollment Source'),
            'Manual (Un)Enrollment Reason': _('Manual (Un)Enrollment Reason'),
            'Enrollment Role': _('Enrollment Role'),
            'List Price': _('List Price'),
            'Payment Amount': _('Payment Amount'),
            'Coupon Codes Used': _('Coupon Codes Used'),
            'Registration Code Used': _('Registration Code Used'),
            'Payment Status': _('Payment Status'),
            'Transaction Reference Number': _('Transaction Reference Number')
        }

        if not header:
            header = list(user_data.keys()) + list(course_enrollment_data.keys()) + list(payment_data.keys())
            display_headers = []
            for header_element in header:
                # translate header into a localizable display string
                display_headers.append(enrollment_report_headers.get(header_element, header_element))
            rows.append(display_headers)

        rows.append(list(user_data.values()) + list(course_enrollment_data.values()) + list(payment_data.values()))
        task_progress.succeeded += 1

    TASK_LOG.info(
        u'%s, Task type: %s, Current step: %s, Detailed enrollment report generated for students: %s/%s',
        task_info_string,
        action_name,
        current_step,
        student_counter,
        total_students
    )

    # By this point, we've got the rows we're going to stuff into our CSV files.
    current_step = {'step': 'Uploading CSVs'}
    task_progress.update_task_state(extra_meta=current_step)
    TASK_LOG.info(u'%s, Task type: %s, Current step: %s', task_info_string, action_name, current_step)

    # Perform the actual upload
    upload_csv_to_report_store(rows, 'enrollment_report', course_id, start_date, config_name='FINANCIAL_REPORTS')

    # One last update before we close out...
    TASK_LOG.info(u'%s, Task type: %s, Finalizing detailed enrollment task', task_info_string, action_name)
    return task_progress.update_task_state(extra_meta=current_step)

def upload_may_enroll_csv(_xmodule_instance_args, _entry_id, course_id, task_input, action_name):
    """
    For a given `course_id`, generate a CSV file containing
    information about students who may enroll but have not done so
    yet, and store using a `ReportStore`.
    """
    start_time = time()
    start_date = datetime.now(UTC)
    num_reports = 1
    task_progress = TaskProgress(action_name, num_reports, start_time)
    current_step = {'step': 'Calculating info about students who may enroll'}
    task_progress.update_task_state(extra_meta=current_step)

    # Compute result table and format it
    query_features = task_input.get('features')
    student_data = list_may_enroll(course_id, query_features)
    header, rows = format_dictlist(student_data, query_features)

    task_progress.attempted = task_progress.succeeded = len(rows)
    task_progress.skipped = task_progress.total - task_progress.attempted

    rows.insert(0, header)

    current_step = {'step': 'Uploading CSV'}
    task_progress.update_task_state(extra_meta=current_step)

    # Perform the upload
    upload_csv_to_report_store(rows, 'may_enroll_info', course_id, start_date)

    return task_progress.update_task_state(extra_meta=current_step)

def upload_students_csv(_xmodule_instance_args, _entry_id, course_id, task_input, action_name):
    """
    For a given `course_id`, generate a CSV file containing profile
    information for all students that are enrolled, and store using a
    `ReportStore`.
    """
    start_time = time()
    start_date = datetime.now(UTC)
    enrolled_students = CourseEnrollment.objects.users_enrolled_in(course_id)
    task_progress = TaskProgress(action_name, enrolled_students.count(), start_time)

    current_step = {'step': 'Calculating Profile Info'}
    task_progress.update_task_state(extra_meta=current_step)

    # compute the student features table and format it
    query_features = task_input
    student_data = enrolled_students_features(course_id, query_features)
    header, rows = format_dictlist(student_data, query_features)

    task_progress.attempted = task_progress.succeeded = len(rows)
    task_progress.skipped = task_progress.total - task_progress.attempted

    rows.insert(0, header)

    current_step = {'step': 'Uploading CSV'}
    task_progress.update_task_state(extra_meta=current_step)

    # Perform the upload
    upload_csv_to_report_store(rows, 'student_profile_info', course_id, start_date)

    return task_progress.update_task_state(extra_meta=current_step)


__author__  = 'JPaschoal'
__version__ = '1.0.1'
__email__   = 'jonfisik@hotmail.com'
__date__    = '08/05/2021'
'''
Dados n e uma sequência de números inteiros, determinar quantos segmentos de
números iguais consecutivos compõem essa sequência.

Exemplos:
Sequência: 5, 2, 2, 2, 4, 4, 4, 4, 1, 1
Comprimento do segmento igual >>> 5
'''
#   5, 2, 2, 2, 4, 4, 4, 4, 1, 1
#   ant = 5
#   seg = 1
#   n = 10
#   cont = 0
#-------------------------------------------
#   prox = 2
#   ant == prox -->
#   ant != prox --> seg += 1
#   ant = prox = 2
#-------------------------------------------
#   ant = 2
#   prox = 2
#   ant == prox
#   ant = prox
#--------------------------------------------

def traco():
    return print('-----'*10)

print('')
print("SEQUÊNCIA IGUAL")
traco()

# input
n = int(input('Digite o tamanho da sequência: '))
ant =int(input('Digite o 1º número da sequência: '))

# váriaveis
cont = seg = 1

while cont < n:
    prox = int(input(f'Digite o {cont+1}º número da sequência: '))
    if prox != ant:
        seg += 1
    ant = prox
    cont += 1

print(f'A sequência tem {seg} segmento(s) iguais.')

traco()
print('')
# END


# to measure the accuracy of your model

# a training set and a testing set

# 80 20 Rule for the data, 80 % for training and 20 % for testing

# train the model means create the model
# test the model tests the accuracy of the model

# start with a data set you want to test

# in this data set, there are 100 customers in a shop, and their shopping habits

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(2)
# makes the random numbers predictable
# with the seed reset(every time), the same set of numbers will appear every time

x = np.random.normal(3, 1, 100)
y = np.random.normal(150, 40, 100) / x

# np.random.normal(loc = mean, scale = std, size)
plt.scatter(x, y)
plt.show()

# x axis represents the number of minutes before making a purchase
# y axis represents the amount of money spent on the purchase

# split into train/test
train_x = x[: 80] # end before 80
train_y = y[: 80]

test_x = x[80 :] # start at 80
test_y = y[80 :]

# display the training set

plt.scatter(train_x, train_y)
plt.show()

# display the testing set

plt.scatter(test_x, test_y)
plt.show()

# polynomial regression is the best fit for this case

# create the model

mymodel = np.poly1d(np.polyfit(train_x, train_y, 4))

myline = np.linspace(0, 6, 100)

plt.scatter(train_x, train_y)
plt.plot(myline, mymodel(myline))
plt.show()

"""
import numpy as np
"""
from sklearn.metrics import r2_score
"""
np.random.seed(2)

x = np.random.normal(3, 1, 100)
y = np.random.normal(150, 40, 100) / x

trian_x = x[: 80]
trian_y = y[: 80]

test_x = x[80: ]
test_y = y[80: ]

mymodel = np.poly1d(np.polyfit(train_x, train_y, 4))

"""

r2 = r2_score(train_y, mymodel(train_x))

print(r2)

# for test case : r-squared
"""
import numpy as np
from sklearn.metrics import r2_score

np.random.seed(2)

x = np.random.normal(3, 1, 100)
y = np.random.normal(150, 40, 100) / x

train_x = x[: 80]
train_y = y[: 80]

test_x = x[80: ]
test_y = y[80: ]

mymodel = np.poly1d(np.polyfit(train_x, train_y, 4))

"""

r2 = r2_score(test_y, mymodel(test_x))
print(r2)

# r-squared for both training and testing cases are good and do we can predict values

# how much money will a buying customer spend, if she or he stays in the shop for 5 minutes?

print(mymodel(5))


# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""
This module provides classes to perform grouping of stars.
"""

import numpy as np

__all__ = ['SourceGrouper']

class SourceGrouper:
    """
    Class to group sources into clusters based on a minimum separation
    distance.

    This class uses the `"Density-based Spatial Clustering
    of Applications with Noise" clustering algorithm
    <https://scikit-learn.org/stable/modules/clustering.html#dbscan>`_
    from `scikit-learn <https://scikit-learn.org/>`_.

    Parameters
    ----------
    min_separation : float
        The minimum distance (in pixels) such that any two sources
        separated by less than this distance will be placed in the same
        group if the ``min_size`` criteria is also met.

    min_size : int, optional
        The minimum number of sources necessary to form a group.

    metric : str or callable (default='euclidean'), optional
        The metric to use when calculating distance between each pair of
        sources.

    algorithm : {'auto', 'ball_tree', 'kd_tree', 'brute'}, optional
        The algorithm to use to find nearest neighbors.

    leaf_size : int, optional (default = 30)
        The leaf size passed to the BallTree or cKDTree function.
        Changing ``leaf_size`` will not affect the results of a query,
        but can significantly impact the speed of a query and the memory
        required to store the constructed tree.

    References
    ----------
    [1] scikit-learn DBSCAN.
        https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html

    Notes
    -----
    ``min_separation`` corresponds to ``eps`` in `sklearn.cluster.DBSCAN
    <https://scikit-learn.org/stable/modules/generated/sklearn.cluster.D
    BSCAN.html>`_.
    """
    def __init__(self, min_separation, *, min_size=1, metric='euclidean',
                 algorithm='auto', leaf_size=30):
        self.min_separation = min_separation
        self.min_size = min_size
        self.metric = metric
        self.algorithm = algorithm
        self.leaf_size = leaf_size

    def __call__(self, x, y):
        """
        Group sources into clusters based on a minimum distance
        criteria.

        Parameters
        ----------
        x, y : 1D float `~numpy.ndarray`
            The 1D arrays of the x and y centroid coordinates of the
            sources.

        Returns
        -------
        result : 1D int `~numpy.ndarray`
            A 1D array of the groups, in the same order as the input x
            and y coordinates.
        """
        return self._group_sources(x, y)

    def _group_sources(self, x, y):
        """
        Group sources into clusters based on a minimum distance
        criteria.

        Parameters
        ----------
        x, y : 1D float `~numpy.ndarray`
            The 1D arrays of the x and y centroid coordinates of the
            sources.

        Returns
        -------
        result : 1D int `~numpy.ndarray`
            A 1D array of the groups, in the same order as the input x
            and y coordinates.
        """
        from sklearn.cluster import DBSCAN

        xypos = np.transpose((x, y))
        dbscan = DBSCAN(eps=self.min_separation, min_samples=self.min_size,
                        metric=self.metric, algorithm=self.algorithm,
                        leaf_size=self.leaf_size)
        group_id = dbscan.fit(xypos).labels_ + 1

        return group_id


import pandas as pd
from requests import get
from bs4 import BeautifulSoup

try:
    from utils import get_player_suffix
    from lookup import lookup
except:
    from basketball_ref_scraper.utils import get_player_suffix
    from basketball_ref_scraper.lookup import lookup

def get_game_logs(_name, year, playoffs=False, ask_matches=True):
    name = lookup(_name, ask_matches)
    if name == "":
        print("No matches found")
        return ""
    # suffix = get_player_suffix(name).replace('/', '%2F').replace('.html', '')
    alpha_code = name.split(" ")[-1][0]
    if len(name.split(" ")[-1]) < 5:
        name_code = name.split(" ")[-1] + name[0:2]
    else:
        name_code = name.split(" ")[-1][0:5] + name[0:2]
    r = get(f'https://www.basketball-reference.com/players/{alpha_code}/{name_code}01/gamelog-advanced/{year}')
    if r.status_code==200:
        soup = BeautifulSoup(r.content, 'html.parser')
        table = soup.find('table')
        if table:
            df = pd.read_html(str(table))[0]
            df.rename(columns = {'Date': 'DATE', 'Age': 'AGE', 'Tm': 'TEAM', 'Unnamed: 5': 'HOME/AWAY', 'Opp': 'OPPONENT',
                'Unnamed: 7': 'RESULT', 'GmSc': 'GAME_SCORE'}, inplace=True)
            df['HOME/AWAY'] = df['HOME/AWAY'].apply(lambda x: 'AWAY' if x=='@' else 'HOME')
            df = df[df['Rk']!='Rk']
            df = df.drop(['Rk', 'G'], axis=1)
            df['DATE'] = pd.to_datetime(df['DATE'])
            df = df[df['GS'] == '1'].reset_index(drop=True)
            return df