#!/usr/bin/env python3

import matplotlib
matplotlib.use('QtAgg')

from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import matplotlib.cm as cm
from typing import List

import numpy as np
import sys

def get_next(u: int, m: int, p: int):
  u_next = u * m % p
  r_next = u_next / p
  return u_next, r_next

def generate_int(u0: int, m: int, p: int, n: int):
  res = [0] * n
  u = u0
  res[0] = u

  for idx in range(1, n):
    u, _ = get_next(u, m, p)
    res[idx] = u

  return res

def generate_float(u0: int, m: int, p: int, n: int):
  res = [0.0] * n
  u = u0
  res[0] = u / p

  for idx in range(1, n):
    u, res[idx] = get_next(u, m, p)

  return res

def compute_aperiodic_len(u0: int, m: int, p: int):
  elem_dict = dict()
  aperiodic_len = 0
  current_idx = 0
  u = u0

  while True:
    if u not in elem_dict.keys():
      elem_dict[u] = current_idx
    else:
      aperiodic_len = len(elem_dict) - elem_dict[u]
      break

    current_idx += 1
    u, _ = get_next(u, m, p)

  return aperiodic_len, len(elem_dict)

def get_expected_val_from_seq(sequence: List[float]):
  return np.mean(sequence)

def get_dispersion_from_seq(sequence: List[float]):
  exp_val = get_expected_val_from_seq(sequence)

  square_sum = 0.0

  for variable in sequence:
    square_sum += pow(variable - exp_val, 2)

  return square_sum / len(sequence)

def line_indexN(array: List[float], q: int):
  part_id = 0x00
  power = 0x01

  for num in array[::-1]:
    part_id += int(num * q) * power
    power *= q

  if part_id >= power:
    return power - 1
  else:
    return part_id

def get_points_for_cube(random_array: List[int], q: int = 6, dims: int = 2):
  n = len(random_array) // dims
  m = int(pow(q, dims))
  idx = 0x00
  points_num_list = [0] * m

  while idx < dims * n:
    points_num_list[line_indexN(random_array[idx:idx + dims], q)] += 1
    idx += dims

  return points_num_list

def compute_xi2(random_array: List[float], q: int = 6, dims: int = 2):
  n = len(random_array) // dims
  m = int(pow(q, dims))
  xi2 = 0.0
  n_by_m = n / m

  points_num_list = get_points_for_cube(random_array, q, dims)

  for point_count in points_num_list:
    xi2 += pow(point_count - n_by_m, 2)

  return xi2 / n_by_m

def compute_min_xi2(start_idx: List[int], m: int, p: int, length: int):
  min_xi2 = sys.float_info.max
  u0 = 0

  for u in start_idx:
    xi2 = compute_xi2(generate_float(u, m, p, length))

    if xi2 < min_xi2:
      min_xi2 = xi2
      u0 = u

  return u0, xi2

def generate_table(start_idx: List[int], m: int, p: int, length: int, func):
  xi2_arr = [0] * len(start_idx)
  idx = 0

  for u in start_idx:
    xi2_arr[idx] = func(generate_float(u, m, p, length))
    idx += 1

  return xi2_arr

def plot_3d_graph(arr: List[int], size: int):
  xs = []
  for idx in range(size):
    xs.extend([idx + 1] * size)

  ys = [i for i in range(1, size + 1)] * size

  cmap = cm.get_cmap('hot')
  norm = colors.Normalize(min(arr), max(arr))
  colors_arr = [cmap(norm(num)) for num in arr]

  fig = plt.figure(1)
  ax = fig.add_subplot(121, projection='3d')
  ax.bar3d(xs, ys, np.zeros(size * size), np.ones(size * size), np.ones(size * size), arr, color=colors_arr)
  ax.grid(True)

  ax.set_xticks(np.arange(1, size + 1, 1))
  ax.set_yticks(np.arange(1, size + 1, 1))
  ax.set_zticks(np.arange(1, max(arr), max(arr) // 3))

  ax.set_xlabel('Row')
  ax.set_ylabel('Column')
  ax.set_zlabel('Occurrence')

def plot_2d_graph(arr: List[int], size: int):
  x_array = []

  for idx in range(size):
    x_array.extend([idx + 1.5] * size)

  y_array = [i + 0.5 for i in range(1, size + 1)] * size

  fig = plt.figure(2)
  ax = fig.add_subplot()
  ax.axis([1, size + 1, 1, size + 1])
  ax.grid(True)

  ax.set_xticks(np.arange(1, size + 1, 1))
  ax.set_yticks(np.arange(1, size + 1, 1))

  ax.set_xlabel('Row')
  ax.set_ylabel('Column')
  ax.scatter(x_array, y_array, c=arr, cmap="gist_yarg")

def plot_exp_val_xi2_dispersion(u_values: List[int], m: int, p: int, length: int, q: int = 2, dims: int = 3):
  mean_values = []
  dispersion = []
  xi2 = []
  aperiodic_len = []
  unique_len = []

  for u in u_values:
    res = generate_float(u, m, p, length)
    mean_values.append(get_expected_val_from_seq(res))
    dispersion.append(get_dispersion_from_seq(res))
    xi2.append(compute_xi2(res, q, dims))
    aper_len, uni_len = compute_aperiodic_len(u, m, p)
    aperiodic_len.append(aper_len)
    unique_len.append(uni_len)

    print(f"{u}, {mean_values[-1]}, {dispersion[-1]}, {xi2[-1]}, {aper_len}, {uni_len}")

  print(res)

  fig_mean_val = plt.figure(3)
  mean_val_fig = fig_mean_val.add_subplot()
  mean_val_fig.grid(True)
  mean_val_fig.set_title(f"Mean values for {length}")
  mean_val_fig.set_xlabel("u0")
  mean_val_fig.set_ylabel("Mean value")
  mean_val_fig.scatter(u_values, mean_values)

  fig_dispersion = plt.figure(4)
  disp_fig = fig_dispersion.add_subplot()
  disp_fig.grid(True)
  disp_fig.set_title(f"Dispersion for length {length}")
  disp_fig.set_xlabel("u0")
  disp_fig.set_ylabel("Dispersion")
  disp_fig.scatter(u_values, dispersion)

  fig_xi2 = plt.figure(5)
  xi2_fig = fig_xi2.add_subplot()
  xi2_fig.grid(True)
  xi2_fig.set_title(f"xi2 for length {length}")
  xi2_fig.set_xlabel("u0")
  xi2_fig.set_ylabel("xi2 value")
  xi2_fig.scatter(u_values, xi2)

def plot_2d_histogram(arr: List[int]):
  fig = plt.figure(6)
  ax = fig.add_subplot()
  # ax.axis([1, len(arr) + 1, 1, len(arr) + 1])
  # ax.grid(True)

  # ax.set_xticks(np.arange(1, len(arr) + 1, 1))
  # ax.set_yticks(np.arange(1, max(arr) + 1, max(arr) // 100))
  # ax.set_ylim(len(arr));
  ax.set_xlabel('Count')
  ax.set_ylabel('Point Num')
  ax.bar(np.arange(1, len(arr) + 1, 1), arr, align='center')

def find_min_xi2_disp_mean(u_range: int, m_range: int, p: int, length: int, q:int = 2, dims: int = 3, debug = True):
  min_xi2 = 1000
  min_dispersion = 1000
  min_mean = 1

  min_arr = [None] * 3

  for m in m_range:
    for u in u_range:
      int_vect = generate_int(u, m, p, length)
      float_vect = [num / p for num in int_vect]

      temp_xi2 = compute_xi2(float_vect, q, dims)
      temp_mean = get_expected_val_from_seq(float_vect)
      temp_dispersion = get_dispersion_from_seq(float_vect)
      aper_len, uni_len = compute_aperiodic_len(u, m, p)

      if debug:
        print(f"{u}, {temp_mean}, {temp_dispersion}, {temp_xi2}, {aper_len}, {uni_len}, {m}")

      if temp_xi2 < min_xi2:
        min_xi2 = temp_xi2
        min_arr[0] = (u, m)

      if temp_dispersion < min_dispersion:
        min_dispersion = temp_dispersion
        min_arr[1] = (u, m)

      if abs(temp_mean - 0.5) < abs(min_mean - 0.5):
        min_mean = temp_mean
        min_arr[2] = (u, m)

      if (uni_len != p - 1):
        break

  print(min_arr)

if __name__ == '__main__':
  p = 10007
  m = 214 # 28
  length = 15000
  u0 = 1275
  q = 6
  dims = 2

  # print(get_expected_val(7, 5, 10007, 100000))

  # find_min_xi2_disp_mean(range(1, p // 2), range(2, p // 2), p, length, q, dims)

  plot_exp_val_xi2_dispersion(range(1, p), m, p, length)

  random_vect = generate_float(u0, m, p, length)

  cube_points = get_points_for_cube(random_vect, q, dims)
  plot_3d_graph(cube_points, q)
  plot_2d_graph(cube_points, q)
  # cube_points = get_points_for_cube(random_vect, q ** dims, 1)
  plot_2d_histogram(cube_points)

  aper_len, uni_len = compute_aperiodic_len(u0, m, p)
  print(f"exp_val={get_expected_val_from_seq(random_vect)}, "
        f"disp={get_dispersion_from_seq(random_vect)}, "
        f"xi2={compute_xi2(random_vect, q, dims)}, "
        f"aperiodic_len={aper_len}, "
        f"unique_len={uni_len}", file=sys.stderr)
  plt.show()


from copy import deepcopy
from dataclasses import dataclass, field
from itertools import chain
from typing import (
    List,
    Dict,
    Any,
    Optional,
    TypeVar,
    Union,
    Mapping,
)
from typing_extensions import Protocol, runtime_checkable

import os

from dbt.flags import get_flags
from dbt import deprecations
from dbt.constants import (
    DEPENDENCIES_FILE_NAME,
    PACKAGES_FILE_NAME,
    PACKAGE_LOCK_HASH_KEY,
)
from dbt.clients.system import path_exists, load_file_contents
from dbt.clients.yaml_helper import load_yaml_text
from dbt.contracts.connection import QueryComment
from dbt.exceptions import (
    DbtProjectError,
    SemverError,
    ProjectContractBrokenError,
    ProjectContractError,
    DbtRuntimeError,
)
from dbt.graph import SelectionSpec
from dbt.helper_types import NoValue
from dbt.semver import VersionSpecifier, versions_compatible
from dbt.version import get_installed_version
from dbt.utils import MultiDict, md5
from dbt.node_types import NodeType
from dbt.config.selectors import SelectorDict
from dbt.contracts.project import (
    Project as ProjectContract,
    SemverString,
)
from dbt.contracts.project import PackageConfig, ProjectPackageMetadata
from dbt.dataclass_schema import ValidationError
from .renderer import DbtProjectYamlRenderer, PackageRenderer
from .selectors import (
    selector_config_from_data,
    selector_data_from_root,
    SelectorConfig,
)

INVALID_VERSION_ERROR = """\
This version of dbt is not supported with the '{package}' package.
  Installed version of dbt: {installed}
  Required version of dbt for '{package}': {version_spec}
Check for a different version of the '{package}' package, or run dbt again with \
--no-version-check
"""

IMPOSSIBLE_VERSION_ERROR = """\
The package version requirement can never be satisfied for the '{package}
package.
  Required versions of dbt for '{package}': {version_spec}
Check for a different version of the '{package}' package, or run dbt again with \
--no-version-check
"""

MALFORMED_PACKAGE_ERROR = """\
The packages.yml file in this project is malformed. Please double check
the contents of this file and fix any errors before retrying.

You can find more information on the syntax for this file here:
https://docs.getdbt.com/docs/package-management

Validator Error:
{error}
"""

MISSING_DBT_PROJECT_ERROR = """\
No dbt_project.yml found at expected path {path}
Verify that each entry within packages.yml (and their transitive dependencies) contains a file named dbt_project.yml
"""

@runtime_checkable
class IsFQNResource(Protocol):
    fqn: List[str]
    resource_type: NodeType
    package_name: str

def _load_yaml(path):
    contents = load_file_contents(path)
    return load_yaml_text(contents)

def load_yml_dict(file_path):
    ret = {}
    if path_exists(file_path):
        ret = _load_yaml(file_path) or {}
    return ret

def package_and_project_data_from_root(project_root):

    packages_yml_dict = load_yml_dict(f"{project_root}/{PACKAGES_FILE_NAME}")
    dependencies_yml_dict = load_yml_dict(f"{project_root}/{DEPENDENCIES_FILE_NAME}")

    if "packages" in packages_yml_dict and "packages" in dependencies_yml_dict:
        msg = "The 'packages' key cannot be specified in both packages.yml and dependencies.yml"
        raise DbtProjectError(msg)
    if "projects" in packages_yml_dict:
        msg = "The 'projects' key cannot be specified in packages.yml"
        raise DbtProjectError(msg)

    packages_specified_path = PACKAGES_FILE_NAME
    packages_dict = {}
    if "packages" in dependencies_yml_dict:
        packages_dict["packages"] = dependencies_yml_dict["packages"]
        packages_specified_path = DEPENDENCIES_FILE_NAME
    else:  # don't check for "packages" here so we capture invalid keys in packages.yml
        packages_dict = packages_yml_dict

    return packages_dict, packages_specified_path

def package_config_from_data(packages_data: Dict[str, Any]) -> PackageConfig:
    if not packages_data:
        packages_data = {"packages": []}

    if PACKAGE_LOCK_HASH_KEY in packages_data:
        packages_data.pop(PACKAGE_LOCK_HASH_KEY)
    try:
        PackageConfig.validate(packages_data)
        packages = PackageConfig.from_dict(packages_data)
    except ValidationError as e:
        raise DbtProjectError(MALFORMED_PACKAGE_ERROR.format(error=str(e.message))) from e
    return packages

def _parse_versions(versions: Union[List[str], str]) -> List[VersionSpecifier]:
    """Parse multiple versions as read from disk. The versions value may be any
    one of:
        - a single version string ('>0.12.1')
        - a single string specifying multiple comma-separated versions
            ('>0.11.1,<=0.12.2')
        - an array of single-version strings (['>0.11.1', '<=0.12.2'])

    Regardless, this will return a list of VersionSpecifiers
    """
    if isinstance(versions, str):
        versions = versions.split(",")
    return [VersionSpecifier.from_version_string(v) for v in versions]

def _all_source_paths(
    model_paths: List[str],
    seed_paths: List[str],
    snapshot_paths: List[str],
    analysis_paths: List[str],
    macro_paths: List[str],
) -> List[str]:
    paths = chain(model_paths, seed_paths, snapshot_paths, analysis_paths, macro_paths)
    # Strip trailing slashes since the path is the same even though the name is not
    stripped_paths = map(lambda s: s.rstrip("/"), paths)
    return list(set(stripped_paths))

T = TypeVar("T")

def flag_or(flag: Optional[T], value: Optional[T], default: T) -> T:
    if flag is None:
        return value_or(value, default)
    else:
        return flag

def value_or(value: Optional[T], default: T) -> T:
    if value is None:
        return default
    else:
        return value

def load_raw_project(project_root: str) -> Dict[str, Any]:

    project_root = os.path.normpath(project_root)
    project_yaml_filepath = os.path.join(project_root, "dbt_project.yml")

    # get the project.yml contents
    if not path_exists(project_yaml_filepath):
        raise DbtProjectError(MISSING_DBT_PROJECT_ERROR.format(path=project_yaml_filepath))

    project_dict = _load_yaml(project_yaml_filepath)

    if not isinstance(project_dict, dict):
        raise DbtProjectError("dbt_project.yml does not parse to a dictionary")

    return project_dict

def _query_comment_from_cfg(
    cfg_query_comment: Union[QueryComment, NoValue, str, None]
) -> QueryComment:
    if not cfg_query_comment:
        return QueryComment(comment="")

    if isinstance(cfg_query_comment, str):
        return QueryComment(comment=cfg_query_comment)

    if isinstance(cfg_query_comment, NoValue):
        return QueryComment()

    return cfg_query_comment

def validate_version(dbt_version: List[VersionSpecifier], project_name: str):
    """Ensure this package works with the installed version of dbt."""
    installed = get_installed_version()
    if not versions_compatible(*dbt_version):
        msg = IMPOSSIBLE_VERSION_ERROR.format(
            package=project_name, version_spec=[x.to_version_string() for x in dbt_version]
        )
        raise DbtProjectError(msg)

    if not versions_compatible(installed, *dbt_version):
        msg = INVALID_VERSION_ERROR.format(
            package=project_name,
            installed=installed.to_version_string(),
            version_spec=[x.to_version_string() for x in dbt_version],
        )
        raise DbtProjectError(msg)

def _get_required_version(
    project_dict: Dict[str, Any],
    verify_version: bool,
) -> List[VersionSpecifier]:
    dbt_raw_version: Union[List[str], str] = ">=0.0.0"
    required = project_dict.get("require-dbt-version")
    if required is not None:
        dbt_raw_version = required

    try:
        dbt_version = _parse_versions(dbt_raw_version)
    except SemverError as e:
        raise DbtProjectError(str(e)) from e

    if verify_version:
        # no name is also an error that we want to raise
        if "name" not in project_dict:
            raise DbtProjectError(
                'Required "name" field not present in project',
            )
        validate_version(dbt_version, project_dict["name"])

    return dbt_version

@dataclass
class RenderComponents:
    project_dict: Dict[str, Any] = field(metadata=dict(description="The project dictionary"))
    packages_dict: Dict[str, Any] = field(metadata=dict(description="The packages dictionary"))
    selectors_dict: Dict[str, Any] = field(metadata=dict(description="The selectors dictionary"))

@dataclass
class PartialProject(RenderComponents):
    # This class includes the project_dict, packages_dict, selectors_dict, etc from RenderComponents
    profile_name: Optional[str] = field(
        metadata=dict(description="The unrendered profile name in the project, if set")
    )
    project_name: Optional[str] = field(
        metadata=dict(
            description=(
                "The name of the project. This should always be set and will not be rendered"
            )
        )
    )
    project_root: str = field(
        metadata=dict(description="The root directory of the project"),
    )
    verify_version: bool = field(
        metadata=dict(description=("If True, verify the dbt version matches the required version"))
    )
    packages_specified_path: str = field(
        metadata=dict(description="The filename where packages were specified")
    )

    def render_profile_name(self, renderer) -> Optional[str]:
        if self.profile_name is None:
            return None
        return renderer.render_value(self.profile_name)

    def get_rendered(
        self,
        renderer: DbtProjectYamlRenderer,
    ) -> RenderComponents:

        rendered_project = renderer.render_project(self.project_dict, self.project_root)
        rendered_packages = renderer.render_packages(
            self.packages_dict, self.packages_specified_path
        )
        rendered_selectors = renderer.render_selectors(self.selectors_dict)

        return RenderComponents(
            project_dict=rendered_project,
            packages_dict=rendered_packages,
            selectors_dict=rendered_selectors,
        )

    # Called by Project.from_project_root (not PartialProject.from_project_root!)
    def render(self, renderer: DbtProjectYamlRenderer) -> "Project":
        try:
            rendered = self.get_rendered(renderer)
            return self.create_project(rendered)
        except DbtProjectError as exc:
            if exc.path is None:
                exc.path = os.path.join(self.project_root, "dbt_project.yml")
            raise

    def render_package_metadata(self, renderer: PackageRenderer) -> ProjectPackageMetadata:
        packages_data = renderer.render_data(self.packages_dict)
        packages_config = package_config_from_data(packages_data)
        if not self.project_name:
            raise DbtProjectError("Package dbt_project.yml must have a name!")
        return ProjectPackageMetadata(self.project_name, packages_config.packages)

    def check_config_path(
        self, project_dict, deprecated_path, expected_path=None, default_value=None
    ):
        if deprecated_path in project_dict:
            if expected_path in project_dict:
                msg = (
                    "{deprecated_path} and {expected_path} cannot both be defined. The "
                    "`{deprecated_path}` config has been deprecated in favor of `{expected_path}`. "
                    "Please update your `dbt_project.yml` configuration to reflect this "
                    "change."
                )
                raise DbtProjectError(
                    msg.format(deprecated_path=deprecated_path, expected_path=expected_path)
                )
            # this field is no longer supported, but many projects may specify it with the default value
            # if so, let's only raise this deprecation warning if they set a custom value
            if not default_value or project_dict[deprecated_path] != default_value:
                kwargs = {"deprecated_path": deprecated_path}
                if expected_path:
                    kwargs.update({"exp_path": expected_path})
                deprecations.warn(f"project-config-{deprecated_path}", **kwargs)

    def create_project(self, rendered: RenderComponents) -> "Project":
        unrendered = RenderComponents(
            project_dict=self.project_dict,
            packages_dict=self.packages_dict,
            selectors_dict=self.selectors_dict,
        )
        dbt_version = _get_required_version(
            rendered.project_dict,
            verify_version=self.verify_version,
        )

        self.check_config_path(rendered.project_dict, "source-paths", "model-paths")
        self.check_config_path(rendered.project_dict, "data-paths", "seed-paths")
        self.check_config_path(rendered.project_dict, "log-path", default_value="logs")
        self.check_config_path(rendered.project_dict, "target-path", default_value="target")

        try:
            ProjectContract.validate(rendered.project_dict)
            cfg = ProjectContract.from_dict(rendered.project_dict)
        except ValidationError as e:
            raise ProjectContractError(e) from e
        # name/version are required in the Project definition, so we can assume
        # they are present
        name = cfg.name
        version = cfg.version
        # this is added at project_dict parse time and should always be here
        # once we see it.
        if cfg.project_root is None:
            raise DbtProjectError("cfg must have a project root!")
        else:
            project_root = cfg.project_root
        # this is only optional in the sense that if it's not present, it needs
        # to have been a cli argument.
        profile_name = cfg.profile
        # these are all the defaults

        # `source_paths` is deprecated but still allowed. Copy it into
        # `model_paths` to simlify logic throughout the rest of the system.
        model_paths: List[str] = value_or(
            cfg.model_paths if "model-paths" in rendered.project_dict else cfg.source_paths,
            ["models"],
        )
        macro_paths: List[str] = value_or(cfg.macro_paths, ["macros"])
        # `data_paths` is deprecated but still allowed. Copy it into
        # `seed_paths` to simlify logic throughout the rest of the system.
        seed_paths: List[str] = value_or(
            cfg.seed_paths if "seed-paths" in rendered.project_dict else cfg.data_paths, ["seeds"]
        )
        test_paths: List[str] = value_or(cfg.test_paths, ["tests"])
        analysis_paths: List[str] = value_or(cfg.analysis_paths, ["analyses"])
        snapshot_paths: List[str] = value_or(cfg.snapshot_paths, ["snapshots"])

        all_source_paths: List[str] = _all_source_paths(
            model_paths, seed_paths, snapshot_paths, analysis_paths, macro_paths
        )

        docs_paths: List[str] = value_or(cfg.docs_paths, all_source_paths)
        asset_paths: List[str] = value_or(cfg.asset_paths, [])
        flags = get_flags()

        flag_target_path = str(flags.TARGET_PATH) if flags.TARGET_PATH else None
        target_path: str = flag_or(flag_target_path, cfg.target_path, "target")
        log_path: str = str(flags.LOG_PATH)

        clean_targets: List[str] = value_or(cfg.clean_targets, [target_path])
        packages_install_path: str = value_or(cfg.packages_install_path, "dbt_packages")
        # in the default case we'll populate this once we know the adapter type
        # It would be nice to just pass along a Quoting here, but that would
        # break many things
        quoting: Dict[str, Any] = {}
        if cfg.quoting is not None:
            quoting = cfg.quoting.to_dict(omit_none=True)

        dispatch: List[Dict[str, Any]]
        models: Dict[str, Any]
        seeds: Dict[str, Any]
        snapshots: Dict[str, Any]
        sources: Dict[str, Any]
        tests: Dict[str, Any]
        metrics: Dict[str, Any]
        semantic_models: Dict[str, Any]
        saved_queries: Dict[str, Any]
        exposures: Dict[str, Any]
        vars_value: VarProvider
        dbt_cloud: Dict[str, Any]

        dispatch = cfg.dispatch
        models = cfg.models
        seeds = cfg.seeds
        snapshots = cfg.snapshots
        sources = cfg.sources
        tests = cfg.tests
        metrics = cfg.metrics
        semantic_models = cfg.semantic_models
        saved_queries = cfg.saved_queries
        exposures = cfg.exposures
        if cfg.vars is None:
            vars_dict: Dict[str, Any] = {}
        else:
            vars_dict = cfg.vars

        vars_value = VarProvider(vars_dict)
        # There will never be any project_env_vars when it's first created
        project_env_vars: Dict[str, Any] = {}
        on_run_start: List[str] = value_or(cfg.on_run_start, [])
        on_run_end: List[str] = value_or(cfg.on_run_end, [])

        query_comment = _query_comment_from_cfg(cfg.query_comment)

        packages: PackageConfig = package_config_from_data(rendered.packages_dict)
        selectors = selector_config_from_data(rendered.selectors_dict)
        manifest_selectors: Dict[str, Any] = {}
        if rendered.selectors_dict and rendered.selectors_dict["selectors"]:
            # this is a dict with a single key 'selectors' pointing to a list
            # of dicts.
            manifest_selectors = SelectorDict.parse_from_selectors_list(
                rendered.selectors_dict["selectors"]
            )
        dbt_cloud = cfg.dbt_cloud

        project = Project(
            project_name=name,
            version=version,
            project_root=project_root,
            profile_name=profile_name,
            model_paths=model_paths,
            macro_paths=macro_paths,
            seed_paths=seed_paths,
            test_paths=test_paths,
            analysis_paths=analysis_paths,
            docs_paths=docs_paths,
            asset_paths=asset_paths,
            target_path=target_path,
            snapshot_paths=snapshot_paths,
            clean_targets=clean_targets,
            log_path=log_path,
            packages_install_path=packages_install_path,
            packages_specified_path=self.packages_specified_path,
            quoting=quoting,
            models=models,
            on_run_start=on_run_start,
            on_run_end=on_run_end,
            dispatch=dispatch,
            seeds=seeds,
            snapshots=snapshots,
            dbt_version=dbt_version,
            packages=packages,
            manifest_selectors=manifest_selectors,
            selectors=selectors,
            query_comment=query_comment,
            sources=sources,
            tests=tests,
            metrics=metrics,
            semantic_models=semantic_models,
            saved_queries=saved_queries,
            exposures=exposures,
            vars=vars_value,
            config_version=cfg.config_version,
            unrendered=unrendered,
            project_env_vars=project_env_vars,
            restrict_access=cfg.restrict_access,
            dbt_cloud=dbt_cloud,
        )
        # sanity check - this means an internal issue
        project.validate()
        return project

    @classmethod
    def from_dicts(
        cls,
        project_root: str,
        project_dict: Dict[str, Any],
        packages_dict: Dict[str, Any],
        selectors_dict: Dict[str, Any],
        *,
        verify_version: bool = False,
        packages_specified_path: str = PACKAGES_FILE_NAME,
    ):
        """Construct a partial project from its constituent dicts."""
        project_name = project_dict.get("name")
        profile_name = project_dict.get("profile")

        # Create a PartialProject
        return cls(
            profile_name=profile_name,
            project_name=project_name,
            project_root=project_root,
            project_dict=project_dict,
            packages_dict=packages_dict,
            selectors_dict=selectors_dict,
            verify_version=verify_version,
            packages_specified_path=packages_specified_path,
        )

    @classmethod
    def from_project_root(
        cls, project_root: str, *, verify_version: bool = False
    ) -> "PartialProject":
        project_root = os.path.normpath(project_root)
        project_dict = load_raw_project(project_root)
        (
            packages_dict,
            packages_specified_path,
        ) = package_and_project_data_from_root(project_root)
        selectors_dict = selector_data_from_root(project_root)

        return cls.from_dicts(
            project_root=project_root,
            project_dict=project_dict,
            selectors_dict=selectors_dict,
            packages_dict=packages_dict,
            verify_version=verify_version,
            packages_specified_path=packages_specified_path,
        )

class VarProvider:
    """Var providers are tied to a particular Project."""

    def __init__(self, vars: Dict[str, Dict[str, Any]]) -> None:
        self.vars = vars

    def vars_for(self, node: IsFQNResource, adapter_type: str) -> Mapping[str, Any]:
        # in v2, vars are only either project or globally scoped
        merged = MultiDict([self.vars])
        merged.add(self.vars.get(node.package_name, {}))
        return merged

    def to_dict(self):
        return self.vars

# The Project class is included in RuntimeConfig, so any attribute
# additions must also be set where the RuntimeConfig class is created
@dataclass
class Project:
    project_name: str
    version: Optional[Union[SemverString, float]]
    project_root: str
    profile_name: Optional[str]
    model_paths: List[str]
    macro_paths: List[str]
    seed_paths: List[str]
    test_paths: List[str]
    analysis_paths: List[str]
    docs_paths: List[str]
    asset_paths: List[str]
    target_path: str
    snapshot_paths: List[str]
    clean_targets: List[str]
    log_path: str
    packages_install_path: str
    packages_specified_path: str
    quoting: Dict[str, Any]
    models: Dict[str, Any]
    on_run_start: List[str]
    on_run_end: List[str]
    dispatch: List[Dict[str, Any]]
    seeds: Dict[str, Any]
    snapshots: Dict[str, Any]
    sources: Dict[str, Any]
    tests: Dict[str, Any]
    metrics: Dict[str, Any]
    semantic_models: Dict[str, Any]
    saved_queries: Dict[str, Any]
    exposures: Dict[str, Any]
    vars: VarProvider
    dbt_version: List[VersionSpecifier]
    packages: PackageConfig
    manifest_selectors: Dict[str, Any]
    selectors: SelectorConfig
    query_comment: QueryComment
    config_version: int
    unrendered: RenderComponents
    project_env_vars: Dict[str, Any]
    restrict_access: bool
    dbt_cloud: Dict[str, Any]

    @property
    def all_source_paths(self) -> List[str]:
        return _all_source_paths(
            self.model_paths,
            self.seed_paths,
            self.snapshot_paths,
            self.analysis_paths,
            self.macro_paths,
        )

    @property
    def generic_test_paths(self):
        generic_test_paths = []
        for test_path in self.test_paths:
            generic_test_paths.append(os.path.join(test_path, "generic"))
        return generic_test_paths

    def __str__(self):
        cfg = self.to_project_config(with_packages=True)
        return str(cfg)

    def __eq__(self, other):
        if not (isinstance(other, self.__class__) and isinstance(self, other.__class__)):
            return False
        return self.to_project_config(with_packages=True) == other.to_project_config(
            with_packages=True
        )

    def to_project_config(self, with_packages=False):
        """Return a dict representation of the config that could be written to
        disk with `yaml.safe_dump` to get this configuration.

        :param with_packages bool: If True, include the serialized packages
            file in the root.
        :returns dict: The serialized profile.
        """
        result = deepcopy(
            {
                "name": self.project_name,
                "version": self.version,
                "project-root": self.project_root,
                "profile": self.profile_name,
                "model-paths": self.model_paths,
                "macro-paths": self.macro_paths,
                "seed-paths": self.seed_paths,
                "test-paths": self.test_paths,
                "analysis-paths": self.analysis_paths,
                "docs-paths": self.docs_paths,
                "asset-paths": self.asset_paths,
                "target-path": self.target_path,
                "snapshot-paths": self.snapshot_paths,
                "clean-targets": self.clean_targets,
                "log-path": self.log_path,
                "quoting": self.quoting,
                "models": self.models,
                "on-run-start": self.on_run_start,
                "on-run-end": self.on_run_end,
                "dispatch": self.dispatch,
                "seeds": self.seeds,
                "snapshots": self.snapshots,
                "sources": self.sources,
                "tests": self.tests,
                "metrics": self.metrics,
                "semantic-models": self.semantic_models,
                "saved-queries": self.saved_queries,
                "exposures": self.exposures,
                "vars": self.vars.to_dict(),
                "require-dbt-version": [v.to_version_string() for v in self.dbt_version],
                "config-version": self.config_version,
                "restrict-access": self.restrict_access,
                "dbt-cloud": self.dbt_cloud,
            }
        )
        if self.query_comment:
            result["query-comment"] = self.query_comment.to_dict(omit_none=True)

        if with_packages:
            result.update(self.packages.to_dict(omit_none=True))

        return result

    def validate(self):
        try:
            ProjectContract.validate(self.to_project_config())
        except ValidationError as e:
            raise ProjectContractBrokenError(e) from e

    # Called by:
    # RtConfig.load_dependencies => RtConfig.load_projects => RtConfig.new_project => Project.from_project_root
    # RtConfig.from_args => RtConfig.collect_parts => load_project => Project.from_project_root
    @classmethod
    def from_project_root(
        cls,
        project_root: str,
        renderer: DbtProjectYamlRenderer,
        *,
        verify_version: bool = False,
    ) -> "Project":
        partial = PartialProject.from_project_root(project_root, verify_version=verify_version)
        return partial.render(renderer)

    def hashed_name(self):
        return md5(self.project_name)

    def get_selector(self, name: str) -> Union[SelectionSpec, bool]:
        if name not in self.selectors:
            raise DbtRuntimeError(
                f"Could not find selector named {name}, expected one of {list(self.selectors)}"
            )
        return self.selectors[name]["definition"]

    def get_default_selector_name(self) -> Union[str, None]:
        """This function fetch the default selector to use on `dbt run` (if any)
        :return: either a selector if default is set or None
        :rtype: Union[SelectionSpec, None]
        """
        for selector_name, selector in self.selectors.items():
            if selector["default"] is True:
                return selector_name

        return None

    def get_macro_search_order(self, macro_namespace: str):
        for dispatch_entry in self.dispatch:
            if dispatch_entry["macro_namespace"] == macro_namespace:
                return dispatch_entry["search_order"]
        return None

    @property
    def project_target_path(self):
        # If target_path is absolute, project_root will not be included
        return os.path.join(self.project_root, self.target_path)


#!/usr/bin/python
# coding=utf8

import unicodedata
from Foundation import NSUserDefaults, NSCFDictionary, NSGlobalDomain
import sqlite3
import time
import os

def my_replacements():
    for code in range(ord(u'α'), ord(u'ω') + 1):
        char = unichr(code)
        name =unicodedata.name(char)
        assert name.startswith("GREEK SMALL LETTER ")
        name = name[len("GREEK SMALL LETTER "):].lower().replace(' ', '')
        replace = '\\' + name
        yield (replace, char)

def add_replacements_to_defaults():
    defaults = NSUserDefaults.standardUserDefaults()
    replacements = defaults.objectForKey_('NSUserDictionaryReplacementItems').mutableCopy()
    existing = set( x['replace'] for x in replacements )
    for key,value in my_replacements():
        if not key in existing:
            replacements.append({'replace': key,
                                 'with'   : value,
                                 'on'     : 1})
            defaults.setObject_forKey_inDomain_(replacements, 'NSUserDictionaryReplacementItems', NSGlobalDomain)
    defaults.synchronize()

def add_replacements_to_sqlite(filename):
    sql = sqlite3.connect(filename)
    for key,value in my_replacements():
        cur = sql.cursor()
        cur.execute("SELECT Z_PK FROM ZUSERDICTIONARYENTRY WHERE ZSHORTCUT == ?", (key,))
        if not len(cur.fetchall()):
            cur.execute(
                "INSERT INTO ZUSERDICTIONARYENTRY(Z_ENT, Z_OPT, ZTIMESTAMP, ZPHRASE, ZSHORTCUT) VALUES(1, 1, ?, ?, ?);",
                (int(time.time()), value, key))
            cur.fetchall()
    sql.commit()

add_replacements_to_defaults()

for root, dirs, files in os.walk(os.path.join(os.getenv("HOME"), "Library/Dictionaries/CoreDataUbiquitySupport")):
    for name in files:
        if name.endswith(".db"):
            add_replacements_to_sqlite(os.path.join(root, name))


from scipy.spatial import distance
from imutils import face_utils
import imutils
import dlib
import cv2
from pygame import mixer
mixer.init()
sound = mixer.Sound('alert.wav')
font = cv2.FONT_HERSHEY_COMPLEX_SMALL

def eye_aspect_ratio(eye):
	A = distance.euclidean(eye[1], eye[5])
	B = distance.euclidean(eye[2], eye[4])
	C = distance.euclidean(eye[0], eye[3])
	ear = (A + B) / (2.0 * C)
	return ear

thresh = 0.25
frame_check = 20
detect = dlib.get_frontal_face_detector()
predict = dlib.shape_predictor("models/shape_predictor_68_face_landmarks.dat")# Dat file is the crux of the code
facecascode=cv2.CascadeClassifier("C:\\Users\\ACER\\PycharmProjects\\weed\\venv\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_alt.xml")
(lStart, lEnd) = face_utils.FACIAL_LANDMARKS_68_IDXS["left_eye"]
(rStart, rEnd) = face_utils.FACIAL_LANDMARKS_68_IDXS["right_eye"]
cap=cv2.VideoCapture(0)
flag=0
while True:
	ret, frame=cap.read()
	imggray=cv2.cvtColor(frame,cv2.COLOR_RGB2GRAY)
	faces=facecascode.detectMultiScale(imggray,1.1,4)

	frame = imutils.resize(frame, width=450)
	gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
	subjects = detect(gray, 0)
	for subject in subjects:
		shape = predict(gray, subject)
		shape = face_utils.shape_to_np(shape)#converting to NumPy Array
		leftEye = shape[lStart:lEnd]
		rightEye = shape[rStart:rEnd]
		leftEAR = eye_aspect_ratio(leftEye)
		rightEAR = eye_aspect_ratio(rightEye)
		ear = (leftEAR + rightEAR) / 2.0
		leftEyeHull = cv2.convexHull(leftEye)
		rightEyeHull = cv2.convexHull(rightEye)
		cv2.drawContours(frame, [leftEyeHull], -1, (0, 255, 0), 1)
		cv2.drawContours(frame, [rightEyeHull], -1, (0, 255, 0), 1)
		cv2.putText(frame,'Score:'+str(flag),(10,30), font,0.7,(0,255,0),2)
		if ear < thresh:

			flag += 1
			print (flag)
			if flag >= frame_check:
				cv2.putText(frame, "****************ALERT!****************", (10, 30),
					cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
				cv2.putText(frame, "****************ALERT!****************", (10,325),
					cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
				#print ("Drowsy")
                #person is feeling sleepy so we beep the alarm
				try:
					sound.play()
				except:

					pass
		else:

			flag = 0
	for (x,y,w,h) in faces:
		# w=w/2
		# h=h/2
		cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
	cv2.imshow("Frame", frame)
	key = cv2.waitKey(1) & 0xFF
	if key == ord("q"):
		break
cv2.destroyAllWindows()
cap.release()


# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        if l1 is None:
            return l2
        elif l2 is None:
            return l1

        head = ListNode(0)
        p = ListNode(0)
        q = ListNode(0)
        r = ListNode(0)

        p.next =l1
        q.next =l2
        r.next =head
        while p.next is not None and q.next is not None:
            if p.next.val <= q.next.val:
                r.next.next = p.next
                p.next = p.next.next
            else:
                r.next.next = q.next
                q.next = q.next.next

            r.next = r.next.next

        if p.next is None:
            r.next.next = q.next
        else:
            r.next.next = p.next

        return head.next

def buildList(a:list)->ListNode:
    head = ListNode(0)
    p = ListNode(0)
    p.next = head

    for x in a:
        p.next.next = ListNode(x)
        p.next = p.next.next

    return head.next

l1 = buildList([1,2,4])
l2 = buildList([1,3,4,5,6,7])
result = Solution().mergeTwoLists(l1, l2)
p = ListNode(0)
p.next = result
while p.next is not None:
    print(p.next.val)
    p.next = p.next.next


#! /usr/bin/env python
"""
Script to make a normal sky model from a polynomial sky model
"""
import argparse
from argparse import RawTextHelpFormatter
from astropy.io import fits
from astropy import wcs
import numpy as np
from numpy.polynomial.polynomial import polyval
import casacore.tables as pt
import lsmtool
import re
import sys
import os
import glob

def main(model_root, ms_file, skymodel, fits_mask=None, min_peak_flux_jy=0.0001,
    max_residual_jy=0.0):
    """
    Make a makesourcedb sky model for input MS from WSClean fits model images

    Parameters
    ----------
    model_root : str
        Root name of WSClean polynomial model sky model
    ms_file : str
        Filename of MS for which sky model is to be made. Can be a list of files
        (e.g., '[ms1,ms2,...]', in which case they should all have the same
        frequency
    skymodel : str
        Filename of the output makesourcedb sky model
    fits_mask : str, optional
        Filename of fits mask
    min_peak_flux_jy : float, optional
        Minimum absolute value of flux in Jy of a source in lowest-frequency model image
        to include in output model
    max_residual_jy : float, optional
        Maximum acceptible total residual absolute flux in Jy

    """
    min_peak_flux_jy = float(min_peak_flux_jy)
    max_residual_jy = float(max_residual_jy)

    if type(fits_mask) is str:
        if fits_mask.lower() == 'none':
            fits_mask = None

    # Read MS file and get the frequency info
    if '[' in ms_file and ']' in ms_file:
        files = ms_file.strip('[]').split(',')
        files = [f.strip() for f in files]
        ms_file = files[0]
    sw = pt.table(ms_file+'::SPECTRAL_WINDOW', ack=False)
    ms_freq = sw.col('REF_FREQUENCY')[0]
    sw.close()

    # Read in sky model
    polymodel = model_root + '-sources.txt'
    s = lsmtool.load(polymodel)
    ref_freq = float(s.getColValues('ReferenceFrequency')[0]) # Hz

    # Find model images and read in frequencies
    fits_models = glob.glob(model_root+'-00*-model.fits')
    if len(fits_models) == 0:
        # No channels images found, so look for non-MFS images
        fits_models = glob.glob(model_root+'-model.fits')
    if len(fits_models) == 0:
        print('ERROR: no model images found')
        sys.exit(1)
    freqs = []
    for f in fits_models:
        # Get the frequency info
        hdr = fits.getheader(f, 0, ignore_missing_end=True)
        freqs.append(hdr['CRVAL3']) # Hz

    # Determine nearest model frequency to MS frequency. We will use this to
    # get the fluxes (to match the frequency blocks used during imaging and
    # calibration)
    sky_freq = min(freqs, key=lambda x:abs(x-ms_freq))

    # Check if fits mask is empty
    if fits_mask is not None:
        if fits_mask.lower() == 'empty':
            # Handle case in which no sources were found during masking
            s.remove(np.array(range(len(s))))
            mask = None
        else:
            mask = fits.getdata(fits_mask, 0, ignore_missing_end=True)
            hdr = fits.getheader(fits_mask, 0, ignore_missing_end=True)
            w = wcs.WCS(hdr)
    else:
        mask = None

    # Discard components not in the mask, if given
    if mask is not None:
        pix = w.wcs_world2pix(np.array([s.getColValues('RA'), s.getColValues('Dec'),
            [0]*len(s), [0]*len(s)]).T, 0)
        not_in_mask = []
        for i, p in enumerate(pix):
            if mask[0, 0, int(round(p[1])), int(round(p[0]))] < 1:
                not_in_mask.append(i)
        s.remove(np.array(not_in_mask))

    # Set fluxes and ref frequency
    specterms = s.getColValues('SpectralIndex')
    stokesI = s.getColValues('I')
    fluxes = []
    for i in range(len(s)):
        # Find flux as follows:
        #     flux(nu) = stokesI + term0 (nu/refnu - 1) + term1 (nu/refnu - 1)^2 + ...,
        # where nu = sky_freq and refnu = ref_freq
        polyterms = specterms[i].tolist()
        polyterms.insert(0, stokesI[i])
        fluxes.append(polyval(sky_freq/ref_freq-1.0, polyterms))
    s.setColValues('I', fluxes)
    s.setColValues('ReferenceFrequency', [ms_freq]*len(s))

    # Remove spectral index values
    s.table.remove_column('SpectralIndex')
    s.table.remove_column('LogarithmicSI')

    # Write the new sky model
    s.write(fileName=skymodel, clobber=True)

if __name__ == '__main__':
    descriptiontext = "Make a makesourcedb sky model from WSClean fits model images.\n"

    parser = argparse.ArgumentParser(description=descriptiontext, formatter_class=RawTextHelpFormatter)
    parser.add_argument('fits_model_root', help='Root of model images')
    parser.add_argument('ms_file', help='Filename of MS for which sky model is to be made')
    parser.add_argument('skymodel', help='Filename of output sky model')
    parser.add_argument('-f', '--fits_mask', help='Filename of fits mask', type=str, default=None)
    parser.add_argument('-p', '--min_peak_flux_jy', help='Minimum absolute value of flux in Jy', type=float, default=0.0001)
    parser.add_argument('-r', '--max_residual_jy', help='Maximum acceptible total residual absolute flux in Jy', type=float, default=0.0)
    args = parser.parse_args()
    main(args.fits_model_root, args.ms_file, args.skymodel, fits_mask=args.fits_mask,
        min_peak_flux_jy=args.min_peak_flux_jy, max_residual_jy=args.max_residual_jy)


import io
from typing import List, Optional, Tuple

import brax
from brax import base
from brax import math
import jax
from jax import numpy as jp
import numpy as onp
from PIL import Image
from pytinyrenderer import TinyRenderCamera as Camera
from pytinyrenderer import TinyRenderLight as Light
from pytinyrenderer import TinySceneRenderer as Renderer
import trimesh

class TextureRGB888:

  def __init__(self, pixels):
    self.pixels = pixels
    self.width = int(onp.sqrt(len(pixels) / 3))
    self.height = int(onp.sqrt(len(pixels) / 3))

class Grid(TextureRGB888):

  def __init__(self, grid_size, color):
    grid = onp.zeros((grid_size, grid_size, 3), dtype=onp.int32)
    grid[:, :] = onp.array(color)
    grid[0] = onp.zeros((grid_size, 3), dtype=onp.int32)
    grid[:, 0] = onp.zeros((grid_size, 3), dtype=onp.int32)
    super().__init__(list(grid.ravel()))

_BASIC = TextureRGB888([133, 118, 102])
_TARGET = TextureRGB888([255, 34, 34])
_GROUND = Grid(100, [200, 200, 200])

def _scene(sys: brax.System, state: brax.State) -> Tuple[Renderer, List[int]]:
  """Converts a brax System and state to a pytinyrenderer scene and instances."""
  scene = Renderer()
  instances = []

  def take_i(obj, i):
    return jax.tree_map(lambda x: jp.take(x, i, axis=0), obj)

  link_names = [n or f'link {i}' for i, n in enumerate(sys.link_names)]
  link_names += ['world']
  link_geoms = {}
  for batch in sys.geoms:
    num_geoms = len(batch.friction)
    for i in range(num_geoms):
      link_idx = -1 if batch.link_idx is None else batch.link_idx[i]
      link_geoms.setdefault(link_names[link_idx], []).append(take_i(batch, i))

  for _, geom in link_geoms.items():
    for col in geom:
      tex = TextureRGB888((col.rgba[:3] * 255).astype('uint32'))
      if isinstance(col, base.Capsule):
        half_height = col.length / 2
        model = scene.create_capsule(col.radius, half_height, 2,
                                     tex.pixels, tex.width, tex.height)
      elif isinstance(col, base.Box):
        model = scene.create_cube(col.halfsize, tex.pixels, tex.width,
                                  tex.height, 16.)
      elif isinstance(col, base.Sphere):
        model = scene.create_capsule(
            col.radius, 0, 2, tex.pixels, tex.width, tex.height
        )
      elif isinstance(col, base.Plane):
        tex = _GROUND
        model = scene.create_cube([1000.0, 1000.0, 0.0001], tex.pixels,
                                  tex.width, tex.height, 8192)
      elif isinstance(col, base.Convex):
        # convex objects are not visual
        continue
      elif isinstance(col, base.Mesh):
        tm = trimesh.Trimesh(vertices=col.vert, faces=col.face)
        vert_norm = tm.vertex_normals
        model = scene.create_mesh(
            col.vert.reshape((-1)).tolist(),
            vert_norm.reshape((-1)).tolist(),
            [0] * col.vert.shape[0] * 2,
            col.face.reshape((-1)).tolist(),
            tex.pixels,
            tex.width,
            tex.height,
            1.0,
        )
      else:
        raise RuntimeError(f'unrecognized collider: {type(col)}')

      i = col.link_idx if col.link_idx is not None else -1
      x = state.x.concatenate(base.Transform.zero((1,)))
      instance = scene.create_object_instance(model)
      off = col.transform.pos
      pos = onp.array(x.pos[i]) + math.rotate(off, x.rot[i])
      rot = col.transform.rot
      rot = math.quat_mul(x.rot[i], rot)
      scene.set_object_position(instance, list(pos))
      scene.set_object_orientation(instance, [rot[1], rot[2], rot[3], rot[0]])
      instances.append(instance)

  return scene, instances

def _eye(sys: brax.System, state: brax.State) -> List[float]:
  """Determines the camera location for a Brax system."""
  xj = state.x.vmap().do(sys.link.joint)
  dist = onp.concatenate(xj.pos[None, ...] - xj.pos[:, None, ...])
  dist = onp.linalg.norm(dist, axis=1).max()
  off = [2 * dist, -2 * dist, dist]
  return list(state.x.pos[0, :] + onp.array(off))

def _up(unused_sys: brax.System) -> List[float]:
  """Determines the up orientation of the camera."""
  return [0, 0, 1]

def get_camera(
    sys: brax.System, state: brax.State, width: int, height: int, ssaa: int = 2
) -> Camera:
  """Gets camera object."""
  eye, up = _eye(sys, state), _up(sys)
  hfov = 58.0
  vfov = hfov * height / width
  target = [state.x.pos[0, 0], state.x.pos[0, 1], 0]
  camera = Camera(
      viewWidth=width * ssaa,
      viewHeight=height * ssaa,
      position=eye,
      target=target,
      up=up,
      hfov=hfov,
      vfov=vfov)
  return camera

def render_array(sys: brax.System,
                 state: brax.State,
                 width: int,
                 height: int,
                 light: Optional[Light] = None,
                 camera: Optional[Camera] = None,
                 ssaa: int = 2) -> onp.ndarray:
  """Renders an RGB array of a brax system and QP."""
  if (len(state.x.pos.shape), len(state.x.rot.shape)) != (2, 2):
    raise RuntimeError('unexpected shape in state')
  scene, instances = _scene(sys, state)
  target = state.x.pos[0, :]
  if light is None:
    direction = [0.57735, -0.57735, 0.57735]
    light = Light(
        direction=direction,
        ambient=0.8,
        diffuse=0.8,
        specular=0.6,
        shadowmap_center=target)
  if camera is None:
    eye, up = _eye(sys, state), _up(sys)
    hfov = 58.0
    vfov = hfov * height / width
    camera = Camera(
        viewWidth=width * ssaa,
        viewHeight=height * ssaa,
        position=eye,
        target=target,
        up=up,
        hfov=hfov,
        vfov=vfov)
  img = scene.get_camera_image(instances, light, camera).rgb
  arr = onp.reshape(
      onp.array(img, dtype=onp.uint8),
      (camera.view_height, camera.view_width, -1))
  if ssaa > 1:
    arr = onp.asarray(Image.fromarray(arr).resize((width, height)))
  return arr

def render(sys: brax.System,
           states: List[brax.State],
           width: int,
           height: int,
           light: Optional[Light] = None,
           cameras: Optional[List[Camera]] = None,
           ssaa: int = 2,
           fmt='png') -> bytes:
  """Returns an image of a brax system and QP."""
  if not states:
    raise RuntimeError('must have at least one qp')
  if cameras is None:
    cameras = [None] * len(states)

  frames = [
      Image.fromarray(
          render_array(sys, state, width, height, light, camera, ssaa))
      for state, camera in zip(states, cameras)
  ]
  f = io.BytesIO()
  if len(frames) == 1:
    frames[0].save(f, format=fmt)
  else:
    frames[0].save(
        f,
        format=fmt,
        append_images=frames[1:],
        save_all=True,
        duration=sys.dt * 1000,
        loop=0)
  return f.getvalue()


import unittest

from longest_substring_without_repeating_characters import LongestSubstringWithoutRepeatingCharacters

class LongestSubstringWithoutRepeatingCharactersTest(unittest.TestCase):
    def test_solution(self):
        testCases = [
            {
                "s": "abcabcbb",
                "expected": 3
            },
            {
                "s": "bbbbb",
                "expected": 1
            },
            {
                "s": "pwwkew",
                "expected": 3
            },
            {
                "s": "",
                "expected": 0
            }
        ]

        for case in testCases:
            actual = LongestSubstringWithoutRepeatingCharacters.solution(self, case["s"])
            actual2 = LongestSubstringWithoutRepeatingCharacters.solution2(self, case["s"])

            self.assertEqual(case["expected"], actual)
            self.assertEqual(case["expected"], actual2)

if __name__ == '__main__':
    unittest.main()


from django.urls import path, include
from rest_framework.routers import DefaultRouter
from rest_framework_simplejwt import views as jwt_views

from users.api.views import TeacherViewSet, AdvisorViewSet, StudentViewSet, UserLoginView, AdvisorStudentsView, \
    AdvisorStudentsDetailView, AdminsViewSet

router = DefaultRouter()
router.register('students', StudentViewSet)
router.register('teachers', TeacherViewSet)
router.register('advisors', AdvisorViewSet)
router.register('admins', AdminsViewSet)

urlpatterns = [
    path('', include(router.urls)),
    path('advisor/students/', AdvisorStudentsView.as_view()),
    path('advisor/students/<int:id>/', AdvisorStudentsDetailView.as_view()),
    path('auth/login/', UserLoginView.as_view()),
    path('token/obtain/', jwt_views.TokenObtainPairView.as_view(), name='token_create'),
    path('token/refresh/', jwt_views.TokenRefreshView.as_view(), name='token_refresh'),
]


import time
import datetime  # Yeah, I'm cheating

def main():
    current_date = datetime.date(month=1, day=1, year=1901)
    last_date = datetime.date(month=12, day=31, year=2000)

    SUNDAY = 6  # According to https://docs.python.org/3/library/datetime.html#datetime.date.weekday

    days = 0

    one_day = datetime.timedelta(days=1)

    while current_date < last_date:
        if current_date.day == 1 and current_date.weekday() == SUNDAY:
            days += 1
        current_date += one_day

    print(days)

if __name__ == "__main__":
    start_time = time.time()
    main()
    elapsed_time = time.time() - start_time
    print("Elapsed Time: ", elapsed_time)


#!/usr/bin/env python
# Script to collect human demonstrations in Playwright-Gym environments

from argparse import ArgumentParser

import cv2
import gym
import numpy as np
import playwrightgym

parser = ArgumentParser("playwright-gym_human_player")
parser.add_argument(
    "--env-name",
    default="LoginFormVisual-v0",
    help="playwright-gym Env name. Default=LoginFormVisual-v0",
)
parser.add_argument(
    "--num-episodes", default=2, help="Number of episodes to play. Default=2"
)

class Demonstrator(object):
    def __init__(self, env_name: str):
        self.env_name = env_name
        self.env = gym.make(self.env_name)
        self.window_name = "Playwright-Gym-demo-collector"
        cv2.namedWindow(self.window_name)
        cv2.setMouseCallback(self.window_name, self.mouse_handler)
        self.obs = np.zeros(self.env.observation_space.shape)
        self.action = {"x": 0, "y": 0, "key_idx": 0}
        # Create a key_action_map: {keyboard_char: key_idx}
        self.ord_key_action_map = {
            v: k for k, v in playwrightgym.ACTION_KEY_MAP.items()
        }

    def mouse_handler(self, event, x, y, flags, params):
        if event == cv2.EVENT_LBUTTONDOWN:
            self.action["x"], self.action["y"] = x, y
            cv2.circle(
                self.obs, (x, y), radius=5, color=(0, 255, 0), thickness=cv2.FILLED
            )
            # Refresh the window to show the circle drawn on self.obs
            cv2.imshow(self.window_name, self.obs)

    def get_action(self, obs):
        """Show obs to human, get demo action

        Args:
            obs (env.observation_space): Obs
        """
        self.obs = obs
        cv2.imshow(self.window_name, obs)
        print("Listening for mouse click event & waiting for key input")
        key = cv2.waitKey(0)  # Blocking request for keyboard input
        key_char = chr(key).upper()

        if key_char in self.ord_key_action_map:
            self.action["key_idx"] = self.ord_key_action_map[key_char]
        else:
            self.action["key_idx"] = 0  # NOKEY
        return np.array([self.action["x"], self.action["y"], self.action["key_idx"]])

if __name__ == "__main__":
    args = parser.parse_args()
    demonstrator = Demonstrator(args.env_name)
    for ep in range(args.num_episodes):
        done = False
        obs = demonstrator.env.reset()
        step = 0
        while not done:
            action = demonstrator.get_action(obs)
            obs, reward, done, info = demonstrator.env.step(action)
            print(f"Ep#:{ep} step#:{step} action:{action} rew:{reward} done:{done}")
            step += 1


import matplotlib.pyplot as plt
import pandas as pd
semana = list()
agencia_id = list()
canal_id = list()
ruta_sak = list()
cliente_id = list()
producto_id = list()
venta_uni_hoy = list()
dev_uni_proxima = list()
dev_proxima = list()
demand_uni_equil = list()
venta_hoy = list()

dataset_path = 'D:/FYP-Developments/Dataset-Kaggale/MedianRejectionSamplingData/train.csv'

for df in pd.read_csv(dataset_path,sep=',', header = None, chunksize=1):# split line into df
    demand_uni_equil.append(df[10][0])
    agencia_id.append(df[1][0])
    canal_id.append(df[2][0])
    ruta_sak.append(df[3][0])
    cliente_id.append(df[4][0])
    producto_id.append(df[5][0])
    venta_uni_hoy.append(df[6][0])
    venta_hoy.append(df[7][0])
    dev_uni_proxima.append(df[8][0])
    dev_proxima.append(df[9][0])
    semana.append(df[0][0])

figureoutfolderpath = 'D:/FYP-Developments/Dataset-Kaggale'
plt.scatter(demand_uni_equil, semana)#, s=5, c=4, alpha=0.5)
plt.ylabel('Semana')
plt.xlabel('Demand_Uni_Equil')
plt.savefig(figureoutfolderpath+'/semana.png')
# plt.show()
plt.clf()

plt.scatter(demand_uni_equil, agencia_id)#, s=5, c=4, alpha=0.5)
plt.ylabel('Agencia_ID')
plt.xlabel('Demand_Uni_Equil')
plt.savefig(figureoutfolderpath+'/agencia_id.png')
# plt.show()
plt.clf()

plt.scatter(demand_uni_equil, canal_id)#, s=5, c=4, alpha=0.5)
plt.ylabel('Canal_ID')
plt.xlabel('Demand_Uni_Equil')
plt.savefig(figureoutfolderpath+'/canal_id.png')
# plt.show()
plt.clf()

plt.scatter(demand_uni_equil, ruta_sak)#, s=5, c=4, alpha=0.5)
plt.ylabel('Ruta_Sak')
plt.xlabel('Demand_Uni_Equil')
plt.savefig(figureoutfolderpath+'/ruta_sak.png')
# plt.show()
plt.clf()

plt.scatter(demand_uni_equil, cliente_id)#, s=5, c=4, alpha=0.5)
plt.ylabel('Cliente_ID')
plt.xlabel('Demand_Uni_Equil')
plt.savefig(figureoutfolderpath+'/cliente.png')
# plt.show()
plt.clf()

plt.scatter(demand_uni_equil, producto_id)#, s=5, c=4, alpha=0.5)
plt.ylabel('Producto_ID')
plt.xlabel('Demand_Uni_Equil')
plt.savefig(figureoutfolderpath+'/producto.png')
# plt.show()
plt.clf()

plt.scatter(demand_uni_equil, venta_uni_hoy)#, s=5, c=4, alpha=0.5)
plt.ylabel('Venta_uni_hoy')
plt.xlabel('Demand_Uni_Equil')
plt.savefig(figureoutfolderpath+'/venta_uni_hoy.png')
# plt.show()
plt.clf()

plt.scatter(demand_uni_equil, venta_hoy)#, s=5, c=4, alpha=0.5)
plt.ylabel('Venta_hoy')
plt.xlabel('Demand_Uni_Equil')
plt.savefig(figureoutfolderpath+'/venta_hoy.png')
# plt.show()
plt.clf()

plt.scatter(demand_uni_equil, dev_uni_proxima)#, s=5, c=4, alpha=0.5)
plt.ylabel('Dev_uni_proxima')
plt.xlabel('Demand_Uni_Equil')
plt.savefig(figureoutfolderpath+'/dev_unit_proxima.png')
# plt.show()
plt.clf()

plt.scatter(demand_uni_equil, dev_proxima)#, s=5, c=4, alpha=0.5)
plt.ylabel('Dev_proxima')
plt.xlabel('Demand_Uni_Equil')
plt.savefig(figureoutfolderpath+'/dev_proxima.png')
# plt.show()
plt.clf()

print("All the plotted Figures are saved in the Out Folder")


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

import pandas
import logging
import sys
logger = logging.getLogger(__name__)

def sliceByTime(begin: float, end: float, column: str, drive_data: pandas.DataFrame):
	"""
		args:
			begin: float defnining the start point of the slice
			end: float defining the end part of the slice
			column: which column in the drive_data frame to use for the time.  This is usually SimTime or VidTime.
			drive_data: pandas DataFrame containing the data to be sliced

		returns:
			pandas.DataFrame slice containing requested time slice

	Given a start and end and a column name that represents a time value, output the slice that contains
	only the specified data.
	"""
	try:
		dataframeslice = drive_data[(drive_data[column] >= begin) & (drive_data[column] <= end)]
	except KeyError:
		logger.error(" Data file(-d) invalid. Data frame slice could not be created. Please check contents of file for \"VidTime\" column.")
		sys.exit(1)
	return dataframeslice

def mergeBySpace(tomerge: list):
	"""
		args:
			tomerge: list of DriveData objects to merge

		returns:
			DriveData object containing merged data and Drive ID of first element in the tomerge list

		Takes the first DriveData in 'tomerge', finds the last X and Y position, matches the closest X and Y
		position in the next DriveData object in 'tomerge'.  The time stamps for the second data list are
		altered appropriately.
		This repeats for all elements in 'tomerge'.
	"""
	for drivedata in tomerge:
		if (len(drivedata.data) > 1):
			logger.warning("Subject {} roi {} contains  more than one DataFrame. Only the first element will be in the merged output.".format(drivedata.SubjectID, DriveData.roi))

		subject = tomerge[0].SubjectID
		driveIDs = tomerge[0].DriveID
		roi = tomerge[0].roi
		sources = list(tomerge[0].sourcefilename)

		out_frame = tomerge[0].data[0]
		if (len(tomerge) > 1):
			i = 0
			while i < len(tomerge) - 1:
				i = i + 1

				#This part sets up data to be included in the final Drive Data object
				if tomerge[i].SubjectID != subject:
					logger.warning("Merging data for multiple subjects {} and {}. Only the first will be used".format(subject, tomerge[i].SubjectID))
				driveIDs.append(list(tomerge[i].DriveID)) #Some may be added twice. Is this desireable?
				if tomerge[i].roi != roi:
					logger.warning("Merging data for multiple rois {} and {}. Only the first will be used.".format(roi, tomerge[i].roi))
				sources.append(list(tomerge[i].sourcefilename))

				#This part does the actual merging
				last_line = out_frame.tail(1)
				last_x = last_line.XPos.iloc[0]
				last_y = last_line.YPos.iloc[0]
				last_time = last_line.SimTime.iloc[0]
				next_frame = tomerge[i].data[0]
				min_dist = float('inf')
				min_index = 0
				for index, row in next_frame.iterrows():
					dist = (row.XPos - last_x)**2 + (row.YPos - last_y)**2
					if (dist < min_dist):
						min_index = index
						min_dist = dist
				start_time = next_frame.iloc[min_index].SimTime
				next_frame = next_frame[min_index:]
				next_frame.SimTime += last_time - start_time
				out_frame = out_frame.append(next_frame)

		return DriveData(subject, driveIDs, roi, out_frame, sources)
	pass

class DriveData:

	def __init__(self, PartID: int, DriveID,	roi: str, data,	sourcefilename):
		self.PartID = PartID
		if type(DriveID) is not list:
			DriveID = [DriveID, ]
		self.DriveID = DriveID
		self.roi = roi
		if type(data) is not list:
			data = [data, ]
		self.data = data
		if type(data) is not list:
			sourcefilename = [sourcefilename, ]
		self.sourcefilename = sourcefilename


# Given the head of a linked list, remove the n^(th) node from the end of the list and return its head.

class Solution(object):
    def removeNthFromEnd(self, head, n):
        slow = head
        fast = head
        for i in range(n):
            fast = fast.next
        if fast == None:
            return head.next
        while fast.next != None:
            fast = fast.next
            slow = slow.next

        slow.next = slow.next.next
        return head


import os
from collections import OrderedDict

import sfsimodels.models.sections
from tests import load_test_data as ltd
from sfsimodels import files
import numpy as np
from sfsimodels import models
import sfsimodels as sm
import json

test_dir = os.path.dirname(__file__)

def test_load_json():
    fp = test_dir + "/unit_test_data/ecp_models.json"
    objs = files.load_json(fp, verbose=0)
    assert np.isclose(objs["soils"][1].unit_dry_weight, 15564.70588)
    assert np.isclose(objs["foundations"][1].length, 1.0)
    assert np.isclose(objs["soil_profiles"][1].layers[0].unit_dry_weight, 15564.70588)
    rel_density = objs["soil_profiles"][1].layer(2).relative_density
    assert np.isclose(objs["soil_profiles"][1].layer(2).relative_density, 0.7299999994277497), rel_density

def test_load_and_save_structure():
    structure = models.SDOFBuilding()
    structure.id = 1
    structure.name = "sample building"
    structure.h_eff = 10.0
    structure.t_fixed = 1.0
    structure.mass_eff = 80000.
    structure.mass_ratio = 1.0  # vertical and horizontal masses are equal
    ecp_output = files.Output()
    ecp_output.add_to_dict(structure)
    ecp_output.name = "test data"
    ecp_output.units = "N, kg, m, s"
    ecp_output.comments = ""

    p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"], indent=4)
    objs = files.loads_json(p_str)
    assert np.isclose(structure.mass_eff, objs['building'][1].mass_eff)

def test_load_and_save_foundation_w_pads():
    fd = models.PadFoundation()
    fd.width = 12  # m
    fd.length = 14  # m
    fd.depth = 0.6  # m
    fd.height = 1.0  # m
    fd.mass = 0.0  # kg
    fd.pad.length = 1.1
    fd.pad.width = 1.1
    fd.n_pads_l = 3
    fd.n_pads_w = 3
    fd.set_pad_pos_in_length_dir_as_equally_spaced()
    fd.set_pad_pos_in_width_dir_as_equally_spaced()
    tie_beams_sect = sm.sections.RCBeamSection()
    tie_beams_sect.depth = fd.height
    tie_beams_sect.width = fd.height
    tie_beams_sect.rc_mat = sm.materials.ReinforcedConcreteMaterial()
    tie_beams_sect.cracked_ratio = 0.6
    fd.tie_beam_sect_in_width_dir = tie_beams_sect
    fd.tie_beam_sect_in_length_dir = tie_beams_sect

    ecp_output = files.Output()
    ecp_output.add_to_dict(fd)
    ecp_output.name = "test data"
    ecp_output.units = "N, kg, m, s"
    ecp_output.comments = ""
    p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"], indent=4)
    objs = files.loads_json(p_str)
    fd_new = objs['foundation'][1]
    fd_pms = ['width', 'length', 'depth', 'height', 'n_pads_l', 'n_pads_w']
    for item in fd_pms:
        np.isclose(getattr(fd, item), getattr(fd_new, item))
    assert np.sum(abs(fd.pad_pos_in_length_dir - fd_new.pad_pos_in_length_dir)) < 1.0e-6
    assert np.sum(abs(fd.pad_pos_in_width_dir - fd_new.pad_pos_in_width_dir)) < 1.0e-6
    pad_pms = ['width', 'length', 'depth', 'height']
    for item in pad_pms:
        np.isclose(getattr(fd.pad, item), getattr(fd_new.pad, item))

def test_save_and_load_soil():
    # Set the void ratio and specific gravity
    sl = sm.Soil()
    sl.id = 1
    sl.e_curr = 0.7
    assert sl.unit_dry_weight is None
    sl.specific_gravity = 2.95
    assert np.isclose(sl.unit_dry_weight, 17000, rtol=0.01)

    # set modulus parameters
    g_mod_set = 40e6
    sl.g_mod = g_mod_set
    sl.poissons_ratio = 0.4
    ecp_output = sm.Output()
    ecp_output.add_to_dict(sl)

    ecp_output.name = "a single soil"
    ecp_output.units = "N, kg, m, s"
    ecp_output.comments = ""
    p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"], indent=4)
    a = open("temp.json", "w")
    a.write(p_str)
    a.close()
    objs = sm.loads_json(p_str, verbose=0)
    loaded_soil = objs['soils'][1]
    assert np.isclose(loaded_soil.g_mod, sl.g_mod)

def test_save_and_load_soil_profile_w_and_wo_none():
    sl1 = models.Soil()
    sl1_gmod = 30e6
    sl1_unit_dry_weight = 16000
    sl1.g_mod = sl1_gmod
    sl1.unit_dry_weight = sl1_unit_dry_weight
    sl2 = models.Soil()
    sl2_cohesion = 20e3
    sl2.cohesion = sl2_cohesion
    sp = models.SoilProfile()
    sp.id = 0
    sp.add_layer(0, sl1)
    sp.add_layer(3, sl2)
    sp.set_soil_ids_to_layers()
    ecp_output_verby = sm.Output()
    ecp_output_verby.add_to_dict(sp, export_none=True)
    p_str = json.dumps(ecp_output_verby.to_dict(), skipkeys=["__repr__"], indent=4)
    assert 'e_min' in p_str
    ecp_output = sm.Output()
    ecp_output.add_to_dict(sp, export_none=False)

    ecp_output.name = "a single soil"
    ecp_output.units = "N, kg, m, s"
    ecp_output.comments = ""
    p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"], indent=4)
    assert 'e_min' not in p_str
    a = open("temp.json", "w")
    a.write(p_str)
    a.close()
    objs = sm.loads_json(p_str, verbose=0)
    loaded_soil = objs['soils'][1]
    load_soil_from_profile = sp.layer(1)
    assert np.isclose(loaded_soil.g_mod, sl1.g_mod)
    assert np.isclose(load_soil_from_profile.g_mod, sl1.g_mod)

def test_save_and_load_building():
    number_of_storeys = 6
    interstorey_height = 3.4  # m
    masses = 40.0e3  # kg
    n_bays = 3

    fb = models.FrameBuilding(number_of_storeys, n_bays)
    fb.id = 1
    fb.interstorey_heights = interstorey_height * np.ones(number_of_storeys)
    fb.floor_length = 18.0  # m
    fb.floor_width = 16.0  # m
    fb.storey_masses = masses * np.ones(number_of_storeys)  # kg

    fb.bay_lengths = [6., 6.0, 6.0]
    fb.set_beam_prop("depth", [0.5, 0.5, 0.5], repeat="up")
    fb.set_beam_prop("width", [0.4, 0.4, 0.4], repeat="up")
    fb.set_column_prop("width", [0.5, 0.5, 0.5, 0.5], repeat="up")
    fb.set_column_prop("depth", [0.5, 0.5, 0.5, 0.5], repeat="up")
    fb.n_seismic_frames = 3
    fb.n_gravity_frames = 0

    ecp_output = sm.Output()
    ecp_output.add_to_dict(fb)

    ecp_output.name = "a single soil"
    ecp_output.units = "N, kg, m, s"
    ecp_output.comments = ""
    p_d = ecp_output.to_dict()
    p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"], indent=4)
    mods = sm.loads_json(p_str)
    bd2 = mods['building'][1]
    print(bd2)
    # a = open("temp.json", "w")
    # a.write(p_str)
    # a.close()

def test_save_and_load_an_element():
    ele = models.buildings.BeamColumnElement()
    ele.sections = [models.sections.RCBeamSection()]
    ele.set_section_prop('width', 0.5)
    ecp_output = sm.Output()
    ecp_output.add_to_dict(ele)
    p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"], indent=4)
    mods = sm.loads_json(p_str)
    ele2 = mods['beam_column_element'][1]
    s2 = mods['section'][1]
    assert ele2.s[0].width == 0.5, ele2.s[0].width
    assert s2.width == 0.5

def test_save_and_load_wall_building():
    number_of_storeys = 6
    interstorey_height = 3.4  # m
    masses = 40.0e3  # kg
    n_bays = 3

    fb = models.WallBuilding(number_of_storeys)
    fb.id = 1
    fb.interstorey_heights = interstorey_height * np.ones(number_of_storeys)
    fb.floor_length = 18.0  # m
    fb.floor_width = 16.0  # m
    fb.storey_masses = masses * np.ones(number_of_storeys)  # kg

    ecp_output = sm.Output()
    ecp_output.add_to_dict(fb)

    ecp_output.name = "a single wall building"
    ecp_output.units = "N, kg, m, s"
    ecp_output.comments = ""
    p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"], indent=4)
    objs = sm.loads_json(p_str)
    building = objs["buildings"][1]
    assert np.isclose(building.floor_length, 18.0)
    # a = open("temp.json", "w")
    # a.write(p_str)
    # a.close()

def test_save_and_load_2d_frame_building():
    number_of_storeys = 6
    interstorey_height = 3.4  # m
    masses = 40.0e3  # kg
    n_bays = 3

    fb2d = models.FrameBuilding2D(number_of_storeys, n_bays)
    fb2d.n_storeys = 6
    fb2d.id = 1
    fb2d.interstorey_heights = interstorey_height * np.ones(number_of_storeys)
    fb2d.floor_length = 18.0  # m
    fb2d.floor_width = 16.0  # m
    fb2d.storey_masses = masses * np.ones(number_of_storeys)  # kg

    fb2d.bay_lengths = [6., 6.0, 6.0]
    fb2d.set_beam_prop("depth", [0.5, 0.6, 0.5], repeat="up")
    fb2d.set_beam_prop("width", [0.4, 0.4, 0.4], repeat="up")
    fb2d.set_column_prop("width", [0.5, 0.5, 0.5, 0.5], repeat="up")
    fb2d.set_column_prop("depth", [0.5, 0.5, 0.5, 0.5], repeat="up")
    fb2d.beams[0][0].set_section_prop('a_custom_property', 11)
    fb2d.beams[0][0].add_inputs_to_section(["a_custom_property"])

    ecp_output = sm.Output()
    ecp_output.add_to_dict(fb2d)

    ecp_output.name = "a single building"
    ecp_output.units = "N, kg, m, s"
    ecp_output.comments = ""
    p_d = ecp_output.to_dict()
    p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"], indent=4)
    a = open("temp.json", "w")
    a.write(p_str)
    a.close()

    objs = sm.loads_json(p_str)
    building = objs["buildings"][1]
    assert np.isclose(building.beams[0][0].sections[0].depth, 0.5), building.beams[0][0].sections[0].depth
    assert np.isclose(building.beams[0][1].sections[0].depth, 0.6)

    assert building.beams[0][0].s[0].a_custom_property == 11, building.beams[0][0].sections[0].a_custom_property
    assert np.isclose(building.columns[0][0].sections[0].depth, 0.5)

def test_full_save_and_load():
    system = models.SoilStructureSystem()
    ltd.load_test_data(system)
    assert system.fd.length == 18.0
    ecp_output = files.Output()
    ecp_output.add_to_dict(system.sp)
    ecp_output.add_to_dict(system.fd)
    ecp_output.add_to_dict(system.bd)
    ecp_output.add_to_dict(system)
    ecp_output.name = "all test data"
    ecp_output.units = "N, kg, m, s"
    ecp_output.comments = ""
    p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"], indent=4)
    a = open("temp.json", "w")
    a.write(p_str)
    a.close()
    objs = files.loads_json(p_str, verbose=0)
    assert np.isclose(system.bd.mass_eff, objs['buildings'][1].mass_eff)

    soil = system.sp.layer(1)
    for item in soil.inputs:
        if getattr(soil, item) is not None:
            if not isinstance(getattr(soil, item), str):
                assert np.isclose(getattr(soil, item), getattr(objs['soils'][1], item)), item
    for item in system.fd.inputs:
        if getattr(system.fd, item) is not None:
            if isinstance(getattr(system.fd, item), str):
                assert getattr(system.fd, item) == getattr(objs['foundations'][1], item), item
            else:
                assert np.isclose(getattr(system.fd, item), getattr(objs['foundations'][1], item)), item
    for item in system.bd.inputs:
        if getattr(system.bd, item) is not None:
            if isinstance(getattr(system.bd, item), str):
                assert getattr(system.bd, item) == getattr(objs['buildings'][1], item), item
            else:
                assert np.isclose(getattr(system.bd, item), getattr(objs['buildings'][1], item)), item

def test_saturation_set_in_soil_profile():
    sl = models.Soil()
    sl.id = 1
    sl.relative_density = .40  # [decimal]
    sl.unit_dry_weight = 17000  # [N/m3]

    sp = models.SoilProfile()
    sp.hydrostatic = True
    sp.gwl = 4.0
    sp.add_layer(0, sl)
    sp.add_layer(6, sl.deepcopy())
    assert np.isclose(sp.layer(1).saturation, 0.00)
    assert np.isclose(sp.layer(2).saturation, 1.00)

    # Add a layer in between
    sl = models.Soil()
    sl.id = 2
    sl.relative_density = .50  # [decimal]
    sl.unit_dry_weight = 18000  # [N/m3]
    sp.add_layer(2, sl)
    assert np.isclose(sp.layer(2).saturation, 0.50)

def test_can_load_then_save_and_load_custom_ecp_w_custom_obj():
    class Cantilever(sm.CustomObject):
        _id = None
        base_type = "cantilever"
        type = "cantilever"
        inputs = ["id", "length", "depth", "e_mod"]

        def to_dict(self, **kwargs):
            outputs = OrderedDict()
            for item in self.inputs:
                outputs[item] = getattr(self, item)
            return outputs

    fp = test_dir + "/unit_test_data/ecp_models_w_custom_obj.json"
    objs, meta_data = files.load_json_and_meta(fp, custom={"cantilever-cantilever": Cantilever}, verbose=0)
    assert np.isclose(objs["foundation"][1].length, 1.0)
    assert np.isclose(objs["cantilever"][1].length, 6.0)
    ecp_output = files.Output()
    for m_type in objs:
        for instance in objs[m_type]:
            ecp_output.add_to_dict(objs[m_type][instance])
    ecp_output.name = meta_data["name"]
    ecp_output.units = meta_data["units"]
    ecp_output.comments = meta_data["comments"]
    p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"], indent=4)
    a = open("temp.json", "w")
    a.write(p_str)
    a.close()
    objs2, md2 = files.loads_json(p_str, custom={"cantilever-cantilever": Cantilever}, meta=True, verbose=0)
    for m_type in objs:
        for instance in objs[m_type]:
            for parameter in objs[m_type][instance].inputs:
                p_org = getattr(objs[m_type][int(instance)], parameter)
                p_2nd = getattr(objs2[m_type][int(instance)], parameter)
                assert p_org == p_2nd, (m_type, parameter, p_org, p_2nd)
    for item in meta_data:
        if item == 'sfsimodels_version':
            continue
        assert meta_data[item] == md2[item], (item, meta_data[item], md2[item])

def test_load_frame_w_hinges():
    # Define special class for section
    class CustomBeamSection(sfsimodels.models.sections.RectangularSection):
        diametertop = None
        fylong = None
        filongtop = None

        def __init__(self):
            super(CustomBeamSection, self).__init__()
            self._extra_class_variables = [
                "diametertop",
                "fylong",
                "filongtop",
                "myplus_section"
            ]
            self.inputs += self._extra_class_variables

    # Attach the section class as the default for the building
    class CustomBuildingFrame2D(sm.FrameBuilding2D):
        _custom_beam_section = CustomBeamSection
        _custom_column_section = None

    fp = test_dir + "/unit_test_data/building_1011_ecp.json"

    # Override the base_type-type for building-building_frame2D with the custom model
    objs = files.load_json(fp, verbose=0, custom={"building-building_frame2D": CustomBuildingFrame2D})
    bd = objs["building"][1]
    assert np.isclose(bd.floor_length, 13.05)
    assert np.isclose(bd.beams[0][0].s[0].myplus_section, 97.03)
    assert np.isclose(bd.beams[1][1].s[0].myplus_section, 127.85), bd.beams[1][1].s[0].myplus_section
    assert bd.beams[1][0].s[0].diametertop is None
    assert np.isclose(bd.columns[1][0].s[0].nbar_hplusx, 2)
    assert "diametertop" in bd.beams[0][0].s[0].inputs
    ecp_output = files.Output()
    ecp_output.add_to_dict(bd)
    p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"], indent=4)
    assert '"filongtop"' in p_str
    objs = files.loads_json(p_str)
    bd = objs["building"][1]
    assert np.isclose(bd.beams[0][0].s[0].myplus_section, 97.03)
    assert np.isclose(bd.beams[1][1].s[0].myplus_section, 127.85), bd.beams[1][1].s[0].myplus_section

def test_load_old_file_w_frame_w_hinges():
    # Define special class for section
    class CustomBeamSection(sfsimodels.models.sections.RectangularSection):
        diametertop = None
        fylong = None
        filongtop = None

        def __init__(self):
            super(CustomBeamSection, self).__init__()
            self._extra_class_variables = [
                "diametertop",
                "fylong",
                "filongtop",
                "myplus_section"
            ]
            self.inputs += self._extra_class_variables

    # Attach the section class as the default for the building
    class CustomBuildingFrame2D(sm.FrameBuilding2D):
        _custom_beam_section = CustomBeamSection
        _custom_column_section = None

    fp = test_dir + "/unit_test_data/building_1011_ecp_old.json"

    # Override the base_type-type for building-building_frame2D with the custom model
    objs = files.load_json(fp, verbose=0, custom={"building-building_frame2D": CustomBuildingFrame2D})
    bd = objs["building"][1]
    assert np.isclose(bd.floor_length, 13.05)
    assert np.isclose(bd.beams[0][0].s[0].myplus_section, 97.03)
    assert np.isclose(bd.beams[1][1].s[0].myplus_section, 127.85), bd.beams[1][1].s[0].myplus_section
    assert bd.beams[1][0].s[0].diametertop is None
    assert np.isclose(bd.columns[1][0].s[0].nbar_hplusx, 2)
    assert "diametertop" in bd.beams[0][0].s[0].inputs
    ecp_output = files.Output()
    ecp_output.add_to_dict(bd)
    p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"], indent=4)
    assert '"filongtop"' in p_str
    objs = files.loads_json(p_str)
    bd = objs["building"][1]
    assert np.isclose(bd.beams[0][0].s[0].myplus_section, 97.03)
    assert np.isclose(bd.beams[1][1].s[0].myplus_section, 127.85), bd.beams[1][1].s[0].myplus_section

class Custom3Req(sm.CustomObject):
    type = "custom3"

    def __init__(self, p1, p2, p3):
        super(Custom3Req, self).__init__()

        self._extra_class_variables = ["p1", "p2", "p3"]
        self.inputs += self._extra_class_variables
        self.p1 = p1
        self.p2 = p2
        self.p3 = p3

def test_can_set_more_than_two_positional_args():
    c3 = Custom3Req(1, 3, 5)
    c3.id = 1
    ecp_output = sm.Output()
    ecp_output.add_to_dict(c3)
    p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"], indent=4)
    objs = sm.loads_json(p_str, custom={"custom_object-custom3": Custom3Req})
    cus = objs["custom_object"][1]
    assert cus.p2 == 3
    assert cus.p3 == 5

def test_save_and_load_soil_w_diff_wmd():  # deprecated
    sl = models.Soil(wmd=1.0)
    sl.e_curr = 0.65
    sl.specific_gravity = 2.65
    ecp_output = sm.Output()
    ecp_output.add_to_dict(sl)
    p_str = json.dumps(ecp_output.to_dict(), indent=4)
    objs = sm.loads_json(p_str)

    sl = models.StressDependentSoil(wmd=1.0, p_atm=101.0)
    sl.e_curr = 0.65
    sl.specific_gravity = 2.65

    ecp_output = sm.Output()
    ecp_output.add_to_dict(sl)
    p_str = json.dumps(ecp_output.to_dict(), indent=4)
    objs = sm.loads_json(p_str)

def test_save_and_load_soil_w_diff_liq_mass_density():
    sl = models.Soil(liq_mass_density=1.0)
    sl.e_curr = 0.65
    sl.specific_gravity = 2.65
    ecp_output = sm.Output()
    ecp_output.add_to_dict(sl)
    p_str = json.dumps(ecp_output.to_dict(), indent=4)
    print(p_str)
    objs = sm.loads_json(p_str)

def test_save_and_load_two_soil_profiles():
    sl = models.Soil(liq_mass_density=1.0)
    sl.e_curr = 0.65
    sl.specific_gravity = 2.65
    sp = models.SoilProfile()
    sp.add_layer(0, sl)
    sp.add_layer(2, sl)
    sp2 = sp.deepcopy()
    sp2.move_layer(3, 2)
    ecp_output = sm.Output()
    ecp_output.add_to_dict(sp)
    ecp_output.add_to_dict(sp2)
    p_str = json.dumps(ecp_output.to_dict(), indent=4)
    objs = sm.loads_json(p_str)
    assert len(objs['soil_profile']) == 2

if __name__ == '__main__':
    # test_load_json()
    # test_save_and_load_wall_building()
    # test_save_and_load_building()
    # test_load_and_save_structure()
    # test_save_and_load_soil_w_diff_liq_mass_density()
    # test_load_and_save_foundation_w_pads()
    test_save_and_load_soil_w_diff_wmd()
    # test_save_and_load_building()
    # test_save_and_load_two_soil_profiles()
    # test_load_json()
    # test_full_save_and_load()
    # test_save_and_load_soil_profile()
    # test_save_and_load_soil()
    # test_can_load_then_save_and_load_custom_ecp_w_custom_obj()
    # test_full_save_and_load()
    # test_can_load_then_save_and_load_custom_ecp_w_custom_obj()


import json

from django.http import Http404, HttpResponse
from django.shortcuts import render
from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.decorators.csrf import csrf_exempt
from rest_framework import status
from rest_framework.exceptions import ValidationError
from rest_framework.generics import get_object_or_404
from rest_framework.response import Response
from rest_framework.views import APIView

from api import PaginatedAPIView
from api.payment.exceptions import InvalidSubscriptionDetails
from api.payment.models import PaymentSubscription
from api.payment.serializers import UserWithdrawRequestWriteSerializer, PaymentSubscriptionSerializer, \
    PaymentSubscriptionListSerializer
from api.reward.models import Reward
from api.saving_goal.exceptions import InsufficientBalance, ActiveWithdrawRequest
from api.saving_goal.models import SavingGoal, Transaction
from lib.cashfree.webhook import PayoutWebhookResponse
from lib.utils import logger, ErrorResponse
from cashfree_sdk import verification
from django.http import JsonResponse

from mpw import settings

class UserWithdrawRequestAPIView(APIView):
    """
    withdraw request REST api
    """
    def post(self, request):
        withdraw_request = UserWithdrawRequestWriteSerializer(data=request.data)
        # logger.debug((request.data))
        if withdraw_request.is_valid():
            try:
                logger.debug(withdraw_request.validated_data)
                #saving_goal = get_object_or_404(SavingGoal, pk=withdraw_request.validated_data['saving_goal'])
                withdraw_request.create_withdraw_request(request.user)
            except InsufficientBalance:
                response_data = {
                    'message': "Insufficient balance",
                    'error': True
                }
                return ErrorResponse(response_data['message'])
            except ActiveWithdrawRequest:
                response_data = {
                    "message": "A withdraw request already exist",
                    "error": True
                }
                return ErrorResponse(response_data['message'])
            except Exception as ex:
                logger.exception("Withdraw request exception")
                return Response({"error": "something went wrong"}, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response(withdraw_request.errors, status=status.HTTP_400_BAD_REQUEST)
        return Response(status=status.HTTP_204_NO_CONTENT)

class PaymentSubscriptionAPIView(APIView):
    """
    Payment subscription REST APIs.
    """
    def get(self, request, pk=None):
        if not pk:
            return self.list(request)
        try:
            subscription = get_object_or_404(PaymentSubscription, saving_goal_id=pk, saving_goal__user=request.user)
        except Http404 as not_found:
            try:
                saving_goal = get_object_or_404(SavingGoal, pk=pk, user=request.user)
                subscription = PaymentSubscription.create_subscription(saving_goal, saving_goal.user)
            except InvalidSubscriptionDetails as ex:
                return Response(status=status.HTTP_400_BAD_REQUEST)
        data = PaymentSubscriptionSerializer(subscription).data
        if settings.DEBUG:
            data['enabled'] = False
            data['message'] = 'Sorry Auto debit option is not working. our team is working on it.'
        return Response(data, status=status.HTTP_200_OK)

    def post(self, request, pk=None):
        subscription = get_object_or_404(PaymentSubscription, pk=pk, saving_goal__user=request.user)
        response = subscription.cancel_subscription(request.user)
        logger.debug(response)
        if not response:
            logger.debug(response)
            return Response(status=status.HTTP_400_BAD_REQUEST)
        return Response(status=status.HTTP_200_OK)

    def list(self, request, pk=None):
        subscription_list = PaginatedAPIView().get_paginated_response_data(
            request, PaymentSubscription.get_user_subscriptions(request.user),
            PaymentSubscriptionListSerializer, many=True
        )
        return Response(subscription_list.data, status=status.HTTP_200_OK)

class PaymentSubscriptionDetails(APIView):
    def post(self, request, reference_id):
        payment_subscription = get_object_or_404(PaymentSubscription, reference_id=reference_id,
                                                 saving_goal_user=request.user)
        subscription = payment_subscription.get_subscription_details(reference_id, request.user)
        return Response(subscription, status=status.HTTP_200_OK)

@csrf_exempt
def subscription_webhook_callback(request):
    if request.method == "POST":
        event_type = request.POST['cf_event']
        if event_type == "SUBSCRIPTION_STATUS_CHANGE":
            pass
        elif event_type == "SUBSCRIPTION_PAYMENT_DECLINED":
            pass
        elif event_type == "SUBSCRIPTION_NEW_PAYMENT":
            reference_id = request.POST['cf_subReferenceId']
            amount = request.POST['cf_amount']
            subscription = get_object_or_404(PaymentSubscription, reference_id=reference_id)
            saving = subscription.saving
            transaction = Transaction.create(saving.user, saving, Transaction.TRANSACTION_TYPE_CREDIT, amount)
            transaction.update_status(transaction.order_id, "SUCCESS")
            return HttpResponse(status=status.HTTP_204_NO_CONTENT)

@csrf_exempt
@xframe_options_exempt
def subscription_complete_callback(request):
    if request.method == "POST":
        logger.debug(request.POST)
        callback_data = request.POST
        reference_id = request.POST['cf_subReferenceId']
        sub_id = request.POST['cf_subscriptionId']
        subscription = get_object_or_404(PaymentSubscription, reference_id=reference_id, subscription_id=sub_id)
        subscription.update_status(callback_data)
        return render(request, 'subscription_auth_callback.html', {'callback_data': callback_data})
    return render(request, 'subscription_auth_callback.html', {'callback_data': {}})

@csrf_exempt
def payout_withdraw_webhook_callback(request):
    logger.debug(('request', request.POST, '=====>>>>><<<<======='))
    if request.method == "POST":
        response = PayoutWebhookResponse(request.POST)
        webhook_data = response.json()
        logger.debug((webhook_data, type(webhook_data)))
        is_valid = verification.verify_webhook(webhook_data, 'JSON')
        if is_valid:
            from api.payment.models import UserWithdrawRequest
            if str(response.transfer_id).startswith('reward_'):
                Reward.process_reward(response)
            else:
                UserWithdrawRequest.process_withdraw_request(response)
            status = True
        else:
            logger.debug(('invalid....', request.POST.dict()))
            status = False
        return JsonResponse({})


#! /usr/bin/env python3

from sys import argv

def check_onesie(a, b):
    count = 0
    for i in range(len(a)):
        if a[i] != b[i]:
            count += 1
        if count > 1:
            return False
    return count == 1

def BFS(graph):
    queue = [argv[2]]
    seen = {argv[2]}
    paths = {argv[2]:None}
    while (queue):
        vertex = queue.pop(0)
        if not graph.get(vertex):
            return None
        nodes = graph[vertex]
        for node in nodes:
            if node not in seen:
                queue.append(node)
                seen.add(node)
                paths[node] = vertex
    return paths

inputs = [line.strip() for line in open(argv[1]) if len(line.strip()) == len(argv[2])]

g = {}

for line_i in inputs.copy():
    for line_j in inputs:
        if check_onesie(line_i, line_j):
            tempA = g.get(line_i, set())
            g[line_i] = tempA.union({line_j})
            tempB = g.get(line_j, set())
            g[line_j] = tempB.union({line_i})
    inputs.remove(line_i)

path = BFS(g)

if path is None:
    print('No solution')
    exit(0)

result = []

note = argv[3]

print(path)

while note != None:
    result.append(note)
    note = path[note]

for line in result[::-1]:
    print(line)


import os
import boto3
import dateutil.parser as dp

client = boto3.client('dynamodb')

def handle(event, context):
    table_name = os.environ["BACKUP_TABLE"]
    print(event)
    for record in event:
        diff = record['diff']
        created = diff['created']['S']
        diff.pop('created', None)
        time_in_seconds = str(int(dp.parse(created).timestamp()))
        diff['created'] = {'N': time_in_seconds}
        print(diff)
        if record['action'] == 'REMOVE':
            print("Record will be removed.")
            client.delete_item(
                TableName=table_name,
                Key=diff
            )
        else:
            print("Record will be updated or created.")
            client.put_item(
                TableName=table_name,
                Item=diff
            )
    return {}


import time
import subprocess
from subprocess import PIPE
import os
import time

import chromedriver_binary
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.chrome.options import Options

if __name__ == "__main__":

    test_epoch = 40
    loc = "icn"

    with open("../data/sites",'r') as f:
        sites = f.readlines()
        for site in sites:
            s = site.split()
            if s[0]=="#":
                continue
            if not os.path.exists("../data/train/"+loc+"/"+s[1]):
                os.mkdir("../data/train/"+loc+"/"+s[1])

        option = Options()
        option.add_argument("--headless")
        for i in range(test_epoch):
            print("get "+str(i)+" times")
            for site in sites:
                s = site.split()
                if s[0]=="#":
                    continue

                driver = webdriver.Chrome(options=option)
                #driver = webdriver.Chrome()

                print(s[1])
                p = subprocess.Popen(['tcpdump','-w', '../data/train/'+loc+"/"+s[1]+'/'+str(i)+'.pcap'], stdout=subprocess.PIPE)
                driver.get(s[0])

                p.terminate()
                driver.delete_all_cookies()
                driver.quit()


def storeindexed(ad):
  """
  Built-in macro to store the next-to-top of the data stack at the
  offset into variable specified by the top of the data stack.\n
  Usage:
    <v> <ix> .storeindexed(variable[,op])
  where:
    <v>         is the value to be stored from the next-to-top of the data
                stack
    <ix>        is the index into the variable
    variable    is the name of the variable
    op          is an optional instruction to override the default "drop"
                instruction at the end of the instruction sequence\n
  The effect is:  variable[ix] = v\n
  ( u_value u_ix - )
  """

  # Add the macro to the list of recognized macros.
  ad.AddMacro('.storeindexed', 4, [
                                    ['','symbol'],
                                    ['drop','instruction','singlemacro','singlevalue','symbol']
                                  ]);

  # Define the macro functionality.
  def emitFunction(ad,fp,argument):
    (addr,ixBank,bankName) = ad.Emit_GetAddrAndBank(argument[0]);
    ad.EmitPush(fp,addr,ad.Emit_String(argument[0]['value']),argument[0]['loc']);
    ad.EmitOpcode(fp,ad.InstructionOpcode('+'),'+');
    ad.EmitOpcode(fp,ad.specialInstructions['store'] | ixBank,'store '+bankName);
    ad.EmitOptArg(fp,argument[1]);

  ad.EmitFunction['.storeindexed'] = emitFunction;


from base_templates import BasicModule
from transformers import AutoModel,AutoConfig
import torch
import torch.nn as nn

#using the cls of claim
class RobertaCls(BasicModule):
    def __init__(self, args):
        super(RobertaCls, self).__init__()
        self.config = AutoConfig.from_pretrained(args.bert_name, num_labels=len(args.id2label))
        hidden_size = self.config.hidden_size
        self.linear1 = nn.Linear(hidden_size, 128)
        self.relu = nn.ReLU()
        # self.linear2 = nn.Linear(128, len(args.id2label))
        self.linear2 = nn.Linear(128, 1)

        self.init_weights()
        self.args = args

        self.bert = AutoModel.from_pretrained(args.bert_name, config=self.config)
        self.dropout = nn.Dropout(args.dropout)

        self.count_parameters()
        # self.print_modules()

    def forward(self, batch, args, test_mode):
        pos_ids, pos_attention_mask, neg_ids, neg_attention_mask = batch
        pos_out = self.bert(pos_ids, attention_mask=pos_attention_mask)[1]

        if test_mode:
            output = pos_out
        else:
            neg_out = self.bert(neg_ids, attention_mask = neg_attention_mask)[1]
            output = torch.cat([pos_out, neg_out], dim=0)

        hg = self.dropout(output)
        hg = self.relu(self.linear1(hg))
        hg = self.linear2(hg)

        if test_mode:
            pos_scores = torch.sigmoid(hg).view(-1)
            neg_scores = None
        else:
            scores = torch.sigmoid(hg).view(2,-1)
            pos_scores = scores[0]
            neg_scores = scores[1]

        golds = torch.ones_like(pos_scores)

        return pos_scores, neg_scores, golds


import csv
import json
from random import shuffle

from ASDC_lab0.src.classes.student import Student

def prepare_data(to_shuffle: bool = False) -> list:
    reader = csv.DictReader
    data = Student.read_from_stream(filename='data/students_data.csv', reader=reader)
    if to_shuffle:
        shuffle(data)
    return data

if __name__ == '__main__':
    students = prepare_data()
    for student in students:
        print(student)
    Student.write_in_stream(students[0], 'data/check_write_method.json', json.dump)