<commit_before>'''rw - IO tools for PLUMED files and related data'''

from collections import OrderedDict
import glob
import itertools
from os.path import join
import re
import subprocess
import sys
import tempfile
from typing import (Any, Sequence, List, Tuple, Iterator, Mapping,
                    Dict, Union, Optional)

import numpy as np
import pandas as pd

__all__ = ['is_plumed', 'is_same_shape', 'read_plumed_fields',
           'read_rdc', 'read_nmr', 'read_plumed', 'read_multi',
           'read_all_hills', 'plumed_iterator', 'file_length',
           'field_glob', 'fields_to_columns', 'sum_hills']

def is_plumed(file: str) -> bool:
    '''
    Checks if the file is of plumed format.

    Parameters
    ----------
    file : Path to plumed file.

    Returns
    -------
    is_plumed : Returns true if file is valid plumed format,
        raises ValueError otherwise.

    '''
    with open(file, 'r') as f:
        head = f.readlines(0)[0]
        if head.startswith('#!'):
            return True
        else:
            raise ValueError('Not a valid plumed file')

def is_same_shape(data: List[np.ndarray]) -> bool:
    '''
    Checks if a list of ndarrays all have the same shape.

    Parameters
    ----------
    data : List of arrays

    Returns
    -------
    is_same_shape : True if same shape, False if not

    '''
    return len(set(d.shape for d in data)) == 1

def read_plumed_fields(file: str) -> List[str]:
    '''
    Reads the fields specified in the plumed file.

    Parameters
    ----------
    file : Path to plumed file.

    Returns
    -------
    fields : List of field names.

    '''
    is_plumed(file)
    with open(file, 'br') as f:
        head = f.readlines(0)[0].split()[2:]
        fields = [x.decode('utf-8') for x in head]
    return fields

def plumed_iterator(file: str) -> Iterator[List[float]]:
    '''
    Creates an iterator over a plumed file.

    Parameters
    ----------
    file : Path to plumed file.

    Yields
    ------
    iter : List of floats for each line read.

    '''
    is_plumed(file)
    with open(file, 'r') as f:
        for line in f:
            if line.startswith('#'):
                continue
            yield [float(n) for n in line.split()]

def file_length(file: str, skip_comments: bool=False) -> int:
    '''
    Counts number of lines in file.

    Parameters
    ----------
    file : Path to file.
    skip_comments : Skipping comments is slightly slower,
        because we have to check each line.

    Returns
    -------
    length : Length of the file.

    '''
    with open(file, 'r') as f:
        i = -1
        if skip_comments:
            for line in f:
                if line.startswith('#'):
                    continue
                i += 1
        else:
            for i, _ in enumerate(f):
                pass
    return i + 1

def read_plumed(
    file: str,
    columns: Union[Sequence[int], Sequence[str], str, None]=None,
    step: int=1,
    start: int=0,
    stop: int=sys.maxsize,
    replicas: bool=False,
    high_mem: bool=True,
    dataframe: bool=True,
    raise_error: bool=False,
    drop_nan: bool=True
) -> Union[pd.DataFrame, Tuple[List[str], np.ndarray]]:
    '''
    Read a plumed file and return its contents as a 2D ndarray.

    Parameters
    ----------
    file : Path to plumed file.
    columns : Column numbers or field names to read from file.
    step : Stepsize to use. Will skip every [step] rows.
    start : Starting point in lines from beginning of file,
        including commented lines.
    stop : Stopping point in lines from beginning of file,
        including commented lines.
    replicas : Enable chunked reading (multiple datapoints per timestep).
    high_mem : Use high memory version, which might be faster.
        Reads in the whole array and then slices it.
    dataframe : Return as pandas dataframe.
    raise_error : Raise error in case of length mismatch.
    drop_nan : Drop missing values.

    Returns
    -------
    fields : List of field names.
    data : 2D numpy ndarray with the contents from file.

    '''
    is_plumed(file)
    length = file_length(file)
    if stop != sys.maxsize and length < stop and raise_error:
        raise ValueError('Value for [stop] is larger than number of lines')

    full_fields = read_plumed_fields(file)
    if columns is not None and not isinstance(columns[0], int):
        columns = field_glob(columns, full_fields)
    fields, columns = fields_to_columns(columns, full_fields)

    full_array = (step == 1 and start == 0 and
                  stop == sys.maxsize and columns is None)

    if full_array or high_mem:
        nrows = stop - start if stop != sys.maxsize else None

        df = pd.read_csv(
            file,
            sep='\s+',
            header=None,
            comment='#',
            names=full_fields,
            dtype=np.float64,
            skiprows=start,
            nrows=nrows,
            usecols=columns,
        )

        # If several replicas write to the same file, we shouldn't use
        # the normal step, since we would only be reading a subset of
        # the replica data (worst case only one!). So we read in chunks
        # the size of the number of replicas.
        if replicas:
            dfgs = []
            for i, (_, dfg) in enumerate(df.groupby('time')):
                if i % step == 0:
                    dfgs.append(dfg)
            data = pd.concat(dfgs)
        else:
            data = df[::step]

        if drop_nan:
            data.dropna(axis=0)

        if not dataframe:
            data = data.values

    else:
        with open(file, 'br') as f:
            data = np.genfromtxt(itertools.islice(f, start, stop, step),
                                 skip_header=1, invalid_raise=False,
                                 usecols=columns)
        if dataframe:
            data = pd.DataFrame(OrderedDict(zip(fields, data.T)))

    if not dataframe:
        return fields, data
    else:
        return data

def read_multi(
    files: Union[Sequence[str], str],
    **kwargs: Optional[Mapping[str, Any]]
) -> pd.DataFrame:
    '''
    Read multiple Plumed files and return as concatenated dataframe.

    Parameters
    ----------
    files : Sequence of (globbed) files to be read.
    kwargs : Arguments passed to read_plumed().

    Returns
    -------
    df : Dataframe with concatenated data.

    '''

    if isinstance(files, str):
        files = [files]

    # Sanity check
    kwargs.pop('dataframe', {'': ''})

    filelist = []  # type: List[str]
    for file in files:
        if any(char in file for char in '*?[]'):
            filelist.extend(glob.iglob(file))
        else:
            filelist.append(file)

    dflist = []  # type: List[str]
    for i, file in enumerate(filelist):
        df = read_plumed(file, **kwargs)
        dflist.append(df.rename(columns={
            k: '{0}_{1}'.format(i, k) for k in df.columns if 'time' not in k
        }))

    return pd.concat(dflist, axis=1)

def field_glob(
    fields: Union[str, Sequence[str]],
    full_fields: Sequence[str]
) -> List[str]:
    '''
    Gets a list of matching fields from valid regular expressions.

    Parameters
    ----------
    fields : Regular expression(s) to be used to find matches.
    full_fields : Full list of fields to match from.

    Returns
    -------
    matches : List of matching fields.

    '''

    if isinstance(fields, str):
        fields = [fields]

    globbed = set()
    for field in fields:
        if field in full_fields:
            globbed.add(field)

        for f_target in full_fields:
            if re.search(field, f_target):
                globbed.add(f_target)

    return list(globbed)

def fields_to_columns(
    fields: Union[Sequence[str], Sequence[int]],
    full_fields: Sequence[str]
) -> Tuple[Tuple[str, ...], Tuple[int, ...]]:
    '''
    Transforms a sequence of field names to their respective column indices.

    Parameters
    ----------
    fields : Sequence of field names or columns numbers
    full_fields : The full list of field names as
        created by read_plumed_fields().

    Returns
    -------
    columns : Column indices, None if fields is none.

    '''
    if fields is None:
        return tuple(full_fields), None

    elif type(fields[0]) == int:
        return tuple(full_fields[i] for i in fields), tuple(fields)

    else:
        return tuple(fields), tuple(full_fields.index(s)
                                    for s in fields if s in full_fields)

def read_all_hills(files: Union[Sequence[str], str],
                   colvar: bool=False,
                   step: int=1) -> pd.DataFrame:
    '''
    Read CV information from HILLS files.

    Parameters
    ----------
    files : List of filenames or glob pattern to read from.
    step : Stepsize to use while reading.
    Returns
    -------
    timedata : Dataframe with time as first column and CV data for the rest.

    '''
    if isinstance(files, str):
        files = [files]

    # Prepare list from globbed strings
    filelist = []  # type: List[str]
    for file in files:
        if any(char in file for char in '*?[]'):
            filelist.extend(glob.iglob(file))
        else:
            filelist.append(file)

    if colvar:
        raw = []
        for file in sorted(filelist):
            raw.append(read_plumed(file, step=step))

        return (pd.concat(raw)
                  .sort_values('time')
                  .dropna(axis=0)
                  .sort_index()
                  .drop('pb.bias', axis=1))

    else:
        # Read the time column first
        length = file_length(filelist[0]) - 1
        timedata = read_plumed(filelist[0], step=step, stop=length,
                               replicas=True, columns=(0,), dataframe=True)

        # Append all other columns
        for file in sorted(filelist):
            data = read_plumed(file, step=step, stop=length,
                               replicas=True, dataframe=True)
            timedata = pd.concat(
                [timedata, pd.DataFrame(data.iloc[:, 1])], axis=1
            )
        return timedata.dropna(axis=0).sort_index()

def sum_hills(files: Union[Sequence[str], str],
              nbins: int=50, plumed: str='plumed') -> pd.DataFrame:
    '''
    Calculate the free-energy using plumed sum_hills.

    Parameters
    ----------
    files : Hills files to be passed to PLUMED, globbing allowed.
    nbins : Number of bins to use for histogramming.
    plumed : Path to the PLUMED executable.

    Returns
    -------
    summed_hills : Dataframe containing binned data for each hills file.

    '''

    if isinstance(files, str):
        files = [files]

    # Prepare list from globbed strings
    filelist = []  # type: List[str]
    for file in files:
        if any(char in file for char in '*?[]'):
            filelist.extend(glob.iglob(file))
        else:
            filelist.append(file)

    # Run sum_hills first
    raw = {}
    with tempfile.TemporaryDirectory() as tmp:
        for hf in sorted(filelist):
            filename = hf.split('/')[-1]
            output = join(tmp, filename)
            cmd = '{0} sum_hills --hills {1} --bin {2} --outfile {3}'.format(
                plumed, hf, nbins, output
            ).split()
            subprocess.run(cmd, check=True)
            raw[filename] = read_plumed(output)['file.free']

    return pd.DataFrame(raw)

def read_rdc(files: Sequence[str]) -> Dict[str, float]:
    '''
    Reads files generated by an RDC program.

    Parameters
    ----------
    files : Paths to files to be read.

    Returns
    -------
    rdcs : Dictionary containing the RDC name
        as keys and the calculated value.

    '''
    rdcs = {}

    # Open dat files and parse
    for file in files:
        with open(file, 'r') as f:
            for line in f.readlines():

                if line.startswith('#'):
                    continue
                data = line.split()
                res_nr, rdc_type, val = int(data[0]), data[3], float(data[4])

                # Translate to our key style
                if rdc_type == 'HN':
                    rdc_type = 'nh'
                elif rdc_type == 'C':
                    rdc_type = 'cac'
                elif rdc_type == 'HA':
                    rdc_type = 'caha'
                else:
                    raise ValueError('Invalid RDC type!')

                rdcs['{0}.rdc{1}'.format(rdc_type, res_nr)] = val
    return rdcs

def read_nmr(
        weights: np.ndarray,
        directory: str,
        nfiles: int,
        skip: int,
        nres: int
) -> Dict[str, float]:
    '''
    Read chemical shifts from an external program.

    Parameters
    ----------
    weights : Array of weights.
    directory : Directory conatining the pred.tab files.
    nfiles : Number of pred.tab files.
    skip : Number of frames to skip when extracting PDB frames.
    nres : Number of residues of the system.

    Returns
    -------
    cs : Dictionary containing the chemical shift names
        as keys and the calculated values.

    '''

    # Prepare input files
    spfiles = [directory + '/traj{0}_pred.tab'.format(i)
               for i in range(nfiles)]
    posatoms = ['nh', 'hn', 'ha', 'ca', 'cb', 'co']

    # Check input
    if len(spfiles) != len(weights):
        raise ValueError(
                'Number of SPARTA+ files must be the same '
                'as the length of the weight array!'
        )

    # Iterate over files
    shifts = {}  # type: Dict[str, float]
    for i, file in enumerate(spfiles):
        with open(file, 'r') as sf:

            # Only use lines starting with digits
            for line in sf.readlines():

                if re.match(r'^\s*\d+', line):
                    tmpline = re.split(r'\s+', line)
                    residue = int(tmpline[1])
                    atoms = tmpline[3].lower()
                    shift = float(tmpline[5])

                    # Skip first and last residues
                    if residue == nres or residue == 1:
                        continue

                    # Use proper Camshift naming convention
                    if atoms == 'n':
                        atoms = 'nh'
                    elif atoms == 'c':
                        atoms = 'co'
                    elif atoms not in posatoms:
                        continue

                    # Add weighted shift to dict
                    key = 'cs.{0}_{1}'.format(atoms, residue - 1)
                    if key in shifts:
                        shifts[key] += shift * weights[i]
                    else:
                        shifts[key] = shift * weights[i]
    return shifts
<commit_msg>made it more pythonic<commit_after>'''rw - IO tools for PLUMED files and related data'''

from collections import OrderedDict
import glob
import itertools
from os.path import join
import re
import subprocess
import sys
import tempfile
from typing import (Any, Sequence, List, Tuple, Iterator, Mapping,
                    Dict, Union, Optional)

import numpy as np
import pandas as pd

__all__ = ['is_plumed', 'is_same_shape', 'read_plumed_fields',
           'read_rdc', 'read_nmr', 'read_plumed', 'read_multi',
           'read_all_hills', 'plumed_iterator', 'file_length',
           'field_glob', 'fields_to_columns', 'sum_hills']

def is_plumed(file: str) -> bool:
    '''
    Checks if the file is of plumed format.

    Parameters
    ----------
    file : Path to plumed file.

    Returns
    -------
    is_plumed : Returns true if file is valid plumed format,
        raises ValueError otherwise.

    '''
    with open(file, 'r') as f:
        head = f.readlines(0)[0]
        if head.startswith('#!'):
            return True
        else:
            raise ValueError('Not a valid plumed file')

def is_same_shape(data: List[np.ndarray]) -> bool:
    '''
    Checks if a list of ndarrays all have the same shape.

    Parameters
    ----------
    data : List of arrays

    Returns
    -------
    is_same_shape : True if same shape, False if not

    '''
    return len(set(d.shape for d in data)) == 1

def read_plumed_fields(file: str) -> List[str]:
    '''
    Reads the fields specified in the plumed file.

    Parameters
    ----------
    file : Path to plumed file.

    Returns
    -------
    fields : List of field names.

    '''
    is_plumed(file)
    with open(file, 'br') as f:
        head = f.readlines(0)[0].split()[2:]
        fields = [x.decode('utf-8') for x in head]
    return fields

def plumed_iterator(file: str) -> Iterator[List[float]]:
    '''
    Creates an iterator over a plumed file.

    Parameters
    ----------
    file : Path to plumed file.

    Yields
    ------
    iter : List of floats for each line read.

    '''
    is_plumed(file)
    with open(file, 'r') as f:
        for line in f:
            if line.startswith('#'):
                continue
            yield [float(n) for n in line.split()]

def file_length(file: str, skip_comments: bool=False) -> int:
    '''
    Counts number of lines in file.

    Parameters
    ----------
    file : Path to file.
    skip_comments : Skipping comments is slightly slower,
        because we have to check each line.

    Returns
    -------
    length : Length of the file.

    '''
    with open(file, 'r') as f:
        i = -1
        if skip_comments:
            for line in f:
                if line.startswith('#'):
                    continue
                i += 1
        else:
            for i, _ in enumerate(f):
                pass
    return i + 1

def read_plumed(
    file: str,
    columns: Union[Sequence[int], Sequence[str], str, None]=None,
    step: int=1,
    start: int=0,
    stop: int=sys.maxsize,
    replicas: bool=False,
    high_mem: bool=True,
    dataframe: bool=True,
    raise_error: bool=False,
    drop_nan: bool=True
) -> Union[pd.DataFrame, Tuple[List[str], np.ndarray]]:
    '''
    Read a plumed file and return its contents as a 2D ndarray.

    Parameters
    ----------
    file : Path to plumed file.
    columns : Column numbers or field names to read from file.
    step : Stepsize to use. Will skip every [step] rows.
    start : Starting point in lines from beginning of file,
        including commented lines.
    stop : Stopping point in lines from beginning of file,
        including commented lines.
    replicas : Enable chunked reading (multiple datapoints per timestep).
    high_mem : Use high memory version, which might be faster.
        Reads in the whole array and then slices it.
    dataframe : Return as pandas dataframe.
    raise_error : Raise error in case of length mismatch.
    drop_nan : Drop missing values.

    Returns
    -------
    fields : List of field names.
    data : 2D numpy ndarray with the contents from file.

    '''
    is_plumed(file)
    length = file_length(file)
    if stop != sys.maxsize and length < stop and raise_error:
        raise ValueError('Value for [stop] is larger than number of lines')

    full_fields = read_plumed_fields(file)
    if columns is not None and not isinstance(columns[0], int):
        columns = field_glob(columns, full_fields)
    fields, columns = fields_to_columns(columns, full_fields)

    full_array = (step == 1 and start == 0 and
                  stop == sys.maxsize and columns is None)

    if full_array or high_mem:
        nrows = stop - start if stop != sys.maxsize else None

        df = pd.read_csv(
            file,
            sep='\s+',
            header=None,
            comment='#',
            names=full_fields,
            dtype=np.float64,
            skiprows=start,
            nrows=nrows,
            usecols=columns,
        )

        # If several replicas write to the same file, we shouldn't use
        # the normal step, since we would only be reading a subset of
        # the replica data (worst case only one!). So we read in chunks
        # the size of the number of replicas.
        if replicas:
            data = pd.concat([
                dfg for i, (_, dfg) in enumerate(df.groupby('time'))
                if i % step == 0
            ])
        else:
            data = df[::step]

        if drop_nan:
            data.dropna(axis=0)

        if not dataframe:
            data = data.values

    else:
        with open(file, 'br') as f:
            data = np.genfromtxt(itertools.islice(f, start, stop, step),
                                 skip_header=1, invalid_raise=False,
                                 usecols=columns)
        if dataframe:
            data = pd.DataFrame(OrderedDict(zip(fields, data.T)))

    if not dataframe:
        return fields, data
    else:
        return data

def read_multi(
    files: Union[Sequence[str], str],
    **kwargs: Optional[Mapping[str, Any]]
) -> pd.DataFrame:
    '''
    Read multiple Plumed files and return as concatenated dataframe.

    Parameters
    ----------
    files : Sequence of (globbed) files to be read.
    kwargs : Arguments passed to read_plumed().

    Returns
    -------
    df : Dataframe with concatenated data.

    '''

    if isinstance(files, str):
        files = [files]

    # Sanity check
    kwargs.pop('dataframe', {'': ''})

    filelist = []  # type: List[str]
    for file in files:
        if any(char in file for char in '*?[]'):
            filelist.extend(glob.iglob(file))
        else:
            filelist.append(file)

    dflist = []  # type: List[str]
    for i, file in enumerate(filelist):
        df = read_plumed(file, **kwargs)
        dflist.append(df.rename(columns={
            k: '{0}_{1}'.format(i, k) for k in df.columns if 'time' not in k
        }))

    return pd.concat(dflist, axis=1)

def field_glob(
    fields: Union[str, Sequence[str]],
    full_fields: Sequence[str]
) -> List[str]:
    '''
    Gets a list of matching fields from valid regular expressions.

    Parameters
    ----------
    fields : Regular expression(s) to be used to find matches.
    full_fields : Full list of fields to match from.

    Returns
    -------
    matches : List of matching fields.

    '''

    if isinstance(fields, str):
        fields = [fields]

    globbed = set()
    for field in fields:
        if field in full_fields:
            globbed.add(field)

        for f_target in full_fields:
            if re.search(field, f_target):
                globbed.add(f_target)

    return list(globbed)

def fields_to_columns(
    fields: Union[Sequence[str], Sequence[int]],
    full_fields: Sequence[str]
) -> Tuple[Tuple[str, ...], Tuple[int, ...]]:
    '''
    Transforms a sequence of field names to their respective column indices.

    Parameters
    ----------
    fields : Sequence of field names or columns numbers
    full_fields : The full list of field names as
        created by read_plumed_fields().

    Returns
    -------
    columns : Column indices, None if fields is none.

    '''
    if fields is None:
        return tuple(full_fields), None

    elif type(fields[0]) == int:
        return tuple(full_fields[i] for i in fields), tuple(fields)

    else:
        return tuple(fields), tuple(full_fields.index(s)
                                    for s in fields if s in full_fields)

def read_all_hills(files: Union[Sequence[str], str],
                   colvar: bool=False,
                   step: int=1) -> pd.DataFrame:
    '''
    Read CV information from HILLS files.

    Parameters
    ----------
    files : List of filenames or glob pattern to read from.
    step : Stepsize to use while reading.
    Returns
    -------
    timedata : Dataframe with time as first column and CV data for the rest.

    '''
    if isinstance(files, str):
        files = [files]

    # Prepare list from globbed strings
    filelist = []  # type: List[str]
    for file in files:
        if any(char in file for char in '*?[]'):
            filelist.extend(glob.iglob(file))
        else:
            filelist.append(file)

    if colvar:
        raw = []
        for file in sorted(filelist):
            raw.append(read_plumed(file, step=step))

        return (pd.concat(raw)
                  .sort_values('time')
                  .dropna(axis=0)
                  .sort_index()
                  .drop('pb.bias', axis=1))

    else:
        # Read the time column first
        length = file_length(filelist[0]) - 1
        timedata = read_plumed(filelist[0], step=step, stop=length,
                               replicas=True, columns=(0,), dataframe=True)

        # Append all other columns
        for file in sorted(filelist):
            data = read_plumed(file, step=step, stop=length,
                               replicas=True, dataframe=True)
            timedata = pd.concat(
                [timedata, pd.DataFrame(data.iloc[:, 1])], axis=1
            )
        return timedata.dropna(axis=0).sort_index()

def sum_hills(files: Union[Sequence[str], str],
              nbins: int=50, plumed: str='plumed') -> pd.DataFrame:
    '''
    Calculate the free-energy using plumed sum_hills.

    Parameters
    ----------
    files : Hills files to be passed to PLUMED, globbing allowed.
    nbins : Number of bins to use for histogramming.
    plumed : Path to the PLUMED executable.

    Returns
    -------
    summed_hills : Dataframe containing binned data for each hills file.

    '''

    if isinstance(files, str):
        files = [files]

    # Prepare list from globbed strings
    filelist = []  # type: List[str]
    for file in files:
        if any(char in file for char in '*?[]'):
            filelist.extend(glob.iglob(file))
        else:
            filelist.append(file)

    # Run sum_hills first
    raw = {}
    with tempfile.TemporaryDirectory() as tmp:
        for hf in sorted(filelist):
            filename = hf.split('/')[-1]
            output = join(tmp, filename)
            cmd = '{0} sum_hills --hills {1} --bin {2} --outfile {3}'.format(
                plumed, hf, nbins, output
            ).split()
            subprocess.run(cmd, check=True)
            raw[filename] = read_plumed(output)['file.free']

    return pd.DataFrame(raw)

def read_rdc(files: Sequence[str]) -> Dict[str, float]:
    '''
    Reads files generated by an RDC program.

    Parameters
    ----------
    files : Paths to files to be read.

    Returns
    -------
    rdcs : Dictionary containing the RDC name
        as keys and the calculated value.

    '''
    rdcs = {}

    # Open dat files and parse
    for file in files:
        with open(file, 'r') as f:
            for line in f.readlines():

                if line.startswith('#'):
                    continue
                data = line.split()
                res_nr, rdc_type, val = int(data[0]), data[3], float(data[4])

                # Translate to our key style
                if rdc_type == 'HN':
                    rdc_type = 'nh'
                elif rdc_type == 'C':
                    rdc_type = 'cac'
                elif rdc_type == 'HA':
                    rdc_type = 'caha'
                else:
                    raise ValueError('Invalid RDC type!')

                rdcs['{0}.rdc{1}'.format(rdc_type, res_nr)] = val
    return rdcs

def read_nmr(
        weights: np.ndarray,
        directory: str,
        nfiles: int,
        skip: int,
        nres: int
) -> Dict[str, float]:
    '''
    Read chemical shifts from an external program.

    Parameters
    ----------
    weights : Array of weights.
    directory : Directory conatining the pred.tab files.
    nfiles : Number of pred.tab files.
    skip : Number of frames to skip when extracting PDB frames.
    nres : Number of residues of the system.

    Returns
    -------
    cs : Dictionary containing the chemical shift names
        as keys and the calculated values.

    '''

    # Prepare input files
    spfiles = [directory + '/traj{0}_pred.tab'.format(i)
               for i in range(nfiles)]
    posatoms = ['nh', 'hn', 'ha', 'ca', 'cb', 'co']

    # Check input
    if len(spfiles) != len(weights):
        raise ValueError(
                'Number of SPARTA+ files must be the same '
                'as the length of the weight array!'
        )

    # Iterate over files
    shifts = {}  # type: Dict[str, float]
    for i, file in enumerate(spfiles):
        with open(file, 'r') as sf:

            # Only use lines starting with digits
            for line in sf.readlines():

                if re.match(r'^\s*\d+', line):
                    tmpline = re.split(r'\s+', line)
                    residue = int(tmpline[1])
                    atoms = tmpline[3].lower()
                    shift = float(tmpline[5])

                    # Skip first and last residues
                    if residue == nres or residue == 1:
                        continue

                    # Use proper Camshift naming convention
                    if atoms == 'n':
                        atoms = 'nh'
                    elif atoms == 'c':
                        atoms = 'co'
                    elif atoms not in posatoms:
                        continue

                    # Add weighted shift to dict
                    key = 'cs.{0}_{1}'.format(atoms, residue - 1)
                    if key in shifts:
                        shifts[key] += shift * weights[i]
                    else:
                        shifts[key] = shift * weights[i]
    return shifts
<|endoftext|>


<commit_before>"""
Default model implementations. Custom database or OAuth backends need to
implement these models with fields and and methods to be compatible with the
views in :attr:`provider.views`.
"""

from django.db import models
from django.conf import settings
from .. import constants
from ..constants import CLIENT_TYPES
from ..utils import now, short_token, long_token, get_code_expiry
from ..utils import get_token_expiry, serialize_instance, deserialize_instance
from .managers import AccessTokenManager
from .. import scope

try:
    from django.utils import timezone
except ImportError:
    timezone = None

AUTH_USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', 'auth.User')

class ClientStatus:
    TEST = 1
    LIVE = 2
    DISABLED = 3

    CHOICES = (
        (TEST, 'TEST'),
        (LIVE, 'LIVE'),
        (DISABLED, 'DISABLED'),
    )

class ScopeField(models.IntegerField):
    initial = {}

    def __init__(self, *args, **kwargs):
        kwargs['choices'] = scope.SCOPE_CHOICES
        super(ScopeField, self).__init__(self, *args, **kwargs)

    def formfield(self, **kwargs):
        from .forms import ScopeChoiceField
        defaults = {'choices_form_class': ScopeChoiceField}
        defaults.update(kwargs)
        return super(ScopeField, self).formfield(**defaults)

    def validate(self, value, model_instance):
        # all the bits in value must be present in list of all scopes
        return value == (value & scope.to_int(*scope.SCOPE_NAME_DICT.values()))

    def __unicode__(self):
        return u'scope'

    def __str__(self):
        return 'scope'

class Client(models.Model):
    """
    Default client implementation.

    Expected fields:

    * :attr:`user`
    * :attr:`name`
    * :attr:`url`
    * :attr:`redirect_url`
    * :attr:`client_id`
    * :attr:`client_secret`
    * :attr:`client_type`

    Clients are outlined in the :rfc:`2` and its subsections.
    """

    user = models.ForeignKey(AUTH_USER_MODEL, related_name='oauth2_client',
        blank=True, null=True)
    name = models.CharField(max_length=255, blank=True)
    url = models.URLField(help_text="Your application's URL.")
    redirect_uri = models.URLField(help_text="Your application's callback URL")
    webhook_uri = models.URLField(help_text="Your application's webhook URL", null=True, blank=True)
    logo = models.ImageField(upload_to=constants.LOGO_STORAGE, null=True, blank=True, help_text="40x40 pixel logo of your application")
    status = models.PositiveSmallIntegerField(max_length=2, choices=ClientStatus.CHOICES, default=1)
    last_updated_date = models.DateTimeField(auto_now=True)
    created_date = models.DateTimeField(auto_now_add=True)
    client_id = models.CharField(max_length=255, default=short_token)
    client_secret = models.CharField(max_length=255, default=long_token)
    client_type = models.IntegerField(choices=CLIENT_TYPES)
    scope = ScopeField(default=0)

    def __unicode__(self):
        return self.redirect_uri

    def __str__(self):
        return self.redirect_uri

    def get_default_token_expiry(self):
        public = (self.client_type == 1)
        return get_token_expiry(public)

    def serialize(self):
        return dict(user=serialize_instance(self.user),
                    name=self.name,
                    url=self.url,
                    redirect_uri=self.redirect_uri,
                    client_id=self.client_id,
                    client_secret=self.client_secret,
                    client_type=self.client_type)

    @classmethod
    def deserialize(cls, data):
        if not data:
            return None

        kwargs = {}

        # extract values that we care about
        for field in cls._meta.fields:
            name = field.name
            val = data.get(field.name, None)

            # handle relations
            if val and field.rel:
                val = deserialize_instance(field.rel.to, val)

            kwargs[name] = val

        return cls(**kwargs)

class Grant(models.Model):
    """
    Default grant implementation. A grant is a code that can be swapped for an
    access token. Grants have a limited lifetime as defined by
    :attr:`provider.constants.EXPIRE_CODE_DELTA` and outlined in
    :rfc:`4.1.2`

    Expected fields:

    * :attr:`user`
    * :attr:`client` - :class:`Client`
    * :attr:`code`
    * :attr:`expires` - :attr:`datetime.datetime`
    * :attr:`redirect_uri`
    * :attr:`scope`
    """
    user = models.ForeignKey(AUTH_USER_MODEL)
    client = models.ForeignKey(Client)
    code = models.CharField(max_length=255, default=long_token)
    expires = models.DateTimeField(default=get_code_expiry)
    redirect_uri = models.CharField(max_length=255, blank=True)
    scope = ScopeField(default=0)

    def __unicode__(self):
        return self.code

class AccessToken(models.Model):
    """
    Default access token implementation. An access token is a time limited
    token to access a user's resources.

    Access tokens are outlined :rfc:`5`.

    Expected fields:

    * :attr:`user`
    * :attr:`token`
    * :attr:`client` - :class:`Client`
    * :attr:`expires` - :attr:`datetime.datetime`
    * :attr:`scope`

    Expected methods:

    * :meth:`get_expire_delta` - returns an integer representing seconds to
        expiry
    """
    user = models.ForeignKey(AUTH_USER_MODEL)
    token = models.CharField(max_length=255, default=long_token, db_index=True)
    client = models.ForeignKey(Client)
    expires = models.DateTimeField()
    scope = ScopeField(default=0)

    objects = AccessTokenManager()

    def __unicode__(self):
        return self.token

    def save(self, *args, **kwargs):
        if not self.expires:
            self.expires = self.client.get_default_token_expiry()
        super(AccessToken, self).save(*args, **kwargs)

    def get_expire_delta(self, reference=None):
        """
        Return the number of seconds until this token expires.
        """
        if reference is None:
            reference = now()
        expiration = self.expires

        if timezone:
            if timezone.is_aware(reference) and timezone.is_naive(expiration):
                # MySQL doesn't support timezone for datetime fields
                # so we assume that the date was stored in the UTC timezone
                expiration = timezone.make_aware(expiration, timezone.utc)
            elif timezone.is_naive(reference) and timezone.is_aware(expiration):
                reference = timezone.make_aware(reference, timezone.utc)

        timedelta = expiration - reference
        return timedelta.days*86400 + timedelta.seconds

class RefreshToken(models.Model):
    """
    Default refresh token implementation. A refresh token can be swapped for a
    new access token when said token expires.

    Expected fields:

    * :attr:`user`
    * :attr:`token`
    * :attr:`access_token` - :class:`AccessToken`
    * :attr:`client` - :class:`Client`
    * :attr:`expired` - ``boolean``
    """
    user = models.ForeignKey(AUTH_USER_MODEL)
    token = models.CharField(max_length=255, default=long_token)
    access_token = models.OneToOneField(AccessToken,
            related_name='refresh_token')
    client = models.ForeignKey(Client)
    expired = models.BooleanField(default=False)

    def __unicode__(self):
        return self.token

from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^provider\.oauth2\.models\.ScopeField"])
<commit_msg>++ Use client id and icon.png name instead of user supplied name<commit_after>"""
Default model implementations. Custom database or OAuth backends need to
implement these models with fields and and methods to be compatible with the
views in :attr:`provider.views`.
"""

import os
from django.db import models
from django.conf import settings
from .. import constants
from ..constants import CLIENT_TYPES
from ..utils import now, short_token, long_token, get_code_expiry
from ..utils import get_token_expiry, serialize_instance, deserialize_instance
from .managers import AccessTokenManager
from .. import scope

try:
    from django.utils import timezone
except ImportError:
    timezone = None

AUTH_USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', 'auth.User')

class ClientStatus:
    TEST = 1
    LIVE = 2
    DISABLED = 3

    CHOICES = (
        (TEST, 'TEST'),
        (LIVE, 'LIVE'),
        (DISABLED, 'DISABLED'),
    )

class ScopeField(models.IntegerField):
    initial = {}

    def __init__(self, *args, **kwargs):
        kwargs['choices'] = scope.SCOPE_CHOICES
        super(ScopeField, self).__init__(self, *args, **kwargs)

    def formfield(self, **kwargs):
        from .forms import ScopeChoiceField
        defaults = {'choices_form_class': ScopeChoiceField}
        defaults.update(kwargs)
        return super(ScopeField, self).formfield(**defaults)

    def validate(self, value, model_instance):
        # all the bits in value must be present in list of all scopes
        return value == (value & scope.to_int(*scope.SCOPE_NAME_DICT.values()))

    def __unicode__(self):
        return u'scope'

    def __str__(self):
        return 'scope'

def client_logo_image_path(instance, filename):
    filename_split = os.path.splitext(filename)
    ext = filename_split[1]
    if not ext:
        ext = '.png'
    return '/'.join([constants.LOGO_STORAGE, instance.client_id, 'icon' + ext])

class Client(models.Model):
    """
    Default client implementation.

    Expected fields:

    * :attr:`user`
    * :attr:`name`
    * :attr:`url`
    * :attr:`redirect_url`
    * :attr:`client_id`
    * :attr:`client_secret`
    * :attr:`client_type`

    Clients are outlined in the :rfc:`2` and its subsections.
    """

    user = models.ForeignKey(AUTH_USER_MODEL, related_name='oauth2_client',
        blank=True, null=True)
    name = models.CharField(max_length=255, blank=True)
    url = models.URLField(help_text="Your application's URL.")
    redirect_uri = models.URLField(help_text="Your application's callback URL")
    webhook_uri = models.URLField(help_text="Your application's webhook URL", null=True, blank=True)
    logo = models.ImageField(upload_to=client_logo_image_path, null=True, blank=True, help_text="40x40 pixel logo of your application")
    status = models.PositiveSmallIntegerField(max_length=2, choices=ClientStatus.CHOICES, default=1)
    last_updated_date = models.DateTimeField(auto_now=True)
    created_date = models.DateTimeField(auto_now_add=True)
    client_id = models.CharField(max_length=255, default=short_token)
    client_secret = models.CharField(max_length=255, default=long_token)
    client_type = models.IntegerField(choices=CLIENT_TYPES)
    scope = ScopeField(default=0)

    def __unicode__(self):
        return self.redirect_uri

    def __str__(self):
        return self.redirect_uri

    def get_default_token_expiry(self):
        public = (self.client_type == 1)
        return get_token_expiry(public)

    def serialize(self):
        return dict(user=serialize_instance(self.user),
                    name=self.name,
                    url=self.url,
                    redirect_uri=self.redirect_uri,
                    client_id=self.client_id,
                    client_secret=self.client_secret,
                    client_type=self.client_type)

    @classmethod
    def deserialize(cls, data):
        if not data:
            return None

        kwargs = {}

        # extract values that we care about
        for field in cls._meta.fields:
            name = field.name
            val = data.get(field.name, None)

            # handle relations
            if val and field.rel:
                val = deserialize_instance(field.rel.to, val)

            kwargs[name] = val

        return cls(**kwargs)

class Grant(models.Model):
    """
    Default grant implementation. A grant is a code that can be swapped for an
    access token. Grants have a limited lifetime as defined by
    :attr:`provider.constants.EXPIRE_CODE_DELTA` and outlined in
    :rfc:`4.1.2`

    Expected fields:

    * :attr:`user`
    * :attr:`client` - :class:`Client`
    * :attr:`code`
    * :attr:`expires` - :attr:`datetime.datetime`
    * :attr:`redirect_uri`
    * :attr:`scope`
    """
    user = models.ForeignKey(AUTH_USER_MODEL)
    client = models.ForeignKey(Client)
    code = models.CharField(max_length=255, default=long_token)
    expires = models.DateTimeField(default=get_code_expiry)
    redirect_uri = models.CharField(max_length=255, blank=True)
    scope = ScopeField(default=0)

    def __unicode__(self):
        return self.code

class AccessToken(models.Model):
    """
    Default access token implementation. An access token is a time limited
    token to access a user's resources.

    Access tokens are outlined :rfc:`5`.

    Expected fields:

    * :attr:`user`
    * :attr:`token`
    * :attr:`client` - :class:`Client`
    * :attr:`expires` - :attr:`datetime.datetime`
    * :attr:`scope`

    Expected methods:

    * :meth:`get_expire_delta` - returns an integer representing seconds to
        expiry
    """
    user = models.ForeignKey(AUTH_USER_MODEL)
    token = models.CharField(max_length=255, default=long_token, db_index=True)
    client = models.ForeignKey(Client)
    expires = models.DateTimeField()
    scope = ScopeField(default=0)

    objects = AccessTokenManager()

    def __unicode__(self):
        return self.token

    def save(self, *args, **kwargs):
        if not self.expires:
            self.expires = self.client.get_default_token_expiry()
        super(AccessToken, self).save(*args, **kwargs)

    def get_expire_delta(self, reference=None):
        """
        Return the number of seconds until this token expires.
        """
        if reference is None:
            reference = now()
        expiration = self.expires

        if timezone:
            if timezone.is_aware(reference) and timezone.is_naive(expiration):
                # MySQL doesn't support timezone for datetime fields
                # so we assume that the date was stored in the UTC timezone
                expiration = timezone.make_aware(expiration, timezone.utc)
            elif timezone.is_naive(reference) and timezone.is_aware(expiration):
                reference = timezone.make_aware(reference, timezone.utc)

        timedelta = expiration - reference
        return timedelta.days*86400 + timedelta.seconds

class RefreshToken(models.Model):
    """
    Default refresh token implementation. A refresh token can be swapped for a
    new access token when said token expires.

    Expected fields:

    * :attr:`user`
    * :attr:`token`
    * :attr:`access_token` - :class:`AccessToken`
    * :attr:`client` - :class:`Client`
    * :attr:`expired` - ``boolean``
    """
    user = models.ForeignKey(AUTH_USER_MODEL)
    token = models.CharField(max_length=255, default=long_token)
    access_token = models.OneToOneField(AccessToken,
            related_name='refresh_token')
    client = models.ForeignKey(Client)
    expired = models.BooleanField(default=False)

    def __unicode__(self):
        return self.token

from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^provider\.oauth2\.models\.ScopeField"])
<|endoftext|>


<commit_before>from dateutil import parser
from django.core.management import BaseCommand
import feedparser
from podcasts.models import Podcast, Episode

class Command(BaseCommand):
    help = 'Fetch new podcast episodes'

    def handle(self, *args, **kwargs):
        for podcast in Podcast.objects.all():
            episodes = podcast.episodes
            feed = feedparser.parse(podcast.feed)
            for feed_episode in feed.entries:
                try:
                    if len(episodes.filter(podcast=podcast).filter(
                            title=feed_episode.title)):
                        # If the episode already is in the DB
                        # break and don't check any more episodes in this feed
                        break
                except AttributeError:
                    # The episode in the feed doesn't have a title
                    continue
                episode = Episode(
                    podcast=podcast,
                    title=feed_episode.title,
                    link=self.get_link(feed_episode),
                    description=self.get_description(feed_episode),
                    published=self.get_published(feed_episode),
                    audio_file=self.get_audio_file(feed_episode),
                )
                episode.save()

    @staticmethod
    def get_link(episode):
        return getattr(episode, 'link', '')

    @staticmethod
    def get_published(episode):
        # parser.parse(): http://stackoverflow.com/a/18726020/595990
        return parser.parse(episode.published)

    @staticmethod
    def get_audio_file(episode):
        enclosures = getattr(episode, 'enclosures', '')
        for enclosure in enclosures:
            if enclosure.type[:5] == 'audio':
                return enclosures[0].href
        return ''

    @staticmethod
    def get_description(episode):
        summary = getattr(episode, 'summary', None)
        if summary:
            return summary
        content = getattr(episode, 'content', None)
        if content:
            return content[0].value
        return ''
<commit_msg>Make it possible to fetch episodes from a specific podcast<commit_after>from dateutil import parser
from django.core.management import BaseCommand
import feedparser
from podcasts.models import Podcast, Episode

class Command(BaseCommand):
    help = 'Fetch new podcast episodes'

    def handle(self, *args, **kwargs):
        if len(args):
            podcasts = []
            for arg in args:
                if arg.isdigit():
                    podcasts.extend(Podcast.objects.filter(pk=arg))
                else:
                    podcasts.extend(Podcast.objects.filter(slug=arg))
        else:
            podcasts = Podcast.objects.all()
        for podcast in podcasts:
            episodes = podcast.episodes
            feed = feedparser.parse(podcast.feed)
            for feed_episode in feed.entries:
                try:
                    if len(episodes.filter(podcast=podcast).filter(
                            title=feed_episode.title)):
                        # If the episode already is in the DB
                        # break and don't check any more episodes in this feed
                        break
                except AttributeError:
                    # The episode in the feed doesn't have a title
                    continue
                episode = Episode(
                    podcast=podcast,
                    title=feed_episode.title,
                    link=self.get_link(feed_episode),
                    description=self.get_description(feed_episode),
                    published=self.get_published(feed_episode),
                    audio_file=self.get_audio_file(feed_episode),
                )
                episode.save()

    @staticmethod
    def get_link(episode):
        return getattr(episode, 'link', '')

    @staticmethod
    def get_published(episode):
        # parser.parse(): http://stackoverflow.com/a/18726020/595990
        return parser.parse(episode.published)

    @staticmethod
    def get_audio_file(episode):
        enclosures = getattr(episode, 'enclosures', '')
        for enclosure in enclosures:
            if enclosure.type[:5] == 'audio':
                return enclosures[0].href
        return ''

    @staticmethod
    def get_description(episode):
        summary = getattr(episode, 'summary', None)
        if summary:
            return summary
        content = getattr(episode, 'content', None)
        if content:
            return content[0].value
        return ''
<|endoftext|>


<commit_before>import sys

import json
import logging
import requests
import time
import traceback
import uuid

import clize
from clize import Parameter
from scout import Scout

from AmbassadorConfig import AmbassadorConfig

import VERSION

__version__ = VERSION.Version

logging.basicConfig(
    level=logging.INFO, # if appDebug else logging.INFO,
    format="%%(asctime)s ambassador %s %%(levelname)s: %%(message)s" % __version__,
    datefmt="%Y-%m-%d %H:%M:%S"
)

# logging.getLogger("datawire.scout").setLevel(logging.DEBUG)
logger = logging.getLogger("ambassador")
logger.setLevel(logging.DEBUG)

scout = Scout(app="ambassador", version=__version__,
              id_plugin=Scout.configmap_install_id_plugin)

def handle_exception(what, e, **kwargs):
    tb = "\n".join(traceback.format_exception(*sys.exc_info()))

    result = scout.report(action=what, exception=str(e), traceback=tb, **kwargs)

    time.sleep(1)

    logger.debug("Scout %s, result: %s" % ("disabled" if scout.disabled else "enabled", result))
    logger.error("%s: %s\n%s" % (what, e, tb))

def version():
    """
    Show Ambassador's version
    """

    print("Ambassador %s" % __version__)

def showid():
    """
    Show Ambassador's installation ID
    """

    print("%s" % scout.install_id)

def publish(config_dir_path:Parameter.REQUIRED, output_config_map="ambassador-config"):
    """
    Push an Ambassador configuration to a configmap

    :param config_dir_path: Configuration directory to scan for Ambassador YAML files
    :param output_config_map: Name of map to update
    """

def config(config_dir_path:Parameter.REQUIRED, output_json_path:Parameter.REQUIRED, *, check=False):
    """
    Generate an Envoy configuration

    :param config_dir_path: Configuration directory to scan for Ambassador YAML files
    :param output_json_path: Path to output envoy.json
    :param check: If set, generate configuration only if it doesn't already exist
    """

    try:
        logger.debug("CHECK MODE  %s" % check)
        logger.debug("CONFIG DIR  %s" % config_dir_path)
        logger.debug("OUTPUT PATH %s" % output_json_path)

        # Bypass the existence check...
        output_exists = False

        if check:
            # ...oh no wait, they explicitly asked for the existence check!
            # Assume that the file exists (ie, we'll do nothing) unless we
            # determine otherwise.
            output_exists = True

            try:
                x = json.loads(open(output_json_path, "r").read())
            except FileNotFoundError:
                logger.debug("output file does not exist")
                output_exists = False
            except OSError:
                logger.warning("output file is not sane?")
                output_exists = False
            except json.decoder.JSONDecodeError:
                logger.warning("output file is not valid JSON")
                output_exists = False

            logger.info("Output file %s" % ("exists" if output_exists else "does not exist"))

        if not output_exists:
            # Either we didn't need to check, or the check didn't turn up
            # a valid config. Regenerate.
            logger.info("Generating new Envoy configuration...")
            aconf = AmbassadorConfig(config_dir_path)
            econf = aconf.envoy_config_object()
            aconf.pretty(econf, out=open(output_json_path, "w"))

        scout.report(action="config", check=check, generated=(not output_exists),
                     config_dir_path=config_dir_path, output_json_path=output_json_path)
    except Exception as e:
        # scout.report(action="WTFO?")
        handle_exception("EXCEPTION from config", e,
                         config_dir_path=config_dir_path, output_json_path=output_json_path)

if __name__ == "__main__":
    clize.run([config, publish], alt=[version, showid],
              description="""
              Generate an Envoy config, or manage an Ambassador deployment. Use

              ambassador.py command --help

              for more help, or

              ambassador.py --version

              to see Ambassador's version.
              """)
<commit_msg>Switch prerelease info for build info when handing off our version to Scout.<commit_after>import sys

import json
import logging
import requests
import time
import traceback
import uuid

import clize
from clize import Parameter
from scout import Scout

from AmbassadorConfig import AmbassadorConfig

import VERSION

__version__ = VERSION.Version

logging.basicConfig(
    level=logging.INFO, # if appDebug else logging.INFO,
    format="%%(asctime)s ambassador %s %%(levelname)s: %%(message)s" % __version__,
    datefmt="%Y-%m-%d %H:%M:%S"
)

# logging.getLogger("datawire.scout").setLevel(logging.DEBUG)
logger = logging.getLogger("ambassador")
logger.setLevel(logging.DEBUG)

scout_version = "+".join(__version__.split('-', 1))

scout = Scout(app="ambassador", version=scout_version,
              id_plugin=Scout.configmap_install_id_plugin)

def handle_exception(what, e, **kwargs):
    tb = "\n".join(traceback.format_exception(*sys.exc_info()))

    result = scout.report(action=what, exception=str(e), traceback=tb, **kwargs)

    time.sleep(1)

    logger.debug("Scout %s, result: %s" % ("disabled" if scout.disabled else "enabled", result))
    logger.error("%s: %s\n%s" % (what, e, tb))

def version():
    """
    Show Ambassador's version
    """

    print("Ambassador %s" % __version__)

def showid():
    """
    Show Ambassador's installation ID
    """

    print("%s" % scout.install_id)

def publish(config_dir_path:Parameter.REQUIRED, output_config_map="ambassador-config"):
    """
    Push an Ambassador configuration to a configmap

    :param config_dir_path: Configuration directory to scan for Ambassador YAML files
    :param output_config_map: Name of map to update
    """

def config(config_dir_path:Parameter.REQUIRED, output_json_path:Parameter.REQUIRED, *, check=False):
    """
    Generate an Envoy configuration

    :param config_dir_path: Configuration directory to scan for Ambassador YAML files
    :param output_json_path: Path to output envoy.json
    :param check: If set, generate configuration only if it doesn't already exist
    """

    try:
        logger.debug("CHECK MODE  %s" % check)
        logger.debug("CONFIG DIR  %s" % config_dir_path)
        logger.debug("OUTPUT PATH %s" % output_json_path)

        # Bypass the existence check...
        output_exists = False

        if check:
            # ...oh no wait, they explicitly asked for the existence check!
            # Assume that the file exists (ie, we'll do nothing) unless we
            # determine otherwise.
            output_exists = True

            try:
                x = json.loads(open(output_json_path, "r").read())
            except FileNotFoundError:
                logger.debug("output file does not exist")
                output_exists = False
            except OSError:
                logger.warning("output file is not sane?")
                output_exists = False
            except json.decoder.JSONDecodeError:
                logger.warning("output file is not valid JSON")
                output_exists = False

            logger.info("Output file %s" % ("exists" if output_exists else "does not exist"))

        if not output_exists:
            # Either we didn't need to check, or the check didn't turn up
            # a valid config. Regenerate.
            logger.info("Generating new Envoy configuration...")
            aconf = AmbassadorConfig(config_dir_path)
            econf = aconf.envoy_config_object()
            aconf.pretty(econf, out=open(output_json_path, "w"))

        scout.report(action="config", check=check, generated=(not output_exists),
                     config_dir_path=config_dir_path, output_json_path=output_json_path)
    except Exception as e:
        # scout.report(action="WTFO?")
        handle_exception("EXCEPTION from config", e,
                         config_dir_path=config_dir_path, output_json_path=output_json_path)

if __name__ == "__main__":
    clize.run([config, publish], alt=[version, showid],
              description="""
              Generate an Envoy config, or manage an Ambassador deployment. Use

              ambassador.py command --help

              for more help, or

              ambassador.py --version

              to see Ambassador's version.
              """)
<|endoftext|>


<commit_before># Generated by Django 2.1.2 on 2019-11-30 20:48

from django.db import migrations, models
import django.db.models.deletion

class Migration(migrations.Migration):

    dependencies = [
        ('pokemon_v2', '0004_iso639length_20191217'),
    ]

    operations = [
        migrations.CreateModel(
            name='PokemonTypePast',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('slot', models.IntegerField()),
                ('generation', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='pokemontypepast', to='pokemon_v2.Generation')),
                ('pokemon', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='pokemontypepast', to='pokemon_v2.Pokemon')),
                ('type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='pokemontypepast', to='pokemon_v2.Type')),
            ],
            options={
                'abstract': False,
            },
        ),
    ]
<commit_msg>Regenerate Pokemon past types migration<commit_after># Generated by Django 2.1.11 on 2021-02-06 21:31

from django.db import migrations, models
import django.db.models.deletion

class Migration(migrations.Migration):

    dependencies = [
        ('pokemon_v2', '0004_iso639length_20191217'),
    ]

    operations = [
        migrations.CreateModel(
            name='PokemonTypePast',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('slot', models.IntegerField()),
                ('generation', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='pokemontypepast', to='pokemon_v2.Generation')),
                ('pokemon', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='pokemontypepast', to='pokemon_v2.Pokemon')),
                ('type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='pokemontypepast', to='pokemon_v2.Type')),
            ],
            options={
                'abstract': False,
            },
        ),
    ]
<|endoftext|>


<commit_before># Copyright 2019 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Contains the version string of TFX."""

# Note that setup.py uses this version.
__version__ = '0.12.0rc0'
<commit_msg>0.12.0rc3 release<commit_after># Copyright 2019 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Contains the version string of TFX."""

# Note that setup.py uses this version.
__version__ = '0.12.0rc3'
<|endoftext|>


<commit_before>"""Generate Warmup requests."""

import tensorflow as tf
import requests

from tensorflow.python.framework import tensor_util
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_log_pb2

IMAGE_URL = 'https://tensorflow.org/images/blogs/serving/cat.jpg'
NUM_RECORDS = 100

def get_image_bytes():
    image_content = requests.get(IMAGE_URL, stream=True)
    image_content.raise_for_status()
    return image_content.content

def main():
    """Generate TFRecords for warming up."""

    with tf.io.TFRecordWriter("tf_serving_warmup_requests") as writer:
        image_bytes = get_image_bytes()
        predict_request = predict_pb2.PredictRequest()
        predict_request.model_spec.name = 'resnet'
        predict_request.model_spec.signature_name = 'serving_default'
        predict_request.inputs['image_bytes'].CopyFrom(
            tensor_util.make_tensor_proto([image_bytes], tf.string))
        log = prediction_log_pb2.PredictionLog(
            predict_log=prediction_log_pb2.PredictLog(request=predict_request))
        for r in range(NUM_RECORDS):
            writer.write(log.SerializeToString())

if __name__ == "__main__":
    main()
<commit_msg>Update model_warmup.py<commit_after>#
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Generate Warmup requests."""

import tensorflow as tf
import requests

from tensorflow.python.framework import tensor_util
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_log_pb2

IMAGE_URL = 'https://tensorflow.org/images/blogs/serving/cat.jpg'
NUM_RECORDS = 100

def get_image_bytes():
    image_content = requests.get(IMAGE_URL, stream=True)
    image_content.raise_for_status()
    return image_content.content

def main():
    """Generate TFRecords for warming up."""

    with tf.io.TFRecordWriter("tf_serving_warmup_requests") as writer:
        image_bytes = get_image_bytes()
        predict_request = predict_pb2.PredictRequest()
        predict_request.model_spec.name = 'resnet'
        predict_request.model_spec.signature_name = 'serving_default'
        predict_request.inputs['image_bytes'].CopyFrom(
            tensor_util.make_tensor_proto([image_bytes], tf.string))
        log = prediction_log_pb2.PredictionLog(
            predict_log=prediction_log_pb2.PredictLog(request=predict_request))
        for r in range(NUM_RECORDS):
            writer.write(log.SerializeToString())

if __name__ == "__main__":
    main()
<|endoftext|>


<commit_before>from collections import defaultdict, Sequence, Sized, Iterable, Callable
import inspect
import wrapt
from cytoolz import curry
from numpy import ndarray

from .exceptions import UndefinedOperatorError, DifferentLengthError
from .exceptions import ExpectedTypeError, ShapeMismatchError
from .exceptions import OutsideRangeError

def is_docs(arg_id, args, kwargs):
    from spacy.tokens.doc import Doc
    docs = args[arg_id]
    if not isinstance(docs, Sequence):
        raise ExpectedTypeError(type(docs), ['Sequence'])
    if not isinstance(docs[0], Doc):
        raise ExpectedTypeError(type(docs[0]), ['spacy.tokens.doc.Doc'])

def equal_length(*args):
    '''Check that arguments have the same length.
    '''
    for i, arg in enumerate(args):
        if not isinstance(arg, Sized):
            raise ExpectedTypeError(arg, ['Sized'])
        if i >= 1 and len(arg) != len(args[0]):
            raise DifferentLengthError(args, arg)

def equal_axis(*args, **axis):
    '''Check that elements have the same dimension on specified axis.
    '''
    axis = axis.get('axis', -1)
    for i, arg in enumerate(args):
        if not isinstance(arg, ndarray):
            raise ExpectedTypeError(arg, ['ndarray'])
        if axis >= 0 and (axis+1) < args[i].shape[axis]:
            raise ShapeError(
                "Shape: %s. Expected at least %d dimensions",
                shape, axis)
        if i >= 1 and arg.shape[axis] != args[0].shape[axis]:
            lengths = [a.shape[axis] for a in args]
            raise DifferentLengthError(lengths, arg)

@curry
def has_shape(shape, arg_id, args, kwargs):
    '''Check that a particular argument is an array with a given shape. The
    shape may contain string attributes, which will be fetched from arg0 to
    the function (usually self).
    '''
    self = args[0]
    arg = args[arg_id]
    if not hasattr(arg, 'shape'):
        raise ExpectedTypeError(arg, ['array'])
    shape_values = []
    for dim in shape:
        if not isinstance(dim, int):
            dim = getattr(self, dim, None)
        shape_values.append(dim)
    if len(shape) != len(arg.shape):
        raise ShapeMismatchError(arg.shape, tuple(shape_values), shape)
    for i, dim in enumerate(shape_values):
        # Allow underspecified dimensions
        if dim != None and arg.shape[i] != dim:
            raise ShapeMismatchError(arg.shape, shape_values, shape)

def is_shape(arg_id, args, func_kwargs, **kwargs):
    arg = args[arg_id]
    if not isinstance(arg, Iterable):
        raise ExpectedTypeError(arg, ['iterable'])
    for value in arg:
        if not isinstance(value, int) or value < 0:
            raise ExpectedTypeError(arg, ['valid shape (positive ints)'])

def is_sequence(arg_id, args, kwargs):
    arg = args[arg_id]
    if not isinstance(arg, Iterable):
        raise ExpectedTypeError(arg, ['iterable'])

def is_float(arg_id, args, func_kwargs, **kwargs):
    arg = args[arg_id]
    if not isinstance(arg, float):
        raise ExpectedTypeError(arg, ['float'])
    if 'min' in kwargs and arg < kwargs['min']:
        raise OutsideRangeError(arg, kwargs['min'], '>=')
    if 'max' in kwargs and arg > kwargs['max']:
        raise OutsideRangeError(arg, kwargs['max'], '<=')

def is_int(arg_id, args, func_kwargs, **kwargs):
    arg = args[arg_id]
    if not isinstance(arg, int):
        raise ExpectedTypeError(arg, ['int'])
    if 'min' in kwargs and arg < kwargs['min']:
        raise OutsideRangeError(arg, kwargs['min'], '>=')
    if 'max' in kwargs and arg > kwargs['max']:
        raise OutsideRangeError(arg, kwargs['max'], '<=')

def is_array(arg_id, args, func_kwargs, **kwargs):
    arg = args[arg_id]
    if not isinstance(arg, ndarray):
        raise ExpectedTypeError(arg, ['ndarray'])

def is_int_array(arg_id, args, func_kwargs, **kwargs):
    arg = args[arg_id]
    if not isinstance(arg, ndarray) or 'i' not in arg.dtype.kind:
        raise ExpectedTypeError(arg, ['ndarray[int]'])

def operator_is_defined(op):
    @wrapt.decorator
    def checker(wrapped, instance, args, kwargs):
        if instance is None:
            instance = args[0]
        if instance is None:
            raise ExpectedTypeError(instance, ['Model'])
        if op not in instance._operators:
            raise UndefinedOperatorError(op, instance, args[0], instance._operators)
        else:
            return wrapped(*args, **kwargs)
    return checker

def arg(arg_id, *constraints):
    @wrapt.decorator
    def checked_function(wrapped, instance, args, kwargs):
        # for partial functions or other C-compiled functions
        if not hasattr(wrapped, 'checks'): # pragma: no cover
            return wrapped(*args, **kwargs)
        if instance is not None:
            fix_args = [instance] + list(args)
        else:
            fix_args = list(args)
        for arg_id, checks in wrapped.checks.items():
            for check in checks:
                if not isinstance(check, Callable):
                    raise ExpectedTypeError(check, ['Callable'])
                check(arg_id, fix_args, kwargs)
        return wrapped(*args, **kwargs)

    def arg_check_adder(func):
        if hasattr(func, 'checks'):
            func.checks.setdefault(arg_id, []).extend(constraints)
            return func
        else:
            wrapped = checked_function(func)
            wrapped.checks = {arg_id: list(constraints)}
            return wrapped
    return arg_check_adder

def args(*constraints):
    @wrapt.decorator
    def arg_check_adder(wrapped, instance, args, kwargs):
        for check in constraints:
            if not isinstance(check, Callable):
                raise ExpectedTypeError(check, ['Callable'])
            check(*args)
        return wrapped(*args, **kwargs)
    return arg_check_adder
<commit_msg>Fix type check for has_shape<commit_after>from collections import defaultdict, Sequence, Sized, Iterable, Callable
import inspect
import wrapt
from cytoolz import curry
from numpy import ndarray

from .exceptions import UndefinedOperatorError, DifferentLengthError
from .exceptions import ExpectedTypeError, ShapeMismatchError
from .exceptions import OutsideRangeError

def is_docs(arg_id, args, kwargs):
    from spacy.tokens.doc import Doc
    docs = args[arg_id]
    if not isinstance(docs, Sequence):
        raise ExpectedTypeError(type(docs), ['Sequence'])
    if not isinstance(docs[0], Doc):
        raise ExpectedTypeError(type(docs[0]), ['spacy.tokens.doc.Doc'])

def equal_length(*args):
    '''Check that arguments have the same length.
    '''
    for i, arg in enumerate(args):
        if not isinstance(arg, Sized):
            raise ExpectedTypeError(arg, ['Sized'])
        if i >= 1 and len(arg) != len(args[0]):
            raise DifferentLengthError(args, arg)

def equal_axis(*args, **axis):
    '''Check that elements have the same dimension on specified axis.
    '''
    axis = axis.get('axis', -1)
    for i, arg in enumerate(args):
        if not isinstance(arg, ndarray):
            raise ExpectedTypeError(arg, ['ndarray'])
        if axis >= 0 and (axis+1) < args[i].shape[axis]:
            raise ShapeError(
                "Shape: %s. Expected at least %d dimensions",
                shape, axis)
        if i >= 1 and arg.shape[axis] != args[0].shape[axis]:
            lengths = [a.shape[axis] for a in args]
            raise DifferentLengthError(lengths, arg)

@curry
def has_shape(shape, arg_id, args, kwargs):
    '''Check that a particular argument is an array with a given shape. The
    shape may contain string attributes, which will be fetched from arg0 to
    the function (usually self).
    '''
    self = args[0]
    arg = args[arg_id]
    if not hasattr(arg, 'shape'):
        raise ExpectedTypeError(arg, ['array'])
    shape_values = []
    for dim in shape:
        if not isinstance(dim, int):
            dim = getattr(self, dim, None)
        shape_values.append(dim)
    if len(shape) != len(arg.shape):
        raise ShapeMismatchError(arg.shape, tuple(shape_values), shape)
    for i, dim in enumerate(shape_values):
        # Allow underspecified dimensions
        if dim != None and arg.shape[i] != dim:
            raise ShapeMismatchError(arg.shape, shape_values, shape)

def is_shape(arg_id, args, func_kwargs, **kwargs):
    arg = args[arg_id]
    if not isinstance(arg, Iterable):
        raise ExpectedTypeError(arg, ['iterable'])
    for value in arg:
        if not isinstance(value, int) or value < 0:
            raise ExpectedTypeError(arg, ['valid shape (positive ints)'])

def is_sequence(arg_id, args, kwargs):
    arg = args[arg_id]
    if not isinstance(arg, Iterable) and not hasattr(arg, '__getitem__'):
        raise ExpectedTypeError(arg, ['iterable'])

def is_float(arg_id, args, func_kwargs, **kwargs):
    arg = args[arg_id]
    if not isinstance(arg, float):
        raise ExpectedTypeError(arg, ['float'])
    if 'min' in kwargs and arg < kwargs['min']:
        raise OutsideRangeError(arg, kwargs['min'], '>=')
    if 'max' in kwargs and arg > kwargs['max']:
        raise OutsideRangeError(arg, kwargs['max'], '<=')

def is_int(arg_id, args, func_kwargs, **kwargs):
    arg = args[arg_id]
    if not isinstance(arg, int):
        raise ExpectedTypeError(arg, ['int'])
    if 'min' in kwargs and arg < kwargs['min']:
        raise OutsideRangeError(arg, kwargs['min'], '>=')
    if 'max' in kwargs and arg > kwargs['max']:
        raise OutsideRangeError(arg, kwargs['max'], '<=')

def is_array(arg_id, args, func_kwargs, **kwargs):
    arg = args[arg_id]
    if not isinstance(arg, ndarray):
        raise ExpectedTypeError(arg, ['ndarray'])

def is_int_array(arg_id, args, func_kwargs, **kwargs):
    arg = args[arg_id]
    if not isinstance(arg, ndarray) or 'i' not in arg.dtype.kind:
        raise ExpectedTypeError(arg, ['ndarray[int]'])

def operator_is_defined(op):
    @wrapt.decorator
    def checker(wrapped, instance, args, kwargs):
        if instance is None:
            instance = args[0]
        if instance is None:
            raise ExpectedTypeError(instance, ['Model'])
        if op not in instance._operators:
            raise UndefinedOperatorError(op, instance, args[0], instance._operators)
        else:
            return wrapped(*args, **kwargs)
    return checker

def arg(arg_id, *constraints):
    @wrapt.decorator
    def checked_function(wrapped, instance, args, kwargs):
        # for partial functions or other C-compiled functions
        if not hasattr(wrapped, 'checks'): # pragma: no cover
            return wrapped(*args, **kwargs)
        if instance is not None:
            fix_args = [instance] + list(args)
        else:
            fix_args = list(args)
        for arg_id, checks in wrapped.checks.items():
            for check in checks:
                if not isinstance(check, Callable):
                    raise ExpectedTypeError(check, ['Callable'])
                check(arg_id, fix_args, kwargs)
        return wrapped(*args, **kwargs)

    def arg_check_adder(func):
        if hasattr(func, 'checks'):
            func.checks.setdefault(arg_id, []).extend(constraints)
            return func
        else:
            wrapped = checked_function(func)
            wrapped.checks = {arg_id: list(constraints)}
            return wrapped
    return arg_check_adder

def args(*constraints):
    @wrapt.decorator
    def arg_check_adder(wrapped, instance, args, kwargs):
        for check in constraints:
            if not isinstance(check, Callable):
                raise ExpectedTypeError(check, ['Callable'])
            check(*args)
        return wrapped(*args, **kwargs)
    return arg_check_adder
<|endoftext|>


<commit_before>import os
import pandas as pd
import pyodbc
import datetime<commit_msg>Delete __init__.py<commit_after><|endoftext|>


<commit_before>import itertools
import random

from players import AbstractPlayer

class Table(object):

    def __init__(self):
        self.grid = range(1, 10)
        self.win_combinations = [
            [1, 2, 3],
            [1, 4, 7],
            [1, 5, 9],
            [2, 5, 8],
            [3, 6, 9],
            [3, 5, 7],
            [4, 5, 6],
            [7, 8, 9],
        ]

    def occupy_cell(self, N):
        self.grid.remove(N)

class AbstractPlayer(object):

    def __init__(self, name=None, human=False):
        self.human = human
        self.owned_cells = []
        self.name = name or "AI" + str(random.randint(1, 10))

    def _check_if_win(self):
        if table.grid:
            c = itertools.combinations(self.owned_cells, 3)

            for combination in c:
                if list(combination) in table.win_combinations:
                    print("Player " + self.name + " wins!")
                    exit(0)

    def move(self, N=None):
        self._occupy_cell(N)
        self._finish_move(N)

    def _occupy_cell(self, N):
        raise NotImplementedError("You must define the way"
                                  "to occupy a cell on the"
                                  "grid")

    def _finish_move(self, N):
        self.owned_cells.append(N)
        self.owned_cells.sort()
        self._check_if_win()

class HumanPlayer(AbstractPlayer):

    def _occupy_cell(self, N):
        if N in table.grid and 0 < N < 10:
            table.occupy_cell(N)
        else:
            print("You are choosing an occupied cell or a non existing one")

class AIPlayer(AbstractPlayer):

    def _occupy_cell(self, N):
        auto_choice = random.choice(table.grid)
        table.occupy_cell(auto_choice)
        print("Player " + self.name + " chooses " + str(auto_choice) + ".")

def main():
    global table
    table = Table()
    start = None

    while not start:
        players = int(raw_input("How many human players will play? (0-2): "))

        if 0 <= players < 3:
            if players == 0:
                player1 = AIPlayer()
                player2 = AIPlayer()
            elif players == 1:
                name = raw_input("Please type the name of the player: ")
                player1 = HumanPlayer(name, True)
                player2 = AIPlayer()
            elif players == 2:
                name = raw_input("Please type the name of the first player: ")
                player1 = HumanPlayer(name, True)
                name = raw_input("Please type the name of the second player: ")
                player2 = HumanPlayer(name, True)
            start = True

    for turn in range(9):
        if turn % 2 == 0:
            N = int(raw_input("Please choose a cell " + player1.name + ": ")
                    ) if player1.human else None
            player1.move(N)
        else:
            N = int(raw_input("Please choose a cell " + player2.name + ": ")
                    ) if player2.human else None
            player2.move(N)

    print("What a match, we have a draw!")

if __name__ == "__main__":
    main()
<commit_msg>Remove bad import<commit_after>import itertools
import random

class Table(object):

    def __init__(self):
        self.grid = range(1, 10)
        self.win_combinations = [
            [1, 2, 3],
            [1, 4, 7],
            [1, 5, 9],
            [2, 5, 8],
            [3, 6, 9],
            [3, 5, 7],
            [4, 5, 6],
            [7, 8, 9],
        ]

    def occupy_cell(self, N):
        self.grid.remove(N)

class AbstractPlayer(object):

    def __init__(self, name=None, human=False):
        self.human = human
        self.owned_cells = []
        self.name = name or "AI" + str(random.randint(1, 10))

    def _check_if_win(self):
        if table.grid:
            c = itertools.combinations(self.owned_cells, 3)

            for combination in c:
                if list(combination) in table.win_combinations:
                    print("Player " + self.name + " wins!")
                    exit(0)

    def move(self, N=None):
        self._occupy_cell(N)
        self._finish_move(N)

    def _occupy_cell(self, N):
        raise NotImplementedError("You must define the way"
                                  "to occupy a cell on the"
                                  "grid")

    def _finish_move(self, N):
        self.owned_cells.append(N)
        self.owned_cells.sort()
        self._check_if_win()

class HumanPlayer(AbstractPlayer):

    def _occupy_cell(self, N):
        if N in table.grid and 0 < N < 10:
            table.occupy_cell(N)
        else:
            print("You are choosing an occupied cell or a non existing one")

class AIPlayer(AbstractPlayer):

    def _occupy_cell(self, N):
        auto_choice = random.choice(table.grid)
        table.occupy_cell(auto_choice)
        print("Player " + self.name + " chooses " + str(auto_choice) + ".")

def main():
    global table
    table = Table()
    start = None

    while not start:
        players = int(raw_input("How many human players will play? (0-2): "))

        if 0 <= players < 3:
            if players == 0:
                player1 = AIPlayer()
                player2 = AIPlayer()
            elif players == 1:
                name = raw_input("Please type the name of the player: ")
                player1 = HumanPlayer(name, True)
                player2 = AIPlayer()
            elif players == 2:
                name = raw_input("Please type the name of the first player: ")
                player1 = HumanPlayer(name, True)
                name = raw_input("Please type the name of the second player: ")
                player2 = HumanPlayer(name, True)
            start = True

    for turn in range(9):
        if turn % 2 == 0:
            N = int(raw_input("Please choose a cell " + player1.name + ": ")
                    ) if player1.human else None
            player1.move(N)
        else:
            N = int(raw_input("Please choose a cell " + player2.name + ": ")
                    ) if player2.human else None
            player2.move(N)

    print("What a match, we have a draw!")

if __name__ == "__main__":
    main()
<|endoftext|>


<commit_before>import random

def display_board(board):
    pass

def player_input():
    pass

def place_marker(board, marker, position):
    pass

def win_check(board, mark):
    pass

def choose_first():
    pass

def space_check(board, position):
    pass

def full_board_check(board):
    pass

def player_choice(board):
    pass

def replay():
    pass

print('Welcome to Tic Tac Toe!')

# while True:
# Set the game up here
# pass

# while game_on:
# Player 1 Turn

# Player2's turn.

# pass

# if not replay():
# break<commit_msg>Delete tic_tac_toe.py<commit_after><|endoftext|>


<commit_before>import os
from flask import render_template, Blueprint, send_file

main = Blueprint('main', __name__, template_folder='templates', static_folder='static/gen', static_url_path='/static')

@main.route('/templates/<path:partial>')
def render_partial(partial=None):
    return render_template(partial + '.html')

@main.route('/favicon.ico')
def send_favicon():
    return send_file('static/favicon.ico')

@main.route('/upload/<path:name>')
def upload(name=None):
    return send_file(os.path.join('upload/'+name))

@main.route('/')
@main.route('/<path:path>')
def index(path=None):
    return render_template('index.html')

<commit_msg>Added 404.<commit_after>import os
from flask import render_template, Blueprint, send_file

main = Blueprint('main', __name__, template_folder='templates', static_folder='static/gen', static_url_path='/static')

@main.route('/templates/<path:partial>')
def render_partial(partial=None):
    return render_template(partial + '.html')

@main.route('/favicon.ico')
def send_favicon():
    return send_file('static/favicon.ico')

@main.route('/upload/<path:name>')
def upload(name=None):
    if os.path.exists(os.path.join('upload/'+name)):
        return send_file(os.path.join('upload/'+name))
    else:
        return "File not found  :(", 400

@main.route('/')
@main.route('/<path:path>')
def index(path=None):
    return render_template('index.html')

<|endoftext|>


<commit_before># Copyright (c) 2010 Chris AtLee
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
"""poster module

Support for streaming HTTP uploads, and multipart/form-data encoding

```poster.version``` is a 3-tuple of integers representing the version number.
New releases of poster will always have a version number that compares greater
than an older version of poster.
New in version 0.6."""

import poster.streaminghttp
import poster.encode

version = (0, 6, 0) # Thanks JP!
<commit_msg>version bump to 0.6.1<commit_after># Copyright (c) 2010 Chris AtLee
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
"""poster module

Support for streaming HTTP uploads, and multipart/form-data encoding

```poster.version``` is a 3-tuple of integers representing the version number.
New releases of poster will always have a version number that compares greater
than an older version of poster.
New in version 0.6."""

import poster.streaminghttp
import poster.encode

version = (0, 6, 1) # Thanks JP!
<|endoftext|>