import logging
from random import randint
import traceback
from typing import cast, Dict, List, Set, Collection

from geniusweb.actions.Accept import Accept
from geniusweb.actions.Action import Action
from geniusweb.actions.LearningDone import LearningDone
from geniusweb.actions.Offer import Offer
from geniusweb.actions.PartyId import PartyId
from geniusweb.actions.Vote import Vote
from geniusweb.actions.Votes import Votes
from geniusweb.bidspace.AllBidsList import AllBidsList
from geniusweb.inform.ActionDone import ActionDone
from geniusweb.inform.Finished import Finished
from geniusweb.inform.Inform import Inform
from geniusweb.inform.OptIn import OptIn
from geniusweb.inform.Settings import Settings
from geniusweb.inform.Voting import Voting
from geniusweb.inform.YourTurn import YourTurn
from geniusweb.issuevalue.Bid import Bid
from geniusweb.issuevalue.Domain import Domain
from geniusweb.issuevalue.Value import Value
from geniusweb.issuevalue.ValueSet import ValueSet
from geniusweb.party.Capabilities import Capabilities
from geniusweb.party.DefaultParty import DefaultParty
from geniusweb.profile.utilityspace.UtilitySpace import UtilitySpace
from geniusweb.profileconnection.ProfileConnectionFactory import ProfileConnectionFactory
from geniusweb.progress.ProgressRounds import ProgressRounds
from geniusweb.utils import val

from collections import deque

DEQUE_SIZE = 5

class Group33Party(DefaultParty):
    """
    Offers random bids until a bid with sufficient utility is offered.
    """
    def __init__(self):
        super().__init__()
        self.getReporter().log(logging.INFO,"party is initialized")
        self._profile = None
        self._lastReceivedBid:Bid = None

        # Acceptance Strategy params
        self.highTime = 0.99
        self.bidsBuffer = []
        self.max_util = 1
        self.max_bid = None
        self.utils = []
        self.bestBids = deque([])
        self.tempFlag = False

    # Override
    def notifyChange(self, info: Inform):
        #self.getReporter().log(logging.INFO,"received info:"+str(info))
        if isinstance(info,Settings) :
            self._settings:Settings=cast(Settings,info)
            self._me = self._settings.getID()
            self._protocol:str = str(self._settings.getProtocol().getURI())
            self._progress = self._settings.getProgress()
            if "Learn" ==  self._protocol:
                self.getConnection().send(LearningDone(self._me)) #type:ignore
            else:
                self._profile = ProfileConnectionFactory.create(info.getProfile().getURI(), self.getReporter())
        elif isinstance(info, ActionDone):
            action:Action=cast( ActionDone,info).getAction()
            if isinstance(action, Offer):
                self._lastReceivedBid = cast(Offer, action).getBid()
                self.bidsBuffer.append(self._lastReceivedBid)
        elif isinstance(info, YourTurn):
            self._myTurn()
            if isinstance(self._progress, ProgressRounds) :
                self._progress = self._progress.advance()
        elif isinstance(info, Finished):
            self.terminate()
        elif isinstance(info, Voting):
            # MOPAC protocol
            self._lastvotes = self._vote(cast(Voting, info));
            val(self.getConnection()).send(self._lastvotes)
        elif isinstance(info, OptIn):
            val(self.getConnection()).send(self._lastvotes)
        else:
            self.getReporter().log(logging.WARNING, "Ignoring unknown info "+str(info))

    # Override
    def getCapabilities(self) -> Capabilities:
        return Capabilities( set(["MOPAC"]), set(['geniusweb.profile.utilityspace.LinearAdditive']))

    # Override
    def getDescription(self) -> str:
        return "Offers varying bids, starting from the maximum utility, and gradually reducing " \
               "the target utility in order to secure an agreement. Uses a combined acceptance " \
               "criterions. Parameters minPower and maxPower can be used to control voting behaviour."

    # Override
    def terminate(self):
        self.getReporter().log(logging.INFO,"party is terminating:")
        super().terminate()
        if self._profile != None:
            self._profile.close()
            self._profile = None

    def _myTurn(self):
        if self._isGood(self._lastReceivedBid):
            action = Accept(self._me, self._lastReceivedBid)
        else:
            for _attempt in range(20):
                bid = self._getBid(self._profile.getProfile().getDomain())
                if self._isGood(bid):
                    break
            action = Offer(self._me, bid)
        self.getConnection().send(action)

    def _isGood(self, bid:Bid, party=None)->bool:
        if bid == None:
            return False
        profile = self._profile.getProfile()
        if isinstance(profile, UtilitySpace):
            curProgress = self._progress.getCurrentRound() -1
            totalDuration = self._progress.getDuration() - 1
            if curProgress < 0.5*totalDuration:
                # Use next criterion
                nextBid = self._getBid(self._profile.getProfile().getDomain())
                return profile.getUtility(bid) >= profile.getUtility(nextBid)
            if curProgress >= 0.5*totalDuration:
                # Use combi criterion
                nextBid = self._getBid(self._profile.getProfile().getDomain())
                ac_next = profile.getUtility(bid) >= profile.getUtility(nextBid)
                ac_time = curProgress >= self.highTime
                utils = []
                windowStart = curProgress - (totalDuration - curProgress)
                windowEnd = curProgress + 1
                for bids in self.bidsBuffer[windowStart:windowEnd]:
                    for oneBid in [bids]: # Assuming that in each time step, there will be
                        # multiple bids
                        utils.append(profile.getUtility(oneBid))
                if len(utils) > 0:
                    if party == self.powerParty[0] and len(self.powerParty) == 1: # If the party has
                        # the most power, get maximum
                        ac_combi = profile.getUtility(bid) >= max(utils)
                    else: # If the party doesnt have the most power, get the average
                        ac_combi = profile.getUtility(bid) >= sum(utils)/len(utils)
                    return (ac_next or ac_time) and ac_combi
                else:
                    return False
        raise Exception("Can not handle this type of profile")

    def _getBid(self, domain:Domain) -> Bid:

        profile = self._profile.getProfile()
        # In the first run of the function, calculate and store all bids with their utilities
        if self.max_bid == None:
            # Get all bids
            self.allBids = AllBidsList(domain)
            # Calculate and store the utility of each bid
            for bid in self.allBids:
                self.utils.append(profile.getUtility(bid))

           # Find the order in which the bids are sorted
            self.order = [bid for _,bid in sorted(zip(self.utils,list(range(len(self.utils)))),
                                                        reverse=True)]
            # Sort the bids
            self.allBids_temp = []
            allBids_list =  list(self.allBids)
            for i in range(len(self.order)):
                self.allBids_temp.append(allBids_list[self.order[i]])
            self.utils.sort(reverse=True)
            self.allBids = self.allBids_temp
            # Get the maximum bid
            self.max_bid = self._get_max_bid(domain)

            # Initialize the bestBids deque
            for _ in range(DEQUE_SIZE):
                self.bestBids.append(self.max_bid)

        curProgress = self._progress.getCurrentRound() - 1
        totalDuration = self._progress.getDuration() - 1
        # If it's early in the negotiation just return max utility bid
        if curProgress < 0.09*totalDuration:
            return self.max_bid
        else:
            self.max_bid = self._get_bid_in_window(domain)
            return self.max_bid

    """
    Returns in a random fashion the best 5 bids according to their utility.
    The best 5 bids deteriorate over time, since the best bid is removed and one that is worse is added, to allow
    conceding.
    """
    def _get_bid_in_window(self, domain:Domain) -> Bid:
        allBids = self.allBids
        max_util = -1
        max_bid = None
        profile = self._profile.getProfile()
        for idx, bid in enumerate(allBids):
            util = self.utils[idx]
            if util < self.max_util:
                max_util = util
                max_bid = bid
                self.allBids = self.allBids[idx+1:]
                self.utils = self.utils[idx+1:]
                break

        if max_bid is None:
            return self.bestBids[randint(0, 4)]

        self.max_util = max_util

        self.bestBids.popleft()
        self.bestBids.append(max_bid)
        self.getReporter().log(logging.INFO,profile.getUtility(max_bid))
        return self.bestBids[randint(0, 4)]

    """
    Returns the bid with maximum utility from the available bids
    """
    def _get_max_bid(self, domain:Domain) ->Bid:
        allBids = self.allBids
        max_util = -1
        max_bid = None
        for idx,bid in enumerate(allBids):
            util = self.utils[idx]
            if util > max_util:
                max_util = util
                max_bid = bid

        self.max_util = max_util
        return max_bid

    def _vote(self, voting:Voting) ->Votes :
        '''
        @param voting the {@link Voting} object containing the options

        @return our next Votes.
        '''
        val = self._settings.getParameters().get("minPower");
        minpower:int = val if isinstance(val, int) else 2
        val = self._settings.getParameters().get("maxPower");
        maxpower:int = val if isinstance(val,int) else  9999999;

        # Get the party with most power
        if self.tempFlag == False:
            self.tempFlag = True
        self.powers = voting.getPowers()
        self.powerParty = [key for key, value in self.powers.items() if value == max(
            self.powers.values())]

        votes:Set[Vote]  = set([Vote(self._me, offer.getBid(), minpower, maxpower)\
                for offer in voting.getOffers() if self._isGood(offer.getBid(),
                                                                party=offer.getActor()
                                                                )
                                ])
        return Votes(self._me, votes);


from ndmapper.libutils import is_list_like
from ndmapper.data import FileName, DataFile, DataFileList

from .calibrations import K_CALIBRATIONS

def convert_region(region, convention):
    """
    Convert a NumPy- or FITS-style region string into a tuple of integers
    and Python slice objects that is suitable for subscripting arrays.

    Some corner cases (eg. involving '*', ':' or steps) currently behave
    differently from Python/IRAF subscripting but should be fairly harmless.

    Parameters
    ----------

    region : str
        Region string, eg. '100:110,50:60', '100,*' or ':,99'.

    convention : str
        Indexing convention used: 'NumPy' (default) or 'FITS'; case
        insensitive.

    """

    # Check arguments:
    if not isinstance(region, str):
        raise TypeError('region must be a string')

    convention = convention.lower()
    if convention not in ['numpy', 'fits']:
        raise ValueError('convention must be NumPy or FITS')

    # Apply appropriate syntax & indexing adjustments for convention used:
    if convention == 'numpy':
        nregion = region
        order = slice(None, None, None)
        orig = 0
    elif convention == 'fits':
        nregion = region.replace('*', ':')
        order = slice(None, None, -1)
        orig = 1
    else:
        raise ValueError('convention must be \'NumPy\' or \'FITS\'')

    # Split region into a range for each axis:
    axes = nregion.split(',')

    # Parse sub-string for each axis into a range & convert to slice object:
    slices = []
    for axis in axes[order]:
        err = False if axis else True    # disallow empty string
        vals = axis.split(':')
        nvals = len(vals)
        if nvals > 3:
            err = True                   # disallow more than start:stop:step
        elif nvals == 1:
            try:
                sliceobj = int(vals[0])-orig  # single row/column number
            except ValueError:
                err = True
        else:
            try:
                # Any adjustment for 1-based indexing is applied only to the
                # start of the range, since 1 has to be added to the ending
                # index to account for FITS/IRAF-style ranges being inclusive.
                sliceobj = slice(*(int(val)-adj if val else None \
                                   for val, adj in zip(vals, (orig, 0, 0))))
            except ValueError:
                err = True               # disallow non-numeric values etc.
        if err:
            raise ValueError('failed to parse region: [%s]' % region)

        slices.append(sliceobj)

    return tuple(slices)

def to_filename_strings(objects, strip_names=True, strip_dirs=True,
                        use_cal_dict=False):
    """
    Extract a list of filename strings from one or more `str`, `FileName` or
    `DataFile` objects (or a `DataFileList`), by default removing any path and
    processing suffix/prefixes. A calibration dictionary may also be given,
    in the format produced by calibrations.init_cal_dict(), if the relevant
    option is enabled. It is the caller's responsibility to ensure that the
    string values are actually valid filenames.

    This is typically used to reproduce base filenames for use in either
    downloading or looking up external information about the files.

    """
    # Convert any recognized single objects to a list (partly to ensure we
    # don't inadvertently iterate over the NDData instances of a DataFile):
    if isinstance(objects, (DataFile, FileName, str)):
        objects = [objects]

    # If the objects argument looks like a calibration dict, extract a list
    # of unique constituent filenames from all the calibrations:
    elif use_cal_dict and hasattr(objects, 'keys') and \
         K_CALIBRATIONS in objects:
        objects = list(set([fn for flist in \
                            objects[K_CALIBRATIONS].values() \
                   for fn in (flist if is_list_like(flist) else [])]))

    # This must be list-like after the above:
    if not is_list_like(objects) or hasattr(objects, 'keys'):
        raise ValueError('objects parameter has an unexpected type')

    return [str(FileName(str(obj), strip=strip_names, \
                         dirname='' if strip_dirs else None)) \
            for obj in objects]

def to_datafilelist(arg, mode=None):
    """
    Derive a `DataFileList` object from one or a sequence of objects than can
    be converted to filename strings (eg. `str`, `FileName` or `DataFile`).
    The ``mode`` defaults to ``'read'`` when given one or more filenames and
    to the existing mode for `DataFile` and `DataFileList`. Where all of the
    inputs are existing `DataFile` instances, those are re-used by reference
    (``mode`` permitting), instead of opening new copies.

    Beware of feeding this inappropriate argument types, as almost anything can
    be converted to `str`...
    """

    # Ensure the input is in a list, for iteration:
    if (isinstance(arg, DataFile) or not is_list_like(arg)):
        arg = [arg]

    # If passed existing DataFile(s), use them as the data argument for
    # instantiation. Currently, DataFiles can only be re-used by reference if
    # all elements have that type. This case also covers DataFileList, which
    # needs re-instantating in case a new mode is specified.
    if arg and all([isinstance(df, DataFile) for df in arg]):
        outlist = DataFileList(data=arg, mode=mode)

    # Otherwise, convert inputs to filename strings and instantiate with those.
    # Should the acceptable types be enumerated to avoid strange results? That
    # might impact user creativity in both good and a bad ways...
    else:
        mode = 'read' if mode is None else mode
        outlist = DataFileList(filenames=[str(fn) for fn in arg], mode=mode)

    return outlist


import glob
import os
import pathlib
import warnings

import logzero
import torch
import torch.nn as nn
import yaml
from torch.utils.tensorboard import SummaryWriter

def write_meters(epoch, tag, tb_writer, meters):
    for name, value in meters.averages("").items():
        tb_writer.add_scalar("{}/{}".format(tag, name), value, epoch)

def save_checkpoint(filename, model, epoch, optimizer=None):
    checkpoint = {'epoch': epoch}
    if isinstance(model, nn.DataParallel):
        checkpoint['state_dict'] = model.module.state_dict()
    else:
        checkpoint['state_dict'] = model.state_dict()
    if optimizer is not None:
        checkpoint['optimizer'] = optimizer.state_dict()
    torch.save(checkpoint, filename)

def load_checkpoint(filename, model, optimizer=None, device="cpu"):
    checkpoint = torch.load(filename, map_location=device)

    model.load_state_dict(checkpoint['state_dict'])

    if optimizer is not None:
        optimizer.load_state_dict(checkpoint['optimizer'])
        return model, optimizer
    else:
        return model

class RunExperiment:
    def __init__(self, result_dir, mode="w"):
        self._check_path(result_dir)
        self.result_dir = result_dir
        self.mode = mode

    def _check_path(self, path):
        """Create directory if path doesn't exist"""
        if path is not None:
            if os.path.isfile(path):
                raise TypeError("Cannot create directory {}".format(path))
            target_dir = path

            if os.path.exists(path):
                warnings.warn(
                    "Experiment {} has been executed before".format(path))
                opt = input("Continue running the experiment, y/[n]: ")
                if opt.lower() != "y":
                    raise RuntimeError()
            pathlib.Path(target_dir).mkdir(parents=True, exist_ok=True)

    def create_logfile(self, name):
        fmt = ("%(color)s[%(levelname)s %(name)s %(asctime)s]"
               "%(end_color)s %(message)s")
        log_fmt = logzero.LogFormatter(fmt=fmt)

        if name is None:
            filename = None
        elif not name.endswith(".log"):
            filename = os.path.join(self.result_dir, name + ".log")
        else:
            filename = os.path.join(self.result_dir, name)

        if os.path.exists(filename):
            os.remove(filename)
        return logzero.setup_logger(name=name,
                                    logfile=filename,
                                    formatter=log_fmt)

    def create_tb_writer(self):
        # remove previous tensorboard results
        files = glob.glob(os.path.join(self.result_dir,
                                       'events.out.tfevents*'))
        for f in files:
            try:
                os.remove(f)
            except Exception:
                raise RuntimeError("Error while removing file {}".format(f))
        writer = SummaryWriter(self.result_dir)
        return writer

    def save_config(self, config):
        with open(os.path.join(self.result_dir, "config.yml"), "w") as fp:
            yaml.dump(config, fp)


import logging
import sys
import os
import subprocess
import fnmatch
import readline # pylint:disable=unused-import

from contextlib import contextmanager
from logging.handlers import SysLogHandler

# py2 compat
try:
    from subprocess import DEVNULL  # pylint: disable=no-name-in-module
except ImportError:
    DEVNULL = open("/dev/null", 'a+')
try:
    _input = raw_input # pylint: disable=undefined-variable
except NameError:
    _input = input

log = logging.getLogger("DD")

# NOTE: Yes, the version is wrong, but previous versions of this utility also
# hardcoded this value, because changing it will break any driver disk that has
# binary/library packages with "installer-enhancement = 19.0"..
# If we *need* to break compatibility, this should definitely get changed, but
# otherwise we probably shouldn't change this unless/until we're sure that
# everyone is using something like "installer-enhancement >= 19.0" instead..
ANACONDAVER = "19.0"

ARCH = os.uname()[4]
KERNELVER = os.uname()[2]

MODULE_UPDATES_DIR = "/lib/modules/%s/updates" % KERNELVER
FIRMWARE_UPDATES_DIR = "/lib/firmware/updates"

def mkdir_seq(stem):
    """
    Create sequentially-numbered directories starting with stem.

    For example, mkdir_seq("/tmp/DD-") would create "/tmp/DD-1";
    if that already exists, try "/tmp/DD-2", "/tmp/DD-3", and so on,
    until a directory is created.

    Returns the newly-created directory name.
    """
    n = 1
    while True:
        dirname = str(stem) + str(n)
        try:
            os.makedirs(dirname)
        except OSError as e:
            if e.errno != 17: raise
            n += 1
        else:
            return dirname

def find_repos(mnt):
    """find any valid driverdisk repos that exist under mnt."""
    dd_repos = []
    for root, dirs, files in os.walk(mnt, followlinks=True):
        repo = root+"/rpms/"+ARCH
        if "rhdd3" in files and "rpms" in dirs and os.path.isdir(repo):
            log.debug("found repo: %s", repo)
            dd_repos.append(repo)
    return dd_repos

# NOTE: it's unclear whether or not we're supposed to recurse subdirs looking
# for .iso files, but that seems like a bad idea if you mount some huge disk..
# So I've made a judgement call: we only load .iso files from the toplevel.
def find_isos(mnt):
    """find files named '.iso' at the top level of mnt."""
    return [mnt+'/'+f for f in os.listdir(mnt) if f.lower().endswith('.iso')]

class Driver(object):
    """Represents a single driver (rpm), as listed by dd_list"""
    def __init__(self, source="", name="", flags="", description="", repo=""):
        self.source = source
        self.name = name
        self.flags = flags
        self.description = description
        self.repo = repo

def dd_list(dd_path, anaconda_ver=None, kernel_ver=None):
    log.debug("dd_list: listing %s", dd_path)
    if not anaconda_ver:
        anaconda_ver = ANACONDAVER
    if not kernel_ver:
        kernel_ver = KERNELVER
    cmd = ["dd_list", '-d', dd_path, '-k', kernel_ver, '-a', anaconda_ver]
    out = subprocess.check_output(cmd, stderr=DEVNULL)
    out = out.decode('utf-8')
    drivers = [Driver(*d.split('\n',3)) for d in out.split('\n---\n') if d]
    log.debug("dd_list: found drivers: %s", ' '.join(d.name for d in drivers))
    for d in drivers: d.repo = dd_path
    return drivers

def dd_extract(rpm_path, outdir, kernel_ver=None, flags='-blmf'):
    log.debug("dd_extract: extracting %s", rpm_path)
    if not kernel_ver:
        kernel_ver = KERNELVER
    cmd = ["dd_extract", flags, '-r', rpm_path, '-d', outdir, '-k', kernel_ver]
    subprocess.check_output(cmd, stderr=DEVNULL) # discard stdout

def list_drivers(repos, anaconda_ver=None, kernel_ver=None):
    return [d for r in repos for d in dd_list(r, anaconda_ver, kernel_ver)]

def mount(dev, mnt=None):
    """Mount the given dev at the mountpoint given by mnt."""
    # NOTE: dev may be a filesystem image - "-o loop" is not necessary anymore
    if not mnt:
        mnt = mkdir_seq("/media/DD-")
    cmd = ["mount", dev, mnt]
    log.debug("mounting %s at %s", dev, mnt)
    subprocess.check_call(cmd)
    return mnt

def umount(mnt):
    log.debug("unmounting %s", mnt)
    subprocess.call(["umount", mnt])

@contextmanager
def mounted(dev, mnt=None):
    mnt = mount(dev, mnt)
    try:
        yield mnt
    finally:
        umount(mnt)

def iter_files(topdir, pattern=None):
    """iterator; yields full paths to files under topdir that match pattern."""
    for head, _, files in os.walk(topdir):
        for f in files:
            if pattern is None or fnmatch.fnmatch(f, pattern):
                yield os.path.join(head, f)

def ensure_dir(d):
    """make sure the given directory exists."""
    subprocess.check_call(["mkdir", "-p", d])

def move_files(files, destdir):
    """move files into destdir (iff they're not already under destdir)"""
    ensure_dir(destdir)
    for f in files:
        if f.startswith(destdir):
            continue
        subprocess.call(["mv", "-f", f, destdir])

def copy_files(files, destdir):
    """copy files into destdir (iff they're not already under destdir)"""
    ensure_dir(destdir)
    for f in files:
        if f.startswith(destdir):
            continue
        subprocess.call(["cp", "-a", f, destdir])

def append_line(filename, line):
    """simple helper to append a line to a file"""
    if not line.endswith("\n"):
        line += "\n"
    with open(filename, 'a') as outf:
        outf.write(line)

# NOTE: items returned by read_lines should match items passed to append_line,
#       which is why we remove the newlines
def read_lines(filename):
    """return a list containing each line in filename, with newlines removed."""
    try:
        return [line.rstrip('\n') for line in open(filename)]
    except IOError:
        return []

def save_repo(repo, target="/run/install"):
    """copy a repo to the place where the installer will look for it later."""
    newdir = mkdir_seq(os.path.join(target, "DD-"))
    log.debug("save_repo: copying %s to %s", repo, newdir)
    subprocess.call(["cp", "-arT", repo, newdir])
    return newdir

def extract_drivers(drivers=None, repos=None, outdir="/updates",
                    pkglist="/run/install/dd_packages"):
    """
    Extract drivers - either a user-selected driver list or full repos.

    drivers should be a list of Drivers to extract, or None.
    repos should be a list of repo paths to extract, or None.
    Raises ValueError if you pass both.

    If any packages containing modules or firmware are extracted, also:
    * call save_repo for that package's repo
    * write the package name(s) to pkglist.

    Returns True if any package containing modules was extracted.
    """
    if not drivers:
        drivers = []
    if drivers and repos:
        raise ValueError("extract_drivers: drivers or repos, not both")
    if repos:
        drivers = list_drivers(repos)

    save_repos = set()
    new_drivers = False

    ensure_dir(outdir)

    for driver in drivers:
        log.info("Extracting: %s", driver.name)
        dd_extract(driver.source, outdir)
        # Make sure we install modules/firmware into the target system
        if 'modules' in driver.flags or 'firmwares' in driver.flags:
            append_line(pkglist, driver.name)
            save_repos.add(driver.repo)
            new_drivers = True

    # save the repos containing those packages
    for repo in save_repos:
        save_repo(repo)

    return new_drivers

def grab_driver_files(outdir="/updates"):
    """
    copy any modules/firmware we just extracted into the running system.
    return a list of the names of any modules we just copied.
    """
    modules = list(iter_files(outdir+'/lib/modules',"*.ko*"))
    firmware = list(iter_files(outdir+'/lib/firmware'))
    copy_files(modules, MODULE_UPDATES_DIR)
    copy_files(firmware, FIRMWARE_UPDATES_DIR)
    move_files(modules, outdir+MODULE_UPDATES_DIR)
    move_files(firmware, outdir+FIRMWARE_UPDATES_DIR)
    return [os.path.basename(m).split('.ko')[0] for m in modules]

def load_drivers(modnames):
    """run depmod and try to modprobe all the given module names."""
    log.debug("load_drivers: %s", modnames)
    subprocess.call(["depmod", "-a"])
    subprocess.call(["modprobe", "-a"] + modnames)

# We *could* pass in "outdir" if we wanted to extract things somewhere else,
# but right now the only use case is running inside the initramfs, so..
def process_driver_disk(dev, interactive=False):
    try:
        _process_driver_disk(dev, interactive=interactive)
    except (subprocess.CalledProcessError, IOError) as e:
        log.error("ERROR: %s", e)

def _process_driver_disk(dev, interactive=False):
    """
    Main entry point for processing a single driver disk.
    Mount the device/image, find repos, and install drivers from those repos.

    If there are no repos, look for .iso files, and (if present) recursively
    process those.

    If interactive, ask the user which driver(s) to install from the repos,
    or ask which iso file to process (if no repos).
    """
    log.info("Examining %s", dev)
    with mounted(dev) as mnt:
        repos = find_repos(mnt)
        isos = find_isos(mnt)

        if repos:
            if interactive:
                new_modules = extract_drivers(drivers=repo_menu(repos))
            else:
                new_modules = extract_drivers(repos=repos)
            if new_modules:
                modules = grab_driver_files()
                load_drivers(modules)
        elif isos:
            if interactive:
                isos = iso_menu(isos)
            for iso in isos:
                process_driver_disk(iso, interactive=interactive)
        else:
            print("=== No driver disks found in %s! ===\n" % dev)

def process_driver_rpm(rpm):
    try:
        _process_driver_rpm(rpm)
    except (subprocess.CalledProcessError, IOError) as e:
        log.error("ERROR: %s", e)

def _process_driver_rpm(rpm):
    """
    Process a single driver rpm. Extract it, install it, and copy the
    rpm for Anaconda to install on the target system.
    """
    log.info("Examining %s", rpm)
    new_modules = extract_drivers(repos=[os.path.dirname(rpm)])
    if new_modules:
        modules = grab_driver_files()
        load_drivers(modules)

def mark_finished(user_request, topdir="/tmp"):
    log.debug("marking %s complete in %s", user_request, topdir)
    append_line(topdir+"/dd_finished", user_request)

def all_finished(topdir="/tmp"):
    finished = read_lines(topdir+"/dd_finished")
    todo = read_lines(topdir+"/dd_todo")
    return all(r in finished for r in todo)

def finish(user_request, topdir="/tmp"):
    # mark that we've finished processing this request
    mark_finished(user_request, topdir)
    # if we're done now, let dracut know
    if all_finished(topdir):
        append_line(topdir+"/dd.done", "true")

# --- DEVICE LISTING HELPERS FOR THE MENU -----------------------------------

class DeviceInfo(object):
    def __init__(self, **kwargs):
        self.device = kwargs.get("DEVNAME", '')
        self.uuid = kwargs.get("UUID", '')
        self.fs_type = kwargs.get("TYPE", '')
        self.label = kwargs.get("LABEL", '')

    def __repr__(self):
        return '<DeviceInfo %s>' % self.device

    @property
    def shortdev(self):
        # resolve any symlinks (/dev/disk/by-label/OEMDRV -> /dev/sr0)
        dev = os.path.realpath(self.device)
        # NOTE: not os.path.basename 'cuz some devices legitimately have
        # a '/' in their name: /dev/cciss/c0d0, /dev/i2o/hda, etc.
        if dev.startswith('/dev/'):
            dev = dev[5:]
        return dev

def blkid():
    try:
        out = subprocess.check_output("blkid -o export -s UUID -s TYPE".split())
        out = out.decode('ascii')
        return [dict(kv.split('=',1) for kv in block.splitlines())
                                     for block in out.split('\n\n')]
    except subprocess.CalledProcessError:
        return []

# We use this to get disk labels because blkid's encoding of non-printable and
# non-ascii characters is weird and doesn't match what you'd expect to see.
def get_disk_labels():
    return {os.path.realpath(s):os.path.basename(s)
            for s in iter_files("/dev/disk/by-label")}

def get_deviceinfo():
    disk_labels = get_disk_labels()
    deviceinfo = [DeviceInfo(**d) for d in blkid()]
    for dev in deviceinfo:
        dev.label = disk_labels.get(dev.device, '')
    return deviceinfo

# --- INTERACTIVE MENU JUNK ------------------------------------------------

class TextMenu(object):
    def __init__(self, items, title=None, formatter=None, headeritem=None,
                 refresher=None, multi=False, page_height=20):
        self.items = items
        self.title = title
        self.formatter = formatter
        self.headeritem = headeritem
        self.refresher = refresher
        self.multi = multi
        self.page_height = page_height
        self.pagenum = 1
        self.selected_items = []
        self.is_done = False
        if callable(items):
            self.refresher = items
            self.refresh()

    @property
    def num_pages(self):
        pages, leftover = divmod(len(self.items), self.page_height)
        if leftover:
            return pages+1
        else:
            return pages

    def next(self):
        if self.pagenum < self.num_pages:
            self.pagenum += 1

    def prev(self):
        if self.pagenum > 1:
            self.pagenum -= 1

    def refresh(self):
        if callable(self.refresher):
            self.items = self.refresher()

    def done(self):
        self.is_done = True

    def invalid(self, k):
        print("Invalid selection %r" % k)

    def toggle_item(self, item):
        if item in self.selected_items:
            self.selected_items.remove(item)
        else:
            self.selected_items.append(item)
        if not self.multi:
            self.done()

    def items_on_page(self):
        start_idx = (self.pagenum-1) * self.page_height
        if start_idx > len(self.items):
            return []
        else:
            items = self.items[start_idx:start_idx+self.page_height]
            return enumerate(items, start=start_idx)

    def format_item(self, item):
        if callable(self.formatter):
            return self.formatter(item)
        else:
            return str(item)

    def format_items(self):
        for n, i in self.items_on_page():
            if self.multi:
                x = 'x' if i in self.selected_items else ' '
                yield "%2d) [%s] %s" % (n+1, x, self.format_item(i))
            else:
                yield "%2d) %s" % (n+1, self.format_item(i))

    def format_header(self):
        if self.multi:
            return (8*' ')+self.format_item(self.headeritem)
        else:
            return (4*' ')+self.format_item(self.headeritem)

    def action_dict(self):
        actions = {
            'r': self.refresh,
            'n': self.next,
            'p': self.prev,
            'c': self.done,
        }
        for n, i in self.items_on_page():
            actions[str(n+1)] = lambda item=i: self.toggle_item(item)
        return actions

    def format_page(self):
        page = '\n(Page {pagenum} of {num_pages}) {title}\n{items}'
        items = list(self.format_items())
        if self.headeritem:
            items.insert(0, self.format_header())
        return page.format(pagenum=self.pagenum,
                           num_pages=self.num_pages,
                           title=self.title or '',
                           items='\n'.join(items))

    def format_prompt(self):
        options = [
            '# to toggle selection' if self.multi else '# to select',
            "'r'-refresh" if callable(self.refresher) else None,
            "'n'-next page" if self.pagenum < self.num_pages else None,
            "'p'-previous page" if self.pagenum > 1 else None,
            "or 'c'-continue"
        ]
        return ', '.join(o for o in options if o is not None) + ': '

    def run(self):
        while not self.is_done:
            print(self.format_page())
            k = _input(self.format_prompt())
            action = self.action_dict().get(k)
            if action:
                action()
            else:
                self.invalid(k)
        return self.selected_items

def repo_menu(repos):
    drivers = list_drivers(repos)
    if not drivers:
        log.info("No suitable drivers found.")
        return []
    menu = TextMenu(drivers, title="Select drivers to install",
                             formatter=lambda d: d.source,
                             multi=True)
    result = menu.run()
    return result

def iso_menu(isos):
    menu = TextMenu(isos, title="Choose driver disk ISO file")
    result = menu.run()
    return result

def device_menu():
    fmt = '{0.shortdev:<8.8} {0.fs_type:<8.8} {0.label:<20.20} {0.uuid:<.36}'
    hdr = DeviceInfo(DEVNAME='DEVICE', TYPE='TYPE', LABEL='LABEL', UUID='UUID')
    menu = TextMenu(get_deviceinfo, title="Driver disk device selection",
                                    formatter=fmt.format,
                                    headeritem=hdr)
    result = menu.run()
    return result

# --- COMMANDLINE-TYPE STUFF ------------------------------------------------

def setup_log():
    log.setLevel(logging.DEBUG)
    handler = SysLogHandler(address="/dev/log")
    log.addHandler(handler)
    handler = logging.StreamHandler()
    handler.setLevel(logging.INFO)
    formatter = logging.Formatter("DD: %(message)s")
    handler.setFormatter(formatter)
    log.addHandler(handler)

def print_usage():
    print("usage: driver-updates --interactive")
    print("       driver-updates --disk DISK KERNELDEV")
    print("       driver-updates --net URL LOCALFILE")

def check_args(args):
    if args and args[0] == '--interactive':
        return True
    elif len(args) == 3 and args[0] in ('--disk', '--net'):
        return True
    else:
        return False

def main(args):
    if not check_args(args):
        print_usage()
        raise SystemExit(2)

    mode = args.pop(0)

    if mode in ('--disk', '--net'):
        request, dev = args
        if dev.endswith(".rpm"):
            process_driver_rpm(dev)
        else:
            process_driver_disk(dev)

    elif mode == '--interactive':
        log.info("starting interactive mode")
        request = 'menu'
        while True:
            dev = device_menu()
            if not dev: break
            process_driver_disk(dev.pop().device, interactive=True)

    finish(request)

    # When using inst.dd and a cdrom stage2 it isn't mounted before running driver-updates
    # In order to get the stage2 cdrom mounted it either needs to be swapped back in
    # or we need to re-trigger the block rules.
    if os.path.exists("/tmp/anaconda-dd-on-cdrom") and not os.path.exists("/dev/root"):
        cmd = ["udevadm", "trigger", "--action=change", "--subsystem-match=block"]
        subprocess.check_call(cmd)

if __name__ == '__main__':
    setup_log()
    try:
        main(sys.argv[1:])
    except KeyboardInterrupt:
        log.info("exiting.")


import requests
def get_lb_total_pages(season):
    homs_url = "https://data.ninjakiwi.com/battles2/homs"
    homs_data = requests.request("GET", homs_url).json()
    season_index = [hom_data['name'].split(" ")[1] for hom_data in homs_data["body"]].index(str(season))
    total_hom_players = homs_data['body'][season_index]["totalScores"]
    lb_page_count = (total_hom_players - 1) // 50 + 1
    return lb_page_count

def get_player_list(season):
    player_list = []
    lb_total_pages = get_lb_total_pages(season)
    for lb_page_num in range(1, lb_total_pages + 1):
        lb_url = f"https://data.ninjakiwi.com/battles2/homs/season_{str(season - 1)}/leaderboard?page={lb_page_num}"
        lb_json = requests.request("GET", lb_url).json()
        player_list += [[player["displayName"], player["score"]] for player in lb_json["body"]]
    return player_list

def get_filtered_player_list(season):
    player_list = get_player_list(season)
    filtered_player_list = [player for player in player_list if '<' in player[0] and '>' in player[0]]
    return filtered_player_list

def get_clan_counts():
    # update this every season
    season = 13
    filtered_player_list = get_filtered_player_list(season)
    clan_counts = {}
    for entry in filtered_player_list:
        name = entry[0]
        if '<' in name and '>' in name:
            start = name.index('<')
            try:
                end = name.index('>', start)
            except ValueError:
                continue
            clan = name[start + 1:end].lower()
            clan_members = clan_counts.get(clan, [0, 0])[0] + 1
            clan_total_score = clan_counts.get(clan, [0, 0])[1] + entry[1]
            clan_counts[clan] = [clan_members, clan_total_score]
    lst_count = [[clan, clan_counts[clan][0], clan_counts[clan][1], clan_counts[clan][1] // clan_counts[clan][0]] for clan in clan_counts]
    # secondary sort: score
    sorted_count = sorted(lst_count, key=lambda x: x[2], reverse=True)
    # primary sort: member count
    return sorted_count


# !/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2018 Zimeng Qiu <zimengq@andrew.cmu.edu>
# Licensed under the GNU LGPL v2.1 - http://www.gnu.org/licenses/lgpl.html

import numpy as np
import matplotlib.pyplot as plt
import argparse
import numbers
import math
import os
import sys
import logging

from operator import itemgetter

class RidgeRegression(object):
    """
     Ridge Regression(Linear Least Squares Regression with Tikhonov regularization).
    """

    def __init__(self):
        self.beta = None

    def fit(self, X, y, alpha=0):
        """
        Fits the ridge regression model to the training data.

        Arguments
        ----------
        X: nxp matrix of n examples with p independent variables
        y: response variable vector for n examples
        alpha: regularization parameter.
        """
        if not isinstance(alpha, numbers.Number) or alpha < 0:
            raise ValueError("Penalty term must be positive; got (alpha=%r)"
                             % alpha)

        X_trans = np.matrix.transpose(X)
        I = np.identity(X.shape[1])
        self.beta = np.dot(np.linalg.inv((np.dot(X_trans, X) + alpha * I)), np.dot(X_trans, y))

    def predict(self, X):
        """
        Predicts the dependent variable of new data using the model.

        Arguments
        ----------
        X: nxp matrix of n examples with p covariates

        Returns
        ----------
        response variable vector for n examples
        """
        if self.beta is None:
            raise SystemExit("Train model before predict!")

        return np.dot(X, self.beta)

    def validate(self, X, y):
        """
        Returns the RMSE(Root Mean Squared Error) when the model is validated.

        Arguments
        ----------
        X: nxp matrix of n examples with p covariates
        y: response variable vector for n examples

        Returns
        ----------
        RMSE when model is used to predict y
        """
        return np.sqrt(((self.predict(X) - y) ** 2).mean())

# run command:
# python ridge.py --X_train_set=Xtraining.csv --y_train_set=Ytraining.csv --X_val_set=Xvalidation.csv --y_val_set=Yvalidation.csv --y_test_set=Ytesting.csv --X_test_set=Xtesting.csv

if __name__ == '__main__':
    program = os.path.basename(sys.argv[0])
    logger = logging.getLogger(program)

    logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s')
    logging.root.setLevel(level=logging.INFO)
    logger.info("running %s " % ' '.join(sys.argv))

    # Read command line arguments
    parser = argparse.ArgumentParser(description='Fit a Ridge Regression Model')
    parser.add_argument('--X_train_set', required=True,
                        help='The file which contains the covariates of the training dataset.')
    parser.add_argument('--y_train_set', required=True,
                        help='The file which contains the response of the training dataset.')
    parser.add_argument('--X_val_set', required=True,
                        help='The file which contains the covariates of the validation dataset.')
    parser.add_argument('--y_val_set', required=True,
                        help='The file which contains the response of the validation dataset.')
    parser.add_argument('--X_test_set', required=True,
                        help='The file which containts the covariates of the testing dataset.')
    parser.add_argument('--y_test_set', required=True,
                        help='The file which containts the response of the testing dataset.')

    args = parser.parse_args()

    # Parse training dataset
    X_train = np.genfromtxt(args.X_train_set, delimiter=',')
    y_train = np.genfromtxt(args.y_train_set, delimiter=',')

    # Parse validation set
    X_val = np.genfromtxt(args.X_val_set, delimiter=',')
    y_val = np.genfromtxt(args.y_val_set, delimiter=',')

    # Parse testing set
    X_test = np.genfromtxt(args.X_test_set, delimiter=',')
    y_test = np.genfromtxt(args.y_test_set, delimiter=',')

    # find the best regularization parameter
    lambda_rec = []
    rmse_rec = []
    predicted_rec = []
    coef_rec = []
    model = RidgeRegression()
    for _lambda in range(1, 2000, 2):
        _lambda /= 1000
        model.fit(X_train, y_train, alpha=_lambda)
        predict_result = model.predict(X_test)
        rmse = model.validate(X_val, y_val)
        lambda_rec.append(_lambda)
        rmse_rec.append(rmse)
        predicted_rec.append(predict_result)
        coef_rec.append(model.beta)
        # print("Lambda: {}  RMSE: {}".format(_lambda, rmse))
    optimal_lambda = lambda_rec[rmse_rec.index(min(rmse_rec))]
    optimal_predicted = predicted_rec[rmse_rec.index(min(rmse_rec))]
    logger.info("Optimal Lambda: {}".format(optimal_lambda))
    logger.info("Minimum RMSE: {}".format(min(rmse_rec)))

    # plot rmse versus lambda
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot(lambda_rec, rmse_rec)
    ax.set_title("RMSE Cruve Versus Lambda")
    ax.set_xlabel("Lambda")
    ax.set_ylabel("RMSE")
    ax.axvline(optimal_lambda, c = "r", lw = 2)
    ax.set_ylim(0, 20)
    ax.annotate(
        'Lowest RMSE, Lambda={}'.format(optimal_lambda),
        xy=(optimal_lambda, min(rmse_rec)),
        # xytext=(3, 1.5),
        arrowprops=dict(facecolor='black', shrink=0.05),
        )

    #  plot predicted versus real value
    fig2 = plt.figure()
    ax2 = fig2.add_subplot(111)
    pre_vs_real = sorted(zip(y_test, optimal_predicted), key=lambda x:x[0])
    real_value = [_[0] for _ in pre_vs_real]
    predicted = [_[1] for _ in pre_vs_real]
    ax2.plot(real_value, predicted)
    ax2.set_title("predicted Cruve Versus Real Value")
    ax2.set_xlabel("Real Value")
    ax2.set_ylabel("Predicted Value")

    #  plot regression coefficients
    labels = [
        "beta0",
        "beta1",
        "beta2",
        "beta3",
        "beta4",
        "beta5",
        "beta6",
        "beta7",
        "beta8",
        "beta9",
        "beta10",
        "beta11",
        "beta12",
        "beta13",
        "beta14",
        "beta15",
        "beta16",
        "beta17",
        "beta18",
        "beta19"
    ]
    fig3 = plt.figure()
    ax3 = fig3.add_subplot(111)
    for i in range(0,20):
        coef = [_[i] for _ in coef_rec]
        ax3.plot(lambda_rec, coef)
    ax3.set_title("Beta Curve Versue Lambda")
    ax3.set_xlabel("Lambda")
    ax3.set_ylabel("Elements of Beta")
    ax3.legend(labels)

    while True:
        try:
            plt.show()
        except UnicodeDecodeError:
            continue
        break


h, n = map(int, input().split())
INF = 10 ** 5
AB = [list(map(int, input().split())) for _ in range(n)]
dp = [[float('inf')] * (h + 10 ** 4 + 100) for _ in range(n + 1)]

# i までの魔法 n
# j HP h
# dp[i][j]

for i in range(n + 1):
    dp[i][0] = 0

# i + 1種類までの魔法を使える
for i in range(n):
    # HPぴったj
    for j in range(1, h + 10 ** 4 + 100):
        if j <= AB[i][0]:
            dp[i + 1][j] = dp[i][j]
        else:
            dp[i + 1][j] = min(dp[i + 1][j], dp[i + 1][j - AB[i][0]] + AB[i][1])

ans = float('inf')
for j in range(h, h + 10 ** 4 + 100):
    ans = min(ans, dp[n][j])
print(ans)


import requests
from bs4 import BeautifulSoup

def get_html(url):
    try:
        result = requests.get(url)
        result.raise_for_status()
        return result.text
    except(requests.RequestException, ValueError):
        print("Сетевая ошибка")
        return False

def get_python_news():
    html = get_html("https://www.python.org/blogs/")
    if html:
        soup = BeautifulSoup(html, "html.parser")
        all_news = soup.find('ul', class_='list-recent-posts').findAll('li')
        result_news = []
        for news in all_news:
            title = news.find('a').text  # ищем строку с а и копируем текст между <>
            url = news.find('a')['href']  # ищем а и копируем ссылку через ['href']
            published = news.find('time').text  # ищем time и копируем дату публикации
            # добавляем в наш список в виде словаря (список словарей)
            result_news.append({
                "title": title,
                "url": url,
                "published": published
            })
        return result_news
    return False

#
# if __name__ == "__main__":
#     html = get_html("https://www.python.org/blogs/")
#     if html:
#         # [1] копируем страницу с кодом с сайта полностью
#         # with open("python.org.html", "w", encoding="utf8") as f:
#         #     f.write(html)
#
#         # [2] печатаем наш список словорей
#         news = get_python_news(html)
#         print(news)


# Preconditioned GMRES solver for Math 5344, Fall 2020.
# Katharine Long, Texas Tech.
# This code is in the public domain.

import time
from copy import deepcopy
import scipy.linalg as la
import numpy as np
import scipy.sparse.linalg as spla
import scipy.sparse as sp
from numpy.random import MT19937
from numpy.random import RandomState, SeedSequence
from Givens import findGivensCoefficients, applyGivens, applyGivensInPlace
from scipy.io import mmread
from BasicPreconditioner import *

# A simple timer class
class MyTimer:
    def __init__(self, name):
        self.name = name
        self.start = time.time()

    def stop(self):
        self.stop = time.time()

    def walltime(self):
        return self.stop - self.start

# Unified mvmult user interface for both scipy.sparse and numpy matrices.
# In scipy.sparse, mvmult is done using the overloaded * operator, e.g., A*x.
# In numpy, mvmult is done using the dot() function, e.g., dot(A,x).
# This function chooses which to use based on whether A is stored as
# a sparse matrix.
def mvmult(A, x):
    if sp.issparse(A):
        return A*x
    else:
        return np.dot(A,x)

# This is function applies GMRES to solve Ax=b for x with optional right
# preconditioning
# Input arguments:
# (*) A -- the system matrix in dense numpy form (no point in going sparse yet)
# (*) b -- the RHS vector as a numpy array
# (*) maxiters -- maximum number of iterations to attempt
# (*) tol -- relative residual tolerance. If ||r_k|| <= tol*||b||, stop.
# (*) precond -- preconditioner. Default is a do-nothing preconditioner. The
#                preconditioner needs to be a class providing an applyRight()
#                function that carries out the operation $$M_R^{-1} v$$ on a
#                vector v, resulting the result as a numpy array.
#
def GMRES(A, b, maxiters=100, tol=1.0e-6,
    precond=PreconditionerBase()):

    # We'll scale residual norms relative to ||b||
    norm_b = la.norm(b)

    # Get shape of matrix and check that it's square. We'll need the size n
    # to set the dimension of the Arnoldi vectors (i.e., the number of rows in
    # the matrix Q).
    n,nc = A.shape
    if n!=nc:
        raise RuntimeError('InnerGMRES: Non-square matrix; size is %d by %d'
            % (n,nc))

    # Allocate space for Arnoldi results
    # Q is n by m+1 after m Arnoldi steps, preallocate to maxiters+1 columns
    Q = np.zeros([n, maxiters+1])
    # HBar is m+1 by m after m Arnoldi steps, preallocated to m=maxiters.
    # We will triangularize HBar via Givens as we go.
    HBar = np.zeros([maxiters+1, maxiters])

    # Create an array in which we'll store all the Givens cosines and sines
    CS = np.zeros([maxiters,2])

    # Initial residual is b.
    r0 = b

    # Initialize q_0 and beta
    beta = la.norm(r0)
    Q[:,0] = r0 / beta

    # Initialize RHS for least squares problem.
    # Least squares problem is to minimize ||HBar y - beta e1||.
    e1 = np.zeros(maxiters+1)
    e1[0] = 1.0
    g = beta*e1 # Will be modified by Givens rotations as we go

    # Flag to indicate whether Arnoldi algorithm has hit breakdown
    # (In Arnoldi's algorithm, breakdown is a good thing!)
    arnoldiBreakdown = False

    # Outer Arnoldi loop for up to maxiters vectors
    for k in range(maxiters):

        # Form A*M_R^-1*q_k
        u = mvmult(A, precond.applyRight(Q[:,k]))

        # Inner modified Gram-Schmidt loop
        for j in range(k+1):
            HBar[j,k]=np.dot(Q[:,j], u)
            u -= HBar[j,k]*Q[:,j]

        # Fill in the extra entry in HBar
        HBar[k+1,k]=la.norm(u)

        # Check for breakdown of Arnoldi. Recall that Arnoldi breaks down
        # iff the iteration count is equal to the degree of the minimal
        # polynomial of A. Therefore, the exact solution is in the current
        # Krylov space and we have converged.
        hLastColNorm = la.norm(HBar[0:k+1,k])
        if abs(HBar[k+1,k]) <= 1.0e-16 * hLastColNorm:
            arnoldiBreakdown = True
        else:
            Q[:,k+1]=u/HBar[k+1,k]

        # We've now updated the Hessenberg matrix HBar with the
        # most recent column. The next step is to triangularize
        # it with Givens rotations.

        # First, apply all previous Givens rotations to
        # it, in order.
        for j in range(k):
            #HBar[:,k] = applyGivensInPlace(HBar[:,k], CS[j,0], CS[j,1], j)
            applyGivensInPlace(HBar[:,k], CS[j,0], CS[j,1], j)

        # Find the Givens rotation that will zero
        # out the bottom entry in the last column.
        CS[k,:]=findGivensCoefficients(HBar[:,k], k)

        # Apply the Givens rotation to kill the subdiagonal in the most
        # recent column
        #HBar[:,k] = applyGivens(HBar[:,k], CS[k,0], CS[k,1], k)
        applyGivensInPlace(HBar[:,k], CS[k,0], CS[k,1], k)
        # Apply the same rotation to the RHS of the least squares problem
        #g = applyGivens(g, CS[k,0], CS[k,1], k)
        applyGivensInPlace(g, CS[k,0], CS[k,1], k)

        # The current residual norm is the absolute value of the final entry in
        # the RHS vector g.
        norm_r_k = np.abs(g[k+1])

        # Print the current residual
        # print('\titer %4d\tr=%12.5g' %(k, (norm_r_k/norm_b)))

        # Check for convergence
        if (arnoldiBreakdown==True) or (norm_r_k <= tol*norm_b):
            # print('GMRES converged!')
            y = la.solve(HBar[0:k+1,0:k+1], g[0:k+1])
            x = precond.applyRight(np.dot(Q[:,0:k+1],y))
            # Compute residual, and compare to implicitly computed
            # residual
            resid = b - mvmult(A,x)
            # print('Implicit residual=%12.5g, true residual=%12.5g'
                # % (norm_r_k/norm_b, la.norm(resid)/norm_b))
            return (True, x, k)

    # Check for reaching maxiters without convergence
    print('GMRES failed to converge after %g iterations'
            % maxiters)
    return (False, 0, maxiters)

# ---- Test program --------

if __name__=='__main__':

    rs = RandomState(MT19937(SeedSequence(123456789)))

    level = 9
    A = mmread('TestMatrices/DH-Matrix-%d.mtx' % level)
    A = A.tocsr()
    n,nc = A.shape
    print('System is %d by %d' %(n,nc))

    if n < 12000:
        Adense = A.todense()
        print('\nCondition number ', np.linalg.cond(Adense))

    # Create a solution

    xEx = rs.rand(n)
    # Multiply the solution by A to create a RHS vector
    b = mvmult(A, xEx)

    # Create a preconditioner
    drop = 1.0e-0
    print('Creating ILU preconditioner with drop tol = %g' % drop)
    precTimer = MyTimer('ILU creation')
    ILU = ILURightPreconditioner(A, drop_tol=drop, fill_factor=15)
    precTimer.stop()

    # Run GMRES
    print('Running GMRES')
    gmresTimer = MyTimer('GMRES')
    (conv,x,_) = GMRES(A,b,maxiters=500, tol=1.0e-6, precond=ILU)
    gmresTimer.stop()

    # Delete the preconditioner object to save memory for the factorization
    del ILU

    # Print the error
    if conv:
        err = la.norm(x - xEx)/la.norm(xEx)
        print('\nGMRES relative error norm = %10.3g' % err)
    else:
        print('GMRES failed')

    # For comparison, do a sparse direct solve using SuperLU
    print('Running SuperLU')
    spluTimer = MyTimer('Super LU')
    LU = spla.splu(A.tocsc())
    xDirect = LU.solve(b)
    spluTimer.stop()

    err = la.norm(xDirect - xEx)/la.norm(xEx)
    print('\nSparse direct solve error norm = %10.3g' % err)

    print('\nTotal GMRES time (prec setup +iter)\t %10.3g seconds'
        % (precTimer.walltime()+gmresTimer.walltime()))
    print('\t-Preconditioner setup time:      %10.3g seconds'
        % precTimer.walltime())
    print('\t-GMRES iteration time:           %10.3g seconds'
        % gmresTimer.walltime())
    print('\nDirect solve time\t                %10.3g seconds'
        % spluTimer.walltime())


# -*- coding: utf-8 -*-
"""
Created on Wed May 30 00:10:56 2018

@author: wstro
"""

import pandas as ps

base=ps.read_csv('credit-data.csv')
base.loc[base.age <0,'age']=40.92

previsores=base.iloc[:,1:4].values
classe=base.iloc[:,4].values

from sklearn.preprocessing import Imputer

imputer=Imputer(missing_values='NaN',strategy='mean',axis=0)
imputer=imputer.fit(previsores[:,1:4])
previsores[:,1:4]=imputer.transform(previsores[:,1:4])

from sklearn.preprocessing import StandardScaler
escalona= StandardScaler()
previsores=escalona.fit_transform(previsores)

from sklearn.cross_validation import train_test_split

previsores_treinamento , previsores_teste,classe_treinamento, classe_teste=train_test_split(previsores,classe,test_size=0.25, random_state=0)
import keras
from keras.models import Sequential
from keras.layers import Dense
classificador=Sequential()
classificador.add(Dense(units=2,activation='relu',input_dim=3))
classificador.add(Dense(units=2,activation='relu'))
classificador.add(Dense(units=1,activation='sigmoid'))#camada binária retorna sigmode

classificador.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])
classificador.fit(previsores_treinamento,classe_treinamento,batch_size=10,nb_epoch=100)

previsoes=classificador.predict(previsores_teste)
previsoes=(previsoes>0.5)

from sklearn.metrics import confusion_matrix,accuracy_score

precisao=accuracy_score(classe_teste,previsoes)

matriz=confusion_matrix(classe_teste,previsoes)

Aprendizado de Maquina/Codigo/Redes Neurais/keras_credit_data.py


import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates
from datetime import datetime

def main():
    f = open('graph.csv', 'r')

    data, dates, severities = [], [], []
    count = 0

    for lines in f:
        if count != 0:
            x = lines.split(',')
            dates.append(str(x[0]).strip())
            data.append(str(x[1]).strip() + ", " + str(x[2]).strip())
            severities.append(str(x[3]).strip())
        count += 1

    dates = [datetime.strptime(ii, "%a %b %d %H:%M:%S %Y") for ii in dates]
    levels = np.array([-5, 5, -3, 3, -1, 1])
    fig, ax = plt.subplots(figsize=(13, 5))

    start = min(dates)
    stop = max(dates)
    ax.plot((start, stop), (0, 0), 'k', alpha=.5)

    low = 'g'
    medium = 'y'
    high = 'r'
    for ii, (iname, idate, iseverity) in enumerate(zip(data, dates, severities)):
        level = levels[ii % 6]
        vert = 'top' if level < 0 else 'bottom'
        rotation = 80 if level < 0 else 110
        severity = 'w'
        if iseverity == 'MEDIUM':
            severity = medium
        elif iseverity == 'HIGH':
            severity = high
        elif iseverity == 'LOW':
            severity = low
        ax.scatter(idate, 0, s=100, facecolor=severity, edgecolor='k', zorder=9999)
        ax.plot((idate, idate), (0, level), c='b', alpha=.7)
        ax.text(idate, level, iname,
                horizontalalignment='left', verticalalignment=vert, fontsize=10,
                backgroundcolor=(1., 1., 1., .3))

    ax.set(title="Event Viewer")

    ax.get_xaxis().set_major_locator(mdates.MonthLocator(interval=1))
    ax.get_xaxis().set_major_formatter(mdates.DateFormatter("%b %d %Y"))
    fig.autofmt_xdate()

    plt.setp((ax.get_yticklabels() + ax.get_yticklines() +
              list(ax.spines.values())), visible=False)
    plt.show()


# encoding: utf-8

"""
Django settings for ihmc project.

For more information on this file, see
https://docs.djangoproject.com/en/1.6/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.6/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os

BASE_DIR = os.path.dirname(os.path.dirname(__file__))

from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS as TCP

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '9+u!*#lzy1r)6@-1ff2i9nq1b4k59+5a$&lc!a9^6+nn)@4p@('

# SECURITY WARNING: don't run with debug turned on in production!
DEV = False

DEBUG = False

TEMPLATE_DEBUG = True

ALLOWED_HOSTS = ['localhost', 'ussamkongre.com','www.ussamkongre.com', 'conference.ussam.co']

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',
    'bootstrapform',
    'common',
    # 'django.contrib.sites',
    'registration',
    'pages',
    'seo',
    'payments',
    'easy_thumbnails',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

TEMPLATE_CONTEXT_PROCESSORS = TCP + (
    'django.core.context_processors.request',
    'pages.context_processors.site',
)

ROOT_URLCONF = 'hhac.urls'

WSGI_APPLICATION = 'hhac.wsgi.application'

# Internationalization
# https://docs.djangoproject.com/en/1.6/topics/i18n/

LANGUAGE_CODE = 'tr'

ugettext = lambda s: s # dummy ugettext function, as django's docs say

LANGUAGES = (
    ('tr', u'Türkçe'),
    ('en', u'English'),
)

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = False

USE_TZ = False

SITE_ID = 1

# Additional locations of static files
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    os.path.join(BASE_DIR, 'templates'),
)

SERVER_EMAIL = ""
DEFAULT_FROM_EMAIL = ""
EMAIL_HOST = ""
EMAIL_HOST_PASSWORD = ""
EMAIL_HOST_USER = ""
EMAIL_PORT = 25
EMAIL_USE_TLS = True

ACCOUNT_ACTIVATION_DAYS = 7

AUTH_USER_MODEL = 'registration.User'

LOCALE_PATHS = (
    os.path.join(BASE_DIR, 'locale'),
)

SEO_FOR_MODELS = (
    'django.contrib.sites.models.Site',
)

THUMBNAIL_ALIASES = {
    '': {
        'big': {'size': (800, 0), },
        'normal': {'size': (600, 0),},
        'small': {'size': (200, 200),'autocrop': True, 'crop': 'smart', 'upscale': True,},
        'billboard': {'size': (710, 250),'autocrop': True, 'crop': 'smart', 'upscale': True,},
    },
}

THUMBNAIL_SUBDIR = 'thumbnails'

'''
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        # Include the default Django email handler for errors
        # This is what you'd get without configuring logging at all.
        'mail_admins': {
            'class': 'django.utils.log.AdminEmailHandler',
            'level': 'ERROR',
             # But the emails are plain text by default - HTML is nicer
            'include_html': True,
        },
        # Log to a text file that can be rotated by logrotate
        'logfile': {
            'class': 'logging.handlers.WatchedFileHandler',
            'filename': os.path.join(BASE_DIR, 'logs','myapp.log'),
        },
    },
    'loggers': {
        # Again, default Django configuration to email unhandled exceptions
        'django.request': {
            'handlers': ['logfile'],
            'level': 'ERROR',
            'propagate': True,
        },
        # Might as well log any errors anywhere else in Django
        'django': {
            'handlers': ['logfile'],
            'level': 'ERROR',
            'propagate': False,
        },
        # Your own app - this assumes all your logger names start with "myapp."
        'myapp': {
            'handlers': ['logfile'],
            'level': 'WARNING', # Or maybe INFO or DEBUG
            'propagate': False
        },
    },
}
'''


def soma(numero1, numero2):
    return float(numero1) + float(numero2)

def subtracao(numero1, numero2):
    return float(numero1) - float(numero2)

def divisao(numero1, numero2):
    if (numero2 == "0"):
        global repetir
        repetir = True
        return "O número 2 não pode ser 0"
    else:
        return float(numero1) / float(numero2)

def multiplicacao(numero1, numero2):
    return float(numero1) * float(numero2)

def calculadora(n1, n2, op):

    if (op == "+"):
        print(soma(n1, n2))
    elif (op == "-"):
        print(subtracao(n1, n2))
    elif (op == "/"):
        print(divisao(n1, n2))
    elif (op == "*"):
        print(multiplicacao(n1, n2))
    else:
        print("O usuário digitou uma operação inválida")
        global repetir
        repetir = True

repetir = True

while (repetir == True):

    num1 = input("Escreva o número 1: ")

    if (num1.isnumeric()):
        num2 = input("Escreva o número 2: ")
        if (num2.isnumeric()):
            repetir = False
            operador = input("Escreva o operador (+,-,/,*)")
            calculadora(num1, num2, operador)
        else:
            print("O número 2 é inválido. Tente novamente!")

    else:
        print("O número 1 é inválido. Tente novamente!")

Programador de Sistemas - UC 1/Repositório de Exemplos/Revisão Funções/calculadora.py


## Real time video from webcamera

import numpy as np
import cv2

fps = 30

def getImage():
    cv2.namedWindow("webcam-feed")
    cam = cv2.VideoCapture(0)

    if cam.isOpened(): # try to get the first frame
        ret, frame = cam.read()
    else:
        ret = False
    frames = 1;
    img_counter = 0
    while ret:
        cv2.imshow("webcam-feed", frame)
        ret, frame = cam.read()
        frames+=1
        ## ==============
        ## what is waitkey
        ## ===============
        key = cv2.waitKey(20) # milliseconds
        if frames%30 == 0:
            print("Time: {} secs \r".format(int(frames/fps)),end="")
        if key==27 : # ESC pressed
            print("\nEscape hit, closing...")
            break

        if key == 32:  # SPACE pressed
            img_name = "opencv_frame_{}.png".format(img_counter)
            cv2.imwrite(img_name, frame)
            print("{} written!".format(img_name))
            img_counter += 1
    cam.release()
    cv2.destroyAllWindows()
    cv2.destroyWindow("webcam-feed")

getImage()


from sys import stdin

def A():
    t = stdin.readline()
    t = int(t)

    while (t):
        t-= 1
        n = int(stdin.readline())
        a = [int(x) for x in stdin.readline().split()]
        a.sort()
        b = [0] * len(a)
        l = 0

        for i in range(0, len(a) // 2):
            b[l] = a[i]
            l += 2
        l = 1
        for i in range(len(a)//2 , len(a)):
            b[l] = a[i]
            l += 2
        for i in b:
            print(i, end=" ")
        print()

def B():
    t = stdin.readline()
    t = int(t)

    while (t):
        t -= 1
        n = int(stdin.readline())
        if n % 11 == 0:
            print("YES")
        else:
            a = n % 11
            if  n - a * 111 >= 0:
                print("YES")
            else:
                print("NO")
def C():
    t = stdin.readline()
    t = int(t)

    a = [int(x) for x in stdin.readline().split()]
    arr = [[0 for _ in range(2001)] for _ in range(2001)]
    arr1 = [[0 for _ in range(2001)] for _ in range(2001)]
    res = 0
    res_posi = 0
    for i in range(0, len(a)):
        arr[0][i] = a[i]
    for i in range(1, len(a)):
        for j in range(0, len(a)):
            if arr[i-1][j-1] + a[j] >= 0:
                arr1[i][j] = arr1[i][j-1] + 1
                arr[i][j] = arr[i-1][j-1] + a[j]

    print(a)
    print(res)

C()


import os
import sys
from glob import glob
import matplotlib.pyplot as plt
from scipy.misc import imread, imresize
from scipy.io import loadmat
import numpy as np

def collect_data(volume_path):
    ipath = os.path.join(volume_path)
    isearch = os.path.join(ipath, 'small_images', '*.jpg')
    print("Searching for images in path: %s" %isearch)
    images = glob(isearch)

    dsearch = os.path.join(volume_path, 'depthmaps', '*.mat')
    print("Searching for depthmaps in path: %s" %dsearch)
    dmaps = glob(dsearch)

    if not len(dmaps):
        print("ERROR: Could not find any depthmaps")
        raise
    if not len(images):
        print("ERROR: Could not find any images")
        raise
    inames = [os.path.split(xx)[1] for xx in images]
    dnames = [os.path.split(xx)[1] for xx in dmaps]
    depn_exp = [ii.replace('img', 'depth').replace('.jpg', '.mat') for ii in inames]
    depn_exp = []

    iout = []
    dout = []

    for xx,ii in enumerate(inames):
        de = ii.replace('img', 'depth').replace('.jpg', '.mat')
        if de in dnames:
            fxx = dnames.index(de)
            iout.append(images[xx])
            dout.append(dmaps[fxx])
    print("FOUND %s matching images and depths" %len(iout))
    return sorted(iout), sorted(dout)

def load_data(images, dmaps):
    # input data - create empty dimensions because
    # conv nets take in 4d arrays [b,c,0,1]
    # seems to need even number of pixels
    # seems to need even number of pixels
    numi = len(images)
    ifiles = []
    dfiles = []
    print("loading %s images and depthmaps" %numi)
    for xx in range(numi):
        imgf = imread(images[xx])
        depf = loadmat(dmaps[xx])['depthMap']
        # if you want to resize the depth to be the same as the image
        depf = imresize(depf, imgf.shape[:2])
        imgf = imgf.transpose(2,0,1)
        ifiles.append(imgf)
        dfiles.append(depf)

    # normalize
    X = np.asarray(ifiles).astype('float32')/255.
    y = np.asarray(dfiles).astype('float32')/255.
    y = np.log(y+1)
    y = y[:,None,:,:]
    return X, y

def plot_est(imgf, depp):
    fig = plt.figure(frameon=False, figsize=(2,2))
    ni = 2
    ax1 = fig.add_subplot(1,ni,1)
    a1 = ax1.imshow(imgf)
    plt.title("Image")
    ax2 = fig.add_subplot(1,ni,2)
    a2 = ax2.imshow(depp)
    plt.title("Estimated Depth")
    ax1.axes.xaxis.set_ticklabels([])
    ax1.axes.yaxis.set_ticklabels([])
    ax2.axes.xaxis.set_ticklabels([])
    ax2.axes.yaxis.set_ticklabels([])
    plt.show()

def plot_img_dep(imgf, depf, depp, depdif, titl):
    # row and column sharing
    fig = plt.figure(frameon=False, figsize=(12,8))
    ni = 4
    ax1 = fig.add_subplot(1,ni,1)
    a1 = ax1.imshow(imgf)
    plt.title("Image")
    ax2 = fig.add_subplot(1,ni,2)
    a2 = ax2.imshow(depf)
    plt.title("Ground Truth Depth")
    ax3 = fig.add_subplot(1,ni,3)
    a3 = ax3.imshow(depp)
    plt.title("Estimated Depth")
    ax4 = fig.add_subplot(1,ni,4)
    a4 = ax4.imshow(depdif, vmin=0,vmax=5)
    plt.title("Depth Difference")
    ax1.axes.xaxis.set_ticklabels([])
    ax1.axes.yaxis.set_ticklabels([])
    ax2.axes.xaxis.set_ticklabels([])
    ax2.axes.yaxis.set_ticklabels([])
    ax3.axes.xaxis.set_ticklabels([])
    ax3.axes.yaxis.set_ticklabels([])
    ax4.axes.xaxis.set_ticklabels([])
    ax4.axes.yaxis.set_ticklabels([])
    plt.show()

def rmse(arr1,arr2):
    # expect shapes to be equal
    err = np.sum((arr1-arr2)**2)
    err /= float(arr1.shape[0]*arr1.shape[1])
    return np.sqrt(err)

def norm(arr):
    # expects numpy array
    # normalize between 0 and 1
    return (arr-arr.min())/(arr.max()-arr.min())


""""
A basic representation of a 1D dataset
"""
from __future__ import division

import os.path
import re

import numpy as np

from refnx.util.nsplice import get_scaling_in_overlap

class Data1D(object):
    r"""
    A basic representation of a 1D dataset.

    Parameters
    ----------
    data : str, file-like or tuple of np.ndarray, optional
        `data` can be a string or file-like object referring to a File to load
        the dataset from.

        Alternatively it is a tuple containing the data from which the dataset
        will be constructed. The tuple should have between 2 and 4 members.

            - data[0] - x
            - data[1] - y
            - data[2] - uncertainties on y, y_err
            - data[3] - uncertainties of x, x_err

        `data` must be at least two long, `x` and `y`.
        If the tuple is at least 3 long then the third member is `y_err`.
        If the tuple is 4 long then the fourth member is `x_err`.
        All arrays must have the same shape.

    Attributes
    ----------
    data : tuple of np.ndarray
        The data, (x, y, y_err, x_err)
    finite_data : tuple of np.ndarray
        Data points that are finite
    x : np.ndarray
        x data
    y : np.ndarray
        y data
    y_err : np.ndarray
        uncertainties on the y data
    x_err : np.ndarray
        uncertainties on the x data
    filename : str or None
        The file the data was read from
    weighted : bool
        Whether the y data has uncertainties
    metadata : dict
        Information that should be retained with the dataset.
    """
    def __init__(self, data=None, **kwds):
        self.filename = None

        self.metadata = kwds
        self.x = np.zeros(0)
        self.y = np.zeros(0)
        self.y_err = np.zeros(0)
        self.x_err = np.zeros(0)
        self.weighted = False

        # if it's a file then open and load the file.
        if hasattr(data, 'read') or type(data) is str:
            self.load(data)
        elif data is not None:
            self.x = np.array(data[0], dtype=float)
            self.y = np.array(data[1], dtype=float)
            if len(data) > 2:
                self.y_err = np.array(data[2], dtype=float)
                self.weighted = True
            else:
                self.y_err = np.ones_like(self.y, dtype=float)

            if len(data) > 3:
                self.x_err = np.array(data[3], dtype=float)
            else:
                self.x_err = np.zeros_like(self.x, dtype=float)

    def __len__(self):
        """
        the number of points in the dataset.
        """
        return self.y.size

    @property
    def data(self):
        """
        4-tuple containing the (x, y, y_err, x_err) data
        """
        return self.x, self.y, self.y_err, self.x_err

    @property
    def finite_data(self):
        """
        4-tuple containing the (x, y, y_err, x_err) datapoints that are
        finite.
        """
        finite_loc = np.where(np.isfinite(self.y))
        return (self.x[finite_loc],
                self.y[finite_loc],
                self.y_err[finite_loc],
                self.x_err[finite_loc])

    @data.setter
    def data(self, data_tuple):
        """
        Set the data for this object from supplied data.

        Parameters
        ----------
        data_tuple : tuple
            2 to 4 member tuple containing the (x, y, y_err, x_err) data to
            specify the dataset. `y_err` and `x_err` are optional.
        """
        self.x = np.array(data_tuple[0], dtype=float)
        self.y = np.array(data_tuple[1], dtype=float)
        self.weighted = False
        if len(data_tuple) > 2:
            self.y_err = np.array(data_tuple[2], dtype=float)
            self.weighted = True
        else:
            self.y_err = np.ones_like(self.y, dtype=float)

        if len(data_tuple) > 3:
            self.x_err = np.array(data_tuple[3], dtype=float)
        else:
            self.x_err = np.zeros_like(self.x, dtype=float)
        self.sort()

    def scale(self, scalefactor=1.):
        """
        Scales the y and y_err data by dividing by `scalefactor`.

        Parameters
        ----------
        scalefactor : float
            The scalefactor to divide by.
        """
        self.y /= scalefactor
        self.y_err /= scalefactor

    def add_data(self, data_tuple, requires_splice=False, trim_trailing=True):
        """
        Adds more data to the dataset

        Parameters
        ----------
        data_tuple : tuple
            2 to 4 member tuple containing the (x, y, y_err, x_err) data to add
            to the dataset. `y_err` and `x_err` are optional.
        requires_splice : bool, optional
            When the new data is added to the dataset do you want to scale it
            vertically so that it overlaps with the existing data? `y` and
            `y_err` in `data_tuple` are both multiplied by the scaling factor.
        trim_trailing : bool, optional
            When the new data is concatenated do you want to remove points from
            the existing data that are in the overlap region? This might be
            done because the datapoints in the `data_tuple` you are adding have
            have lower `y_err` than the preceding data.
        """
        xdata, ydata, ydata_sd, xdata_sd = self.data

        axdata, aydata = data_tuple[0:2]

        if len(data_tuple) > 2:
            aydata_sd = np.array(data_tuple[2], dtype=float)
        else:
            aydata_sd = np.ones_like(aydata)
            self.weighted = False

        if len(data_tuple) > 3:
            axdata_sd = np.array(data_tuple[3], dtype=float)
        else:
            axdata_sd = np.zeros(np.size(axdata))

        qq = np.r_[xdata]
        rr = np.r_[ydata]
        dr = np.r_[ydata_sd]
        dq = np.r_[xdata_sd]

        # which values in the first dataset overlap with the second
        overlap_points = np.zeros_like(qq, 'bool')

        # go through and stitch them together.
        scale = 1.
        dscale = 0.
        if requires_splice and len(self) > 1:
            scale, dscale, overlap_points = (
                get_scaling_in_overlap(qq,
                                       rr,
                                       dr,
                                       axdata,
                                       aydata,
                                       aydata_sd))
        if not trim_trailing:
            overlap_points[:] = False

        qq = np.r_[qq[~overlap_points], axdata]
        dq = np.r_[dq[~overlap_points], axdata_sd]

        rr = np.r_[rr[~overlap_points], aydata * scale]
        dr = np.r_[dr[~overlap_points], aydata_sd * scale]

        self.data = (qq, rr, dr, dq)
        self.sort()

    def sort(self):
        """
        Sorts the data in ascending order
        """
        sorted = np.argsort(self.x)
        self.x = self.x[sorted]
        self.y = self.y[sorted]
        self.y_err = self.y_err[sorted]
        self.x_err = self.x_err[sorted]

    def save(self, f):
        """
        Saves the data to file. Saves the data as 4 column ASCII.

        Parameters
        ----------
        f : file-handle or string
            File to save the dataset to.
        """
        np.savetxt(
            f, np.column_stack((self.x,
                                self.y,
                                self.y_err,
                                self.x_err)))

    def load(self, f):
        """
        Loads a dataset from file. Must be 2 to 4 column ASCII.

        Parameters
        ----------
        f : file-handle or string
            File to load the dataset from.
        """
        # see if there are header rows
        close_file = False
        try:
            g = open(f, 'rb')
            close_file = True
        except TypeError:
            # if you're already a file then you'll get a type error
            g = f
        finally:
            header_lines = 0
            for i, line in enumerate(g):
                try:
                    nums = [float(tok) for tok in
                            re.split('\s|,', line.decode('utf-8'))
                            if len(tok)]
                    if len(nums) >= 2:
                        header_lines = i
                        break
                except ValueError:
                    continue
            if close_file:
                g.close()

        self.data = np.loadtxt(f, unpack=True, skiprows=header_lines)

        if hasattr(f, 'read'):
            fname = f.name
        else:
            fname = f

        self.filename = fname
        self.name = os.path.splitext(os.path.basename(fname))[0]

    def refresh(self):
        """
        Refreshes a previously loaded dataset.
        """
        if self.filename is not None:
            with open(self.filename) as f:
                self.load(f)

    def __add__(self, other):
        """
        Adds two datasets together. Splices the data and trims data in the
        overlap region.
        """
        ret = Data1D(self.data)
        ret.add_data(other.data, requires_splice=True, trim_trailing=True)
        return ret

    def __radd__(self, other):
        """
        radd of two datasets. Splices the data and trims data in the
        overlap region.
        """
        self.add_data(other.data, requires_splice=True, trim_trailing=True)
        return self

    def __iadd__(self, other):
        """
        iadd of two datasets. Splices the data and trims data in the
        overlap region.
        """
        self.add_data(other.data, requires_splice=True, trim_trailing=True)
        return self


class Interval(object):
    def __init__(self, s=0, e=0):
        self.start = s
        self.end = s

class INode(object):
    def __init__(self, interval):
        self.i = interval
        self.max = interval.end
        self.left = self.right = None

def insert(node, interval):
    if not node:
        return INode(interval)

    item = node.i
    if item.start < interval.start:
        node.left = insert(node.left, interval)
    else:
        node.right = insert(node.right, interval)

    if item.max < interval.end:
        item.max = interval.end
    return node


import codecademylib3_seaborn
from matplotlib import pyplot as plt
import pandas as pd
import seaborn as sns

#importing data from the csv file
df = pd.read_csv('WorldCupMatches.csv')
df_goals = pd.read_csv('goals.csv')

#Adding up the total goals from each World Cup
df["Total Goals"]= df['Home Team Goals'] + df['Away Team Goals']

#Plotting the goals onto a bar chart
sns.set_style("whitegrid")
sns.set_context("notebook", font_scale=1.25)
f, ax = plt.subplots(figsize=(12, 7))
ax = sns.barplot(x=df["Year"], y=df["Total Goals"])
ax.set_title("Average Goals Scored in World Cup Matches By Year")
plt.show()

#Plotting the distribution of goals
f, ax2 = plt.subplots(figsize=(12, 7))
ax2 = sns.boxplot(x= 'year', y= 'goals', data=df_goals, palette='Spectral')
ax2.set_title('Distribution of Goals')
plt.show()

print(df_goals.head())
print(df.head())


import sys
from collections import deque
input = sys.stdin.readline

def make_board(m, n, k):
    board = list(list([0] * n) for _ in range(m))
    for _ in range(k):
        x_1, y_1, x_2, y_2 = map(int, input().split())
        for x in range(x_1, x_2):
            for y in range(y_1, y_2):
                board[y][x] = 1
    return board

def bfs(m, n, board):
    q = deque()
    d = [(-1, 0), (1, 0), (0, -1), (0, 1)]
    area = list()

    for i in range(m):
        for j in range(n):
            if not board[i][j]:
                board[i][j] = 1
                q.append((i, j))
                area.append(1)
                while q:
                    x, y = q.popleft()
                    for dx, dy in d:
                        nx = x + dx
                        ny = y + dy
                        if 0 <= nx < m and 0 <= ny < n and not board[nx][ny]:
                            q.append((nx, ny))
                            board[nx][ny] = 1
                            area[-1] += 1
    return sorted(area)

def solution():
    m, n, k = map(int, input().split())
    board = make_board(m, n, k)
    area = bfs(m, n, board)

    print(len(area))
    print(*area)

solution()