<commit_before>#! /usr/bin/env python

import argparse
import csv
from pprint import pprint
from time import time

import numpy as np
from sklearn.base import BaseEstimator
from sklearn.datasets.base import Bunch
from sklearn.decomposition import PCA
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.grid_search import GridSearchCV
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.preprocessing import Binarizer, MinMaxScaler
from sklearn.svm import LinearSVC
from sklearn.linear_model import LogisticRegression

def fetch_gitlog(data_path, collapse=None, stats=False):
    """Convert the CSV log into a datase suitable for scikit-learn."""
    description = 'Lageled git log history'

    with open(data_path, 'rb') as csvfile:
        csvreader = csv.reader(csvfile, delimiter=',', quotechar='"',
                               doublequote=True)
        next(csvreader)
        # Summary, Message, Number of Files, Total Lines, Added Lines, Deleted Lines, Label, SHA-1
        full_dataset = [(line[0].strip(), line[1].strip(),
                         int(line[2]), int(line[3]), int(line[4]),
                         int(line[5]), line[6], line[7]) for line in csvreader]

        data = np.array([d for d in full_dataset if d[6]])

        collapse = {} if not collapse else collapse
        for key, value in collapse.items():
            data[data[:, 6] == key, 6] = value

        # Encode targets into numbers
        target = [d[6] for d in data]
        le = LabelEncoder()
        le.fit(target)
        target_names = le.classes_
        target = le.transform(target)

        if stats:
            print 'Original dataset [%d]' % len(full_dataset)
            print 'Labeled dataset [%d]' % len(data)
            print 'Ratio [%2.2f%%]' % (100.0 * len(data) / len(full_dataset))

    return Bunch(filename=data_path,
                 data=data,
                 target_names=target_names,
                 target=target,
                 DESCR=description)

class SliceFeature(BaseEstimator):
    """Estimator to slice a feature."""

    def __init__(self, slc, astype=None, flatten=False):
        """Build an instance using a slice object.

        >>> X = np.array([[1, 2, 3], [10, 20, 30]])
        >>> X
        array([[ 1,  2,  3],
               [10, 20, 30]])

        >>> slc = SliceFeature(slice(0, 1))
        >>> slc.transform(X)
        array([ 1, 10])

        >>> slc = SliceFeature(slice(0, 2))
        >>> slc.transform(X)
        array([[ 1,  2],
               [10, 20]])

        """
        self.slc = slc
        self.astype = astype
        self.flatten = flatten

    def fit(self, X, y=None):
        """Does nothing: this transformer is stateless."""
        return self

    def transform(self, X, y=None):
        if self.slc.step:
            index = range(self.slc.start, self.slc.stop, self.slc.step)
        else:
            index = range(self.slc.start, self.slc.stop)

        result = X[:, index]

        if self.astype:
            result = result.astype(self.astype)

        if self.flatten:
            result = result.reshape(X.shape[0])

        return result

class Densifier(BaseEstimator):
    def fit(self, X, y=None):
        pass

    def fit_transform(self, X, y=None):
        return self.transform(X)

    def transform(self, X, y=None):
        return X.toarray()

def print_score_and_parameters(interesting_parameters, all_parameters, score, scores=None):
    print 'score: %0.3f' % score
    print 'parameters set:'
    for param_name in sorted(interesting_parameters.keys()):
        print '\t%s: %r' % (param_name, all_parameters[param_name])
    if scores is not None:
        print "Scores: ",
        print scores

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Train different models with the same dataset.')
    parser.add_argument('-c', '--csv', help='csv file name')

    args = parser.parse_args()

    if not args.csv:
        parser.print_help()
        exit(1)

    pipeline_summary = Pipeline([
        ('slice', SliceFeature(slice(0, 1), flatten=True)),
        ('vect', CountVectorizer(stop_words='english')),
        # ('binary', Binarizer()),
        ('tfidf', TfidfTransformer()),
        # ('scaler', StandardScaler(with_mean=False)),
    ])

    pipeline_message = Pipeline([
        ('slice', SliceFeature(slice(1, 2), flatten=True)),
        ('vect', CountVectorizer(stop_words='english')),
        # ('binary', Binarizer()),
        ('tfidf', TfidfTransformer()),
        # ('scaler', StandardScaler(with_mean=False)),
    ])

    pipeline_n_files = Pipeline([
        ('slice', SliceFeature(slice(2, 3), astype=float)),
        # ('scaler', MinMaxScaler()),
    ])

    pipeline_n_changes = Pipeline([
        ('slice', SliceFeature(slice(3, 6), astype=float)),
        ('scaler', StandardScaler(with_mean=False)),
    ])

    pipeline_numeric = Pipeline([
        ('slice', SliceFeature(slice(2, 6), astype=int)),
    ])

    main_pipeline = Pipeline([
        ('features', FeatureUnion([
            ('summary', pipeline_summary),
            ('message', pipeline_message),
            ('numeric', pipeline_numeric),
            # ('n_files', pipeline_n_files),
            # ('n_changes', pipeline_n_changes),
        ])),
        # ('densifier', Densifier()),
        # ('scaler', StandardScaler(with_mean=False)),
        # ('scaler', StandardScaler()),
        # ('clf', LinearSVC()),
        # ('pca', PCA(n_components=100)),
        ('clf', LogisticRegression()),
    ])

    parameters = {
        'features__summary__vect__max_df': (0.5, 0.75, 1.0),
        'features__summary__vect__max_features': (None, 5000, 10000, 50000),
        'features__summary__vect__ngram_range': ((1, 1), (1, 2)),  # unigrams or bigrams
        # 'features__summary__tfidf__use_idf': (True, False),
        # 'features__summary__tfidf__norm': ('l1', 'l2'),
        'features__message__vect__max_df': (0.5, 0.75, 1.0),
        'features__message__vect__max_features': (None, 5000, 10000, 50000),
        'features__message__vect__ngram_range': ((1, 1), (1, 2)),  # unigrams or bigrams
        # 'features__message__tfidf__use_idf': (True, False),
        # 'features__message__tfidf__norm': ('l1', 'l2'),
        # 'clf__C': (0.0001, 0.001, 0.01, 0.1, 1.0),
        # 'clf__loss': ('l1', 'l2'),
        # 'clf__penalty': ('l1', 'l2'),
        # 'clf__dual': (True, False),
        # 'clf__tol': (1e-4),
        # 'clf__multi_class': ('ovr', 'crammer_singer'),
        # 'clf__fit_intercept': (True, False),
        # 'clf__intercept_scaling': (0.0001, 0.001, 0.01, 0.1, 1.0),
    }
    grid_search = GridSearchCV(main_pipeline, parameters, n_jobs=-1, verbose=1)

    print 'Performing grid search...'
    print 'pipeline:', [name for name, _ in main_pipeline.steps]
    print 'parameters:'
    pprint(parameters)

    collapse_map = {
        'Fix (Minor)': 'Fix',
        'Fix (Major)': 'Fix',
        'Regression (Minor)': 'Regression',
        'Regression (Major)': 'Regression',
        'Refactoring (Minor)': 'Refactoring',
        'Refactoring (Major)': 'Refactoring',
        'Feature (Minor)': 'Feature',
        'Feature (Major)': 'Feature',
        'Documentation (Minor)': 'Documentation',
        'Documentation (Major)': 'Documentation',
    }
    data = fetch_gitlog(args.csv, collapse=collapse_map, stats=True)

    t0 = time()

    grid_search.fit(data.data, data.target)
    print 'done in %0.3fs' % (time() - t0)
    print

    print "Best result:"
    print_score_and_parameters(parameters,
                               grid_search.best_estimator_.get_params(),
                               grid_search.best_score_)

    # print
    # print "All results:"
    # for result in sorted(grid_search.grid_scores_,
    #                      key=lambda x: x.mean_validation_score):
    #     print_score_and_parameters(parameters,
    #                                result.parameters,
    #                                result.mean_validation_score,
    #                                result.cv_validation_scores)
    #     print
<commit_msg>Collapse intro Fix and Feature (0.816)<commit_after>#! /usr/bin/env python

import argparse
import csv
from pprint import pprint
from time import time

import numpy as np
from sklearn.base import BaseEstimator
from sklearn.datasets.base import Bunch
from sklearn.decomposition import PCA
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.grid_search import GridSearchCV
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.preprocessing import Binarizer, MinMaxScaler
from sklearn.svm import LinearSVC
from sklearn.linear_model import LogisticRegression

def fetch_gitlog(data_path, collapse=None, stats=False):
    """Convert the CSV log into a datase suitable for scikit-learn."""
    description = 'Lageled git log history'

    with open(data_path, 'rb') as csvfile:
        csvreader = csv.reader(csvfile, delimiter=',', quotechar='"',
                               doublequote=True)
        next(csvreader)
        # Summary, Message, Number of Files, Total Lines, Added Lines, Deleted Lines, Label, SHA-1
        full_dataset = [(line[0].strip(), line[1].strip(),
                         int(line[2]), int(line[3]), int(line[4]),
                         int(line[5]), line[6], line[7]) for line in csvreader]

        data = np.array([d for d in full_dataset if d[6]])

        collapse = {} if not collapse else collapse
        for key, value in collapse.items():
            data[data[:, 6] == key, 6] = value

        # Encode targets into numbers
        target = [d[6] for d in data]
        le = LabelEncoder()
        le.fit(target)
        target_names = le.classes_
        target = le.transform(target)

        if stats:
            print 'Original dataset [%d]' % len(full_dataset)
            print 'Labeled dataset [%d]' % len(data)
            print 'Ratio [%2.2f%%]' % (100.0 * len(data) / len(full_dataset))

    return Bunch(filename=data_path,
                 data=data,
                 target_names=target_names,
                 target=target,
                 DESCR=description)

class SliceFeature(BaseEstimator):
    """Estimator to slice a feature."""

    def __init__(self, slc, astype=None, flatten=False):
        """Build an instance using a slice object.

        >>> X = np.array([[1, 2, 3], [10, 20, 30]])
        >>> X
        array([[ 1,  2,  3],
               [10, 20, 30]])

        >>> slc = SliceFeature(slice(0, 1))
        >>> slc.transform(X)
        array([ 1, 10])

        >>> slc = SliceFeature(slice(0, 2))
        >>> slc.transform(X)
        array([[ 1,  2],
               [10, 20]])

        """
        self.slc = slc
        self.astype = astype
        self.flatten = flatten

    def fit(self, X, y=None):
        """Does nothing: this transformer is stateless."""
        return self

    def transform(self, X, y=None):
        if self.slc.step:
            index = range(self.slc.start, self.slc.stop, self.slc.step)
        else:
            index = range(self.slc.start, self.slc.stop)

        result = X[:, index]

        if self.astype:
            result = result.astype(self.astype)

        if self.flatten:
            result = result.reshape(X.shape[0])

        return result

class Densifier(BaseEstimator):
    def fit(self, X, y=None):
        pass

    def fit_transform(self, X, y=None):
        return self.transform(X)

    def transform(self, X, y=None):
        return X.toarray()

def print_score_and_parameters(interesting_parameters, all_parameters, score, scores=None):
    print 'score: %0.3f' % score
    print 'parameters set:'
    for param_name in sorted(interesting_parameters.keys()):
        print '\t%s: %r' % (param_name, all_parameters[param_name])
    if scores is not None:
        print "Scores: ",
        print scores

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Train different models with the same dataset.')
    parser.add_argument('-c', '--csv', help='csv file name')

    args = parser.parse_args()

    if not args.csv:
        parser.print_help()
        exit(1)

    pipeline_summary = Pipeline([
        ('slice', SliceFeature(slice(0, 1), flatten=True)),
        ('vect', CountVectorizer(stop_words='english')),
        # ('binary', Binarizer()),
        ('tfidf', TfidfTransformer()),
        # ('scaler', StandardScaler(with_mean=False)),
    ])

    pipeline_message = Pipeline([
        ('slice', SliceFeature(slice(1, 2), flatten=True)),
        ('vect', CountVectorizer(stop_words='english')),
        # ('binary', Binarizer()),
        ('tfidf', TfidfTransformer()),
        # ('scaler', StandardScaler(with_mean=False)),
    ])

    pipeline_n_files = Pipeline([
        ('slice', SliceFeature(slice(2, 3), astype=float)),
        # ('scaler', MinMaxScaler()),
    ])

    pipeline_n_changes = Pipeline([
        ('slice', SliceFeature(slice(3, 6), astype=float)),
        ('scaler', StandardScaler(with_mean=False)),
    ])

    pipeline_numeric = Pipeline([
        ('slice', SliceFeature(slice(2, 6), astype=int)),
    ])

    main_pipeline = Pipeline([
        ('features', FeatureUnion([
            ('summary', pipeline_summary),
            ('message', pipeline_message),
            ('numeric', pipeline_numeric),
            # ('n_files', pipeline_n_files),
            # ('n_changes', pipeline_n_changes),
        ])),
        # ('densifier', Densifier()),
        # ('scaler', StandardScaler(with_mean=False)),
        # ('scaler', StandardScaler()),
        # ('pca', PCA(n_components=100)),
        ('clf', LinearSVC()),
        # ('clf', LogisticRegression()),
    ])

    parameters = {
        'features__summary__vect__max_df': (0.5, 0.75, 1.0),
        # 'features__summary__vect__max_features': (None, 5000, 10000, 50000),
        # 'features__summary__vect__ngram_range': ((1, 1), (1, 2)),  # unigrams or bigrams
        'features__summary__tfidf__use_idf': (True, False),
        # 'features__summary__tfidf__norm': ('l1', 'l2'),
        'features__message__vect__max_df': (0.5, 0.75, 1.0),
        # 'features__message__vect__max_features': (None, 5000, 10000, 50000),
        # 'features__message__vect__ngram_range': ((1, 1), (1, 2)),  # unigrams or bigrams
        'features__message__tfidf__use_idf': (True, False),
        # 'features__message__tfidf__norm': ('l1', 'l2'),
        # 'clf__C': (0.0001, 0.001, 0.01, 0.1, 1.0),
        # 'clf__loss': ('l1', 'l2'),
        # 'clf__penalty': ('l1', 'l2'),
        # 'clf__dual': (True, False),
        # 'clf__tol': (1e-4),
        # 'clf__multi_class': ('ovr', 'crammer_singer'),
        # 'clf__fit_intercept': (True, False),
        # 'clf__intercept_scaling': (0.0001, 0.001, 0.01, 0.1, 1.0),
    }
    grid_search = GridSearchCV(main_pipeline, parameters, n_jobs=-1, verbose=1)

    print 'Performing grid search...'
    print 'pipeline:', [name for name, _ in main_pipeline.steps]
    print 'parameters:'
    pprint(parameters)

    collapse_map = {
        'Fix (Minor)': 'Fix',
        'Fix (Major)': 'Fix',
        # 'Regression (Minor)': 'Regression',
        # 'Regression (Major)': 'Regression',
        # 'Refactoring (Minor)': 'Refactoring',
        # 'Refactoring (Major)': 'Refactoring',
        'Regression (Minor)': 'Fix',
        'Regression (Major)': 'Fix',
        'Refactoring (Minor)': 'Fix',
        'Refactoring (Major)': 'Fix',
        'Feature (Minor)': 'Feature',
        'Feature (Major)': 'Feature',
        # 'Documentation (Minor)': 'Documentation',
        # 'Documentation (Major)': 'Documentation',
        'Documentation (Minor)': 'Feature',
        'Documentation (Major)': 'Feature',
    }
    data = fetch_gitlog(args.csv, collapse=collapse_map, stats=True)

    t0 = time()

    grid_search.fit(data.data, data.target)
    print 'done in %0.3fs' % (time() - t0)
    print

    print "Best result:"
    print_score_and_parameters(parameters,
                               grid_search.best_estimator_.get_params(),
                               grid_search.best_score_)

    # print
    # print "All results:"
    # for result in sorted(grid_search.grid_scores_,
    #                      key=lambda x: x.mean_validation_score):
    #     print_score_and_parameters(parameters,
    #                                result.parameters,
    #                                result.mean_validation_score,
    #                                result.cv_validation_scores)
    #     print
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
VERSION = __version__ = (0, 1, 0, 'beta', 2)

def get_version(version=None):
    """Derives a PEP386-compliant version number from VERSION."""
    if version is None:
        version = VERSION
    assert len(version) == 5
    assert version[3] in ('alpha', 'beta', 'rc', 'final')

    # Now build the two parts of the version number:
    # main = X.Y[.Z]
    # sub = .devN - for pre-alpha releases
    #     | {a|b|c}N - for alpha, beta and rc releases

    parts = 2 if version[2] == 0 else 3
    main = '.'.join(str(x) for x in version[:parts])

    sub = ''
    if version[3] == 'alpha' and version[4] == 0:
        # At the toplevel, this would cause an import loop.
        from django.utils.version import get_svn_revision
        svn_revision = get_svn_revision()[4:]
        if svn_revision != 'unknown':
            sub = '.dev%s' % svn_revision

    elif version[3] != 'final':
        mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'c'}
        sub = mapping[version[3]] + str(version[4])

    return main + sub
<commit_msg>update version<commit_after># -*- coding: utf-8 -*-
VERSION = __version__ = (0, 1, 0, 'beta', 3)

def get_version(version=None):
    """Derives a PEP386-compliant version number from VERSION."""
    if version is None:
        version = VERSION
    assert len(version) == 5
    assert version[3] in ('alpha', 'beta', 'rc', 'final')

    # Now build the two parts of the version number:
    # main = X.Y[.Z]
    # sub = .devN - for pre-alpha releases
    #     | {a|b|c}N - for alpha, beta and rc releases

    parts = 2 if version[2] == 0 else 3
    main = '.'.join(str(x) for x in version[:parts])

    sub = ''
    if version[3] == 'alpha' and version[4] == 0:
        # At the toplevel, this would cause an import loop.
        from django.utils.version import get_svn_revision
        svn_revision = get_svn_revision()[4:]
        if svn_revision != 'unknown':
            sub = '.dev%s' % svn_revision

    elif version[3] != 'final':
        mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'c'}
        sub = mapping[version[3]] + str(version[4])

    return main + sub
<|endoftext|>


<commit_before>#! /usr/bin/env python2

import wx
from wx.media import MediaCtrl

import os.path
import user

import lyrics
import lyrics3v2

class LyricsCtrl(wx.TextCtrl):
    def __init__(self, parent):
        wx.TextCtrl.__init__(self, parent,
                             style = wx.TE_MULTILINE
                             | wx.TE_READONLY
                             | wx.TE_CENTRE)
        self.lyrics = None

    def SetLyrics(self, lyrics):
        self.lyrics = lyrics
        self.SetValue(''.join(self.lyrics.getPhrases()))

class KaraokePlayer(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        # media widget
        self.player = MediaCtrl(self)

        # lyrics viewer
        self.lyricsViewer = LyricsCtrl(self)

        # menu bar
        self.menuBar = wx.MenuBar()
        self.fileMenu = wx.Menu()
        self.fileMenu.Append(wx.ID_OPEN)
        self.fileMenu.Append(wx.ID_EXIT)
        self.menuBar.Append(self.fileMenu, "&File")
        self.SetMenuBar(self.menuBar)

        self.Bind(wx.EVT_MENU, self.HandleOpen, id=wx.ID_OPEN)
        self.Bind(wx.EVT_MENU, self.HandleExit, id=wx.ID_EXIT)

        # controls
        self.playPauseButton = wx.ToggleButton(self, label="Play/Pause")
        self.stopButton = wx.Button(self, label="Stop")
        self.muteButton = wx.ToggleButton(self, label="Mute")
        self.volumeSlider = wx.Slider(self, minValue=0, maxValue=100, size=(100, -1))
        self.timeSlider = wx.Slider(self, minValue=0, maxValue=0)

        self.Bind(wx.EVT_TOGGLEBUTTON, self.HandlePlayPause, self.playPauseButton)
        self.Bind(wx.EVT_BUTTON, self.HandleStop, self.stopButton)
        self.Bind(wx.EVT_TOGGLEBUTTON, self.HandleMute, self.muteButton)
        self.Bind(wx.EVT_SLIDER, self.HandleVol, self.volumeSlider)
#        self.Bind(wx.EVT_SLIDER, self.HandleTime, self.timeSlider)

        # sizers
        self.buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.buttonSizer.Add(self.playPauseButton, 0, wx.ALL, 10)
        self.buttonSizer.Add(self.stopButton, 0, wx.ALL, 10)
        self.buttonSizer.Add(self.muteButton, 0, wx.ALL | wx.ALIGN_RIGHT, 10)
        self.buttonSizer.Add(self.volumeSlider, 0, wx.ALL | wx.ALIGN_RIGHT, 10)

        self.controlSizer = wx.BoxSizer(wx.VERTICAL)
        self.controlSizer.Add(self.timeSlider, 0, wx.EXPAND)
        self.controlSizer.Add(self.buttonSizer, 0)

        self.viewerSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.viewerSizer.Add(self.player, 1, wx.EXPAND)
        self.viewerSizer.Add(self.lyricsViewer, 1, wx.EXPAND)

        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
        self.mainSizer.Add(self.viewerSizer, 1, wx.EXPAND)
        self.mainSizer.Add(self.controlSizer, 0, wx.EXPAND)

        self.SetSizerAndFit(self.mainSizer)

        # timer
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.HandleTimer, self.timer)

        self.Show()

    def HandleOpen(self, evt):
        self.HandleStop(None)

        dialog = wx.FileDialog(self)

        if dialog.ShowModal() == wx.ID_OK:
            filepath = dialog.GetPath()
            filename = dialog.GetFilename()

            # Show lyrics, if available
            if os.path.splitext(filename)[1] == ".mp3":
                try:
                    self.lyricsViewer.SetLyrics(lyrics3v2.load(lyrics3v2.read(filepath)))
                except ValueError:
                    pass

            self.player.Load(filepath)

            # Hide lyrics viewer if there are no lyrics
            if self.lyricsViewer.IsEmpty():
                self.viewerSizer.Hide(self.lyricsViewer)
            else:
                self.viewerSizer.Show(self.lyricsViewer)

            # Hide player screen if there's no video
            if self.player.GetBestSize() == (0,0):
                self.viewerSizer.Hide(self.player)
            else:
                self.viewerSizer.Show(self.player)

            self.viewerSizer.Layout()

            title = filename
            self.SetTitle(u'{} - Karaoke-chan'.format(title))

            self.volumeSlider.SetValue(int(self.player.GetVolume() * 100))

    def HandleExit(self, evt):
        self.player.Stop()
        self.Close()

    def HandlePlayPause(self, evt):
        if self.playPauseButton.GetValue():
            self.player.Play()
            self.timer.Start(milliseconds=500)
        else:
            self.player.Pause()
            self.timer.Stop()

    def HandleStop(self, evt):
        self.timer.Stop()
        self.player.Stop()
        self.timeSlider.SetMax(0)
        self.timeSlider.SetValue(0)
        self.playPauseButton.SetValue(False)
        self.lyricsViewer.Clear()

    def HandleMute(self, evt):
        if self.muteButton.GetValue():
            self.player.SetVolume(0)
        else:
            self.player.SetVolume(self.volumeSlider.GetValue() / 100.0)

    def HandleVol(self, evt):
        self.player.SetVolume(self.volumeSlider.GetValue() / 100.0)

    def HandleTimer(self, evt):
        self.timeSlider.SetMax(self.player.Length() / 1000)
        self.timeSlider.SetValue(self.player.Tell() / 1000)

if __name__ == "__main__":
    app = wx.App(False)
    player = KaraokePlayer(None, title="Karaoke-chan")
    player.Show()
    app.MainLoop()
<commit_msg>LyricsCtrl now changes text color and scrolls according to timestamps<commit_after>#! /usr/bin/env python2

import wx
import wx.media as wxm

import os.path
import user

import lyrics
import lyrics3v2

class LyricsCtrl(wx.TextCtrl):
    def __init__(self, parent, player):
        wx.TextCtrl.__init__(self, parent,
                             style = wx.TE_MULTILINE
                             | wx.TE_READONLY
                             | wx.TE_CENTRE)
        self.player = player
        self.lyrics = None
        self.phraseTimer = wx.Timer(self)
        self.lastPhrase = None
        self.Bind(wx.EVT_TIMER, self.HandlePhraseTimer, self.phraseTimer)
        parent.Bind(wxm.EVT_MEDIA_STATECHANGED, self.HandlePlayer, self.player)

    def SetLyrics(self, lyrics):
        self.lyrics = lyrics
        self.phrases = lyrics.getPhrases()
        self.times = lyrics.getTimes()
        self.SetValue(''.join(self.phrases))

    def HandlePhraseTimer(self, evt):
        playTime = self.player.Tell() / 10
        phrase, startTime, endTime = self.lyrics.getCurrent(playTime)

        if phrase is not None:
            phraseStart = sum(len(p) for p in self.phrases[:phrase])
            phraseEnd = phraseStart + len(self.phrases[phrase])

            if self.lastPhrase is not None:
                self.SetStyle(self.lastPhrase[0], self.lastPhrase[1],
                              wx.TextAttr(wx.Colour(100,100,100)))

            self.SetStyle(phraseStart, phraseEnd, wx.TextAttr(wx.Colour(0, 0, 255)))
            self.ShowPosition(phraseStart)

            self.lastPhrase = (phraseStart, phraseEnd)

        if endTime is not None:
            self.phraseTimer.Start((endTime - playTime) * 10, wx.TIMER_ONE_SHOT)

    def HandlePlayer(self, evt):
        if self.player.GetState() == wxm.MEDIASTATE_PLAYING:
            self.HandlePhraseTimer(None)
        else:
            self.phraseTimer.Stop()

class KaraokePlayer(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        # media widget
        self.player = wxm.MediaCtrl(self)

        # lyrics viewer
        self.lyricsViewer = LyricsCtrl(self, self.player)

        # menu bar
        self.menuBar = wx.MenuBar()
        self.fileMenu = wx.Menu()
        self.fileMenu.Append(wx.ID_OPEN)
        self.fileMenu.Append(wx.ID_EXIT)
        self.menuBar.Append(self.fileMenu, "&File")
        self.SetMenuBar(self.menuBar)

        self.Bind(wx.EVT_MENU, self.HandleOpen, id=wx.ID_OPEN)
        self.Bind(wx.EVT_MENU, self.HandleExit, id=wx.ID_EXIT)

        # controls
        self.playPauseButton = wx.ToggleButton(self, label="Play/Pause")
        self.stopButton = wx.Button(self, label="Stop")
        self.muteButton = wx.ToggleButton(self, label="Mute")
        self.volumeSlider = wx.Slider(self, minValue=0, maxValue=100, size=(100, -1))
        self.timeSlider = wx.Slider(self, minValue=0, maxValue=0)

        self.Bind(wx.EVT_TOGGLEBUTTON, self.HandlePlayPause, self.playPauseButton)
        self.Bind(wx.EVT_BUTTON, self.HandleStop, self.stopButton)
        self.Bind(wx.EVT_TOGGLEBUTTON, self.HandleMute, self.muteButton)
        self.Bind(wx.EVT_SLIDER, self.HandleVol, self.volumeSlider)
#        self.Bind(wx.EVT_SLIDER, self.HandleTime, self.timeSlider)

        # sizers
        self.buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.buttonSizer.Add(self.playPauseButton, 0, wx.ALL, 10)
        self.buttonSizer.Add(self.stopButton, 0, wx.ALL, 10)
        self.buttonSizer.Add(self.muteButton, 0, wx.ALL | wx.ALIGN_RIGHT, 10)
        self.buttonSizer.Add(self.volumeSlider, 0, wx.ALL | wx.ALIGN_RIGHT, 10)

        self.controlSizer = wx.BoxSizer(wx.VERTICAL)
        self.controlSizer.Add(self.timeSlider, 0, wx.EXPAND)
        self.controlSizer.Add(self.buttonSizer, 0)

        self.viewerSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.viewerSizer.Add(self.player, 1, wx.EXPAND)
        self.viewerSizer.Add(self.lyricsViewer, 1, wx.EXPAND)

        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
        self.mainSizer.Add(self.viewerSizer, 1, wx.EXPAND)
        self.mainSizer.Add(self.controlSizer, 0, wx.EXPAND)

        self.SetSizerAndFit(self.mainSizer)

        # timer
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.HandleTimer, self.timer)

        self.Show()

    def HandleOpen(self, evt):
        self.HandleStop(None)

        dialog = wx.FileDialog(self)

        if dialog.ShowModal() == wx.ID_OK:
            filepath = dialog.GetPath()
            filename = dialog.GetFilename()

            # Show lyrics, if available
            if os.path.splitext(filename)[1] == ".mp3":
                try:
                    self.lyricsViewer.SetLyrics(lyrics3v2.load(lyrics3v2.read(filepath)))
                except ValueError:
                    pass

            self.player.Load(filepath)

            # Hide lyrics viewer if there are no lyrics
            if self.lyricsViewer.IsEmpty():
                self.viewerSizer.Hide(self.lyricsViewer)
            else:
                self.viewerSizer.Show(self.lyricsViewer)

            # Hide player screen if there's no video
            if self.player.GetBestSize() == (0,0):
                self.viewerSizer.Hide(self.player)
            else:
                self.viewerSizer.Show(self.player)

            self.viewerSizer.Layout()

            title = filename
            self.SetTitle(u'{} - Karaoke-chan'.format(title))

            self.volumeSlider.SetValue(int(self.player.GetVolume() * 100))

    def HandleExit(self, evt):
        self.player.Stop()
        self.Close()

    def HandlePlayPause(self, evt):
        if self.playPauseButton.GetValue():
            self.player.Play()
            self.timer.Start(milliseconds=500)
        else:
            self.player.Pause()
            self.timer.Stop()

    def HandleStop(self, evt):
        self.timer.Stop()
        self.player.Stop()
        self.timeSlider.SetMax(0)
        self.timeSlider.SetValue(0)
        self.playPauseButton.SetValue(False)
        self.lyricsViewer.Clear()

    def HandleMute(self, evt):
        if self.muteButton.GetValue():
            self.player.SetVolume(0)
        else:
            self.player.SetVolume(self.volumeSlider.GetValue() / 100.0)

    def HandleVol(self, evt):
        self.player.SetVolume(self.volumeSlider.GetValue() / 100.0)

    def HandleTimer(self, evt):
        self.timeSlider.SetMax(self.player.Length() / 1000)
        self.timeSlider.SetValue(self.player.Tell() / 1000)

if __name__ == "__main__":
    app = wx.App(False)
    player = KaraokePlayer(None, title="Karaoke-chan")
    player.Show()
    app.MainLoop()
<|endoftext|>


<commit_before>import logging
import re
import simplejson as json

from google.appengine.api import memcache
import yaml

from dropbox_client import get_client

# Dropbox API endpoints
path_url = 'https://api-content.dropbox.com/1/files/sandbox' # don't add a `/`!
metadata_url = 'https://api.dropbox.com/1/metadata/sandbox/'

# Get a dropbox client (pickled)
client = get_client()

# helper to download a RESTFUL endpoint with the GET method.
get = lambda x: client.request(x, 'GET')[1]

# A sorting function for posts. Sorts by filename.
path_fun = lambda x: x['path']

def get_posts(sort_key=path_fun):
  '''Returns posts as a sorted dictionary.

      TODO: add caching

  '''
  url = ''.join((metadata_url, 'posts'))
  logging.info('url is: %s' % url)

  return sorted(
    json.loads(get(url)).get('contents', {}),
    key=sort_key
  )

def get_post_front_matter(file_str, overwrite=False):
  '''Helper function which turns the front-matter of a post into YAML

    *e.g.*

      Title: This is a title         title: This is a title
      Author: This is an author  =>  author: This is an author
      Time: 123456789                time: 123456789

      My great post starts here              ||
                                            \\//

                                      {'title': 'This is a title',
                                        'author': 'This is an author',
                                        'time': 123456789
                                      }
  '''
  file_str = split_file(
    get_post(
      file_str,
      overwrite=overwrite
    ))

  return dict([
    (key.lower(), val) for key, val
      in yaml.load(file_str[0]).iteritems()
  ])

def sort_time(obj):
  '''Used as a sorting function which returns a post's time: header vlaue

  Side effect: Reads a post to determine its date.

  '''
  obj = obj.get('path')
  result = split_file(obj)

  frontmatter = get_post_front_matter(result[0])

  found_time = frontmatter['time']

  logging.info('time: %s' % found_time)
  return int(found_time)

def get_posts_time(**kw):
  '''Sort posts by time header'''

  kw.update({'sort_key': sort_time})
  return get_posts(**kw)

def get_post_no(no, **kw):
  '''Gets post based off of index number'''

  post = get_posts_time()[int(no)]['path']
  logging.info('getting post: %s' % post)
  return get_post(post, **kw)

def get_item(path, overwrite=False):
  assert isinstance(path, basestring), 'Expected path to be a string'

  prefix = 'file_'
  key = ''.join((prefix, path))

  fileObj = memcache.get(key)

  if not fileObj or overwrite:
    logging.info('flushing cache for obj: %s' % path)
    fileObj = get(''.join((path_url, path))).decode('ascii', 'ignore')

    result = False
    while not result:
      result = memcache.set(key, fileObj)

  return fileObj

def split_file(file_str):
  result = re.split(r'\n\n', file_str)
  return (result[0], '\n\n'.join(result[1:]))

def get_post(path, **kw):
  return get_item(path, **kw)

def get_header(**kw):
  header = get_item('/templates/header.html', **kw)
  return header

def get_footer(**kw):
  return get_item('/templates/footer.html', **kw)

def get_posts_html(**kw):
  return get_item('/templates/posts.html', **kw)

def get_index(**kw):
  return get_item('/templates/index.html', **kw)
<commit_msg>dropbox conflicted copies really suck.  let's ignore them.<commit_after>import logging
import re
import simplejson as json

from google.appengine.api import memcache
import yaml

from dropbox_client import get_client

# Dropbox API endpoints
path_url = 'https://api-content.dropbox.com/1/files/sandbox' # don't add a `/`!
metadata_url = 'https://api.dropbox.com/1/metadata/sandbox/'

# Get a dropbox client (pickled)
client = get_client()

# helper to download a RESTFUL endpoint with the GET method.
get = lambda x: client.request(x, 'GET')[1]

# A sorting function for posts. Sorts by filename.
path_fun = lambda x: x['path']

def get_posts(sort_key=path_fun):
  '''Returns posts as a sorted list.

      TODO: add caching

  '''
  url = ''.join((metadata_url, 'posts'))
  logging.info('url is: %s' % url)

  # Fuck conflicted copies. They fuck shit up.
  posts = json.loads(get(url)).get('contents', {})
  posts = filter(lambda x: 'conflicted copy' not in x.get('path'), posts)

  return sorted(posts, key=sort_key)

def get_post_front_matter(file_str, overwrite=False):
  '''Helper function which turns the front-matter of a post into YAML

    *e.g.*

      Title: This is a title         title: This is a title
      Author: This is an author  =>  author: This is an author
      Time: 123456789                time: 123456789

      My great post starts here              ||
                                            \\//

                                      {'title': 'This is a title',
                                        'author': 'This is an author',
                                        'time': 123456789
                                      }
  '''
  file_str = split_file(
    get_post(
      file_str,
      overwrite=overwrite
    ))
  front_matter = yaml.load(file_str[0]) or {}
  return dict([
    (key.lower(), val) for key, val
      in front_matter.iteritems()
  ])

def sort_time(obj):
  '''Used as a sorting function which returns a post's time: header vlaue

  Side effect: Reads a post to determine its date.

  '''
  obj = obj.get('path')
  result = split_file(obj)

  frontmatter = get_post_front_matter(result[0])

  found_time = frontmatter['time']

  logging.info('time: %s' % found_time)
  return int(found_time)

def get_posts_time(**kw):
  '''Sort posts by time header'''

  kw.update({'sort_key': sort_time})
  return get_posts(**kw)

def get_post_no(no, **kw):
  '''Gets post based off of index number'''

  post = get_posts_time()[int(no)]['path']
  logging.info('getting post: %s' % post)
  return get_post(post, **kw)

def get_item(path, overwrite=False):
  assert isinstance(path, basestring), 'Expected path to be a string'

  assert 'conflicted copy' not in path, \
    'An attempt to fetch a conflicted copy of a file was made'

  prefix = 'file_'
  key = ''.join((prefix, path))

  fileObj = memcache.get(key)

  if not fileObj or overwrite:
    logging.info('flushing cache for obj: %s' % path)
    fileObj = get(''.join((path_url, path))).decode('ascii', 'ignore')

    result = False
    while not result:
      result = memcache.set(key, fileObj)

  return fileObj

def split_file(file_str):
  result = re.split(r'\n\n', file_str)
  return (result[0], '\n\n'.join(result[1:]))

def get_post(path, **kw):
  return get_item(path, **kw)

def get_header(**kw):
  header = get_item('/templates/header.html', **kw)
  return header

def get_footer(**kw):
  return get_item('/templates/footer.html', **kw)

def get_posts_html(**kw):
  return get_item('/templates/posts.html', **kw)

def get_index(**kw):
  return get_item('/templates/index.html', **kw)
<|endoftext|>


<commit_before>from __future__ import absolute_import, division, print_function, unicode_literals

import pymor.core as core
from .defaultimpl import *  # NOQA

class IConformalTopologicalGrid(IConformalTopologicalGridDefaultImplementation, core.BasicInterface):
    '''desribes a conformal topological grid. The grid is determined via the subentity
    relation given by `subentities(codim, subentity_codim)`.

    All results in the default implementations are cached for the next evaluation
    using functools.lru_cache. Note that the current implementation is very slow
    and should be moved to C code.
    For ``g = pymor.grid.rect.Rect((1000, 1000))`` it takes around 5
    minutes on modern hardware to calculate ``g.neighbours(0, 1, 2)``.
    (The call involves calculating ``g.subentities(0, 2)``, ``g.subentities(1,2)``,
    ``g.superentities(1,0)``, ``g.superentities(2, 1)`` and ``g.superentity_indices(1,0)``
    at the same time.)

    **dim**
        the dimension of the grid
    '''

    @core.interfaces.abstractmethod
    def size(self, codim):
        '''the number of entities in the grid of codimension `codim`'''
        pass

    @core.interfaces.abstractmethod
    def subentities(self, codim, subentity_codim=None):
        '''`retval[e,s]` is the global index of the `s`-th codim-`subentity_codim`
        subentity of the codim-`codim` entity with global index `e`.

        If `subentity_codim == None`, it is set to `codim + 1`.

        Only `subentities(codim, None)` has to be implemented; by default,
        `subentities(codim, subentity_codim)` is computed by calculating the
        transitive closure of `subentities(codim, None)`
        '''
        return self._subentities(codim, subentity_codim)

    def superentities(self, codim, superentity_codim=None):
        '''`retval[e,s]` is the global index of the `s`-th codim-`superentity_codim`
        superentity of the codim-`codim` entity with global index `e`.
        `retval[e]` is sorted by global index.

        If `superentity_codim == None`, it is set to `codim - 1`.

        The default implementation is to compute the result from
        `subentities(superentity_codim, codim)`
        '''
        return self._superentities(codim, superentity_codim)

    def superentity_indices(self, codim, superentity_codim=None):
        '''`retval[e,s]` is the local index of the codim-`codim` entity `e`
        in the codim-`superentity_codim` superentity
        `superentities(codim, superentity_codim)[e,s].`
        '''
        return self._superentity_indices(codim, superentity_codim)

    def neighbours(self, codim, neighbour_codim, intersection_codim=None):
        '''`retval[e,n]` is the global index of the `n`-th codim-`neighbour_codim`
        entitiy of the codim-`codim` entity `e` that shares
        with `e` a subentity of codimension `intersection_codim`.

        If `intersection_codim == None`, it is set to
            `codim` if `codim == neighbour_codim` and to
            `min(codim, neighbour_codim)` otherwise.

        The default implementation is to compute the result from
        `subentities(codim, intersection_codim)` and
        `superentities(intersection_codim, neihbour_codim)`.
        '''
        return self._neighbours(codim, neighbour_codim, intersection_codim)

class ISimpleReferenceElement(ISimpleReferenceElementDefaultImplementation, core.BasicInterface):
    '''defines a reference element with the property that each of its subentities is
    of the same type. I.e. a three-dimensional reference element cannot have triangles
    and rectangles as faces at the same time.

    **dim**
        the dimension of the reference element
    **volume**
        the volume of the reference element
    '''

    dim = None
    volume = None

    @core.interfaces.abstractmethod
    def size(self, codim):
        'number of subentites of codimension `codim`'

    @core.interfaces.abstractmethod
    def subentities(self, codim, subentity_codim):
        '''`subentities(c,sc)[i,j]` is, with respect to the indexing inside the
        reference element, the index of the `j`-th codim-`subentity_codim`
        subentity of the `i`-th codim-`codim` subentity of the reference element.
        '''
        pass

    @core.interfaces.abstractmethod
    def subentity_embedding(self, subentity_codim):
        '''returns a tuple `(A, B)` which defines the embedding of the codim-`subentity_codim`
        subentities into the reference element.

        For `subentity_codim > 1', the embedding is by default given recursively via
        `subentity_embedding(subentity_codim - 1)` and
        `sub_reference_element(subentity_codim - 1).subentity_embedding(1)` choosing always
        the superentity with smallest index.
        '''
        return self._subentity_embedding(subentity_codim)

    @core.interfaces.abstractmethod
    def sub_reference_element(self, codim):
        '''returns the reference relement of the codim-`codim` subentities.'''
        return self._sub_reference_element(codim)

    def __call__(self, codim):
        '''returns the reference relement of the codim-`codim` subentities.'''
        return self.sub_reference_element(codim)

    @core.interfaces.abstractmethod
    def unit_outer_normals(self):
        '''`retval[e]` is the unit outer-normal vector to the codim-1 subentity
        with index `e`.
        '''
        pass

    @core.interfaces.abstractmethod
    def center(self):
        '''coordinates of the barycenter.'''
        pass

    @core.interfaces.abstractmethod
    def mapped_diameter(self, A):
        '''the diameter of the reference element after tranforming it with the
        matrix `A` (vectorized).
        '''
        pass

    @core.interfaces.abstractmethod
    def quadrature(order=None, npoints=None, quadrature_type='default'):
        '''returns tuple `(P, W)` where P is an array of quadrature points with
        corresponding weights `W`.

        The quadrature is of order `order` or has `npoints` integration points.
        '''
        pass

class ISimpleAffineGrid(ISimpleAffineGridDefaultImplementation, IConformalTopologicalGrid):
    '''describes a geometric grid where each codim-0 entity has the same
    `ISimpleReferenceElement` reference element to which it is affinely
    mapped.

    **dim_outer**
        the dimension of the space into which the grid is embedded
    '''

    dim_outer = None

    @core.interfaces.abstractmethod
    def reference_element(self, codim):
        '''the reference element of all codim-`codim` entities.'''
        pass

    def subentities(self, codim, subentity_codim=None):
        '''`retval[e,s]` is the global index of the `s`-th codim-`subentity_codim`
        subentity of the codim-`codim` entity with global index `e`. The ordering
        of subentities(0, subentity_codim)[e] has to correspond under the
        embedding of `e` with the local ordering inside the reference element.

        If `subentity_codim == None`, it is set to `codim + 1`.

        If `codim > 0`, we calculate the subentites of `e` by default as follows:

        1. Find the codim-0 parent entity `e_0` of `e` with minimal global index
        2. Lookup the local indicies of the subentites of `e` inside `e_0` using the reference element.
        3. Map these local indicies to global indicies using `subentities(0, subentity_codim)`.

        This procedures assures that `subentities(codim, subentity_codim)[e]`
        has the right ordering w.r.t. the embedding determined by `e_0`, which
        agrees with what is returned by `embeddings(codim)`
        '''
        return self._subentities(codim, subentity_codim)

    def embeddings(self, codim):
        '''`returns tuple `(A, B)` where `A[e]` and `B[e]` are the linear part
        and the translation part of the map from the reference element of `e`
        to `e`.

        For `codim > 0` the map is determined by the embedding of the codim-1
        parent entity `e_0` of `e` with lowest global index and by the
        subentity_embedding of `e` into `e_0` determined by the reference
        element.
        '''
        return self._embeddings(codim)

    def jacobian_inverse_transposed(self, codim):
        '''`retval[e]` is the transposed (pseudo-)inverse of the jacobian
        of `embeddings(codim)[e].`
        '''
        return self._jacobian_inverse_transposed(codim)

    def integration_element(self, codim):
        '''`retval[e]` is given as `sqrt(det(A^T*A))`, where
        `A = embeddings(codim)[0][e]`.
        '''
        return self._integration_element(codim)

    def volumes(self, codim):
        '''`retval[e]` is the (dim-codim)-dimensional volume of the
        codim-`codim` entity with global index `e`.
        '''
        return self._volumes(codim)

    def volumes_inverse(self, codim):
        '''`retval[e] = 1 / volumes(codim)[e]`.
        '''
        return self._volumes_inverse(codim)

    def unit_outer_normals(self):
        '''`retval[e]` is the unit outer-normal vector to the codim-1 subentity
        with global index `e`.
        '''
        return self._unit_outer_normals()

    def centers(self, codim):
        '''`retval[e]` is the barycenter of the codim-`codim` entity with global
        index `e`.
        '''
        return self._centers(codim)

    def diameters(self, codim):
        '''`retval[e]` is the diameter of the codim-`codim` entity with global
        index `e`.
        '''
        return self._diameters(codim)

    def quadrature_points(self, codim, order=None, npoints=None, quadrature_type='default'):
        '''`retval[e]` is an array of quadrature points in global coordinates
        for the codim-`codim` entity with global index `e`.

        The quadrature is of order `order` or has `npoints` integration points. To
        integrate a function `f` over `e` one has to form

        ``np.dot(f(quadrature_points(codim, order)[e]), reference_element(codim).quadrature(order)[1]) * integration_element(codim)[e]``.  # NOPEP8
        '''
        return self._quadrature_points(codim, order, npoints, quadrature_type)
<commit_msg>[grid.interfaces] made subentites/embeddings abstract again<commit_after>from __future__ import absolute_import, division, print_function, unicode_literals

import pymor.core as core
from .defaultimpl import *  # NOQA

class IConformalTopologicalGrid(IConformalTopologicalGridDefaultImplementation, core.BasicInterface):
    '''desribes a conformal topological grid. The grid is determined via the subentity
    relation given by `subentities(codim, subentity_codim)`.

    All results in the default implementations are cached for the next evaluation
    using functools.lru_cache. Note that the current implementation is very slow
    and should be moved to C code.
    For ``g = pymor.grid.rect.Rect((1000, 1000))`` it takes around 5
    minutes on modern hardware to calculate ``g.neighbours(0, 1, 2)``.
    (The call involves calculating ``g.subentities(0, 2)``, ``g.subentities(1,2)``,
    ``g.superentities(1,0)``, ``g.superentities(2, 1)`` and ``g.superentity_indices(1,0)``
    at the same time.)

    **dim**
        the dimension of the grid
    '''

    @core.interfaces.abstractmethod
    def size(self, codim):
        '''the number of entities in the grid of codimension `codim`'''
        pass

    @core.interfaces.abstractmethod
    def subentities(self, codim, subentity_codim=None):
        '''`retval[e,s]` is the global index of the `s`-th codim-`subentity_codim`
        subentity of the codim-`codim` entity with global index `e`.

        If `subentity_codim == None`, it is set to `codim + 1`.

        Only `subentities(codim, None)` has to be implemented; by default,
        `subentities(codim, subentity_codim)` is computed by calculating the
        transitive closure of `subentities(codim, None)`
        '''
        return self._subentities(codim, subentity_codim)

    def superentities(self, codim, superentity_codim=None):
        '''`retval[e,s]` is the global index of the `s`-th codim-`superentity_codim`
        superentity of the codim-`codim` entity with global index `e`.
        `retval[e]` is sorted by global index.

        If `superentity_codim == None`, it is set to `codim - 1`.

        The default implementation is to compute the result from
        `subentities(superentity_codim, codim)`
        '''
        return self._superentities(codim, superentity_codim)

    def superentity_indices(self, codim, superentity_codim=None):
        '''`retval[e,s]` is the local index of the codim-`codim` entity `e`
        in the codim-`superentity_codim` superentity
        `superentities(codim, superentity_codim)[e,s].`
        '''
        return self._superentity_indices(codim, superentity_codim)

    def neighbours(self, codim, neighbour_codim, intersection_codim=None):
        '''`retval[e,n]` is the global index of the `n`-th codim-`neighbour_codim`
        entitiy of the codim-`codim` entity `e` that shares
        with `e` a subentity of codimension `intersection_codim`.

        If `intersection_codim == None`, it is set to
            `codim` if `codim == neighbour_codim` and to
            `min(codim, neighbour_codim)` otherwise.

        The default implementation is to compute the result from
        `subentities(codim, intersection_codim)` and
        `superentities(intersection_codim, neihbour_codim)`.
        '''
        return self._neighbours(codim, neighbour_codim, intersection_codim)

class ISimpleReferenceElement(ISimpleReferenceElementDefaultImplementation, core.BasicInterface):
    '''defines a reference element with the property that each of its subentities is
    of the same type. I.e. a three-dimensional reference element cannot have triangles
    and rectangles as faces at the same time.

    **dim**
        the dimension of the reference element
    **volume**
        the volume of the reference element
    '''

    dim = None
    volume = None

    @core.interfaces.abstractmethod
    def size(self, codim):
        'number of subentites of codimension `codim`'

    @core.interfaces.abstractmethod
    def subentities(self, codim, subentity_codim):
        '''`subentities(c,sc)[i,j]` is, with respect to the indexing inside the
        reference element, the index of the `j`-th codim-`subentity_codim`
        subentity of the `i`-th codim-`codim` subentity of the reference element.
        '''
        pass

    @core.interfaces.abstractmethod
    def subentity_embedding(self, subentity_codim):
        '''returns a tuple `(A, B)` which defines the embedding of the codim-`subentity_codim`
        subentities into the reference element.

        For `subentity_codim > 1', the embedding is by default given recursively via
        `subentity_embedding(subentity_codim - 1)` and
        `sub_reference_element(subentity_codim - 1).subentity_embedding(1)` choosing always
        the superentity with smallest index.
        '''
        return self._subentity_embedding(subentity_codim)

    @core.interfaces.abstractmethod
    def sub_reference_element(self, codim):
        '''returns the reference relement of the codim-`codim` subentities.'''
        return self._sub_reference_element(codim)

    def __call__(self, codim):
        '''returns the reference relement of the codim-`codim` subentities.'''
        return self.sub_reference_element(codim)

    @core.interfaces.abstractmethod
    def unit_outer_normals(self):
        '''`retval[e]` is the unit outer-normal vector to the codim-1 subentity
        with index `e`.
        '''
        pass

    @core.interfaces.abstractmethod
    def center(self):
        '''coordinates of the barycenter.'''
        pass

    @core.interfaces.abstractmethod
    def mapped_diameter(self, A):
        '''the diameter of the reference element after tranforming it with the
        matrix `A` (vectorized).
        '''
        pass

    @core.interfaces.abstractmethod
    def quadrature(order=None, npoints=None, quadrature_type='default'):
        '''returns tuple `(P, W)` where P is an array of quadrature points with
        corresponding weights `W`.

        The quadrature is of order `order` or has `npoints` integration points.
        '''
        pass

class ISimpleAffineGrid(ISimpleAffineGridDefaultImplementation, IConformalTopologicalGrid):
    '''describes a geometric grid where each codim-0 entity has the same
    `ISimpleReferenceElement` reference element to which it is affinely
    mapped.

    **dim_outer**
        the dimension of the space into which the grid is embedded
    '''

    dim_outer = None

    @core.interfaces.abstractmethod
    def reference_element(self, codim):
        '''the reference element of all codim-`codim` entities.'''
        pass

    @core.interfaces.abstractmethod
    def subentities(self, codim, subentity_codim=None):
        '''`retval[e,s]` is the global index of the `s`-th codim-`subentity_codim`
        subentity of the codim-`codim` entity with global index `e`. The ordering
        of subentities(0, subentity_codim)[e] has to correspond under the
        embedding of `e` with the local ordering inside the reference element.

        If `subentity_codim == None`, it is set to `codim + 1`.

        For `codim > 0`, we provide a default implementation by calculating the
        subentites of `e` as follows:

        1. Find the codim-0 parent entity `e_0` of `e` with minimal global index
        2. Lookup the local indicies of the subentites of `e` inside `e_0` using the reference element.
        3. Map these local indicies to global indicies using `subentities(0, subentity_codim)`.

        This procedures assures that `subentities(codim, subentity_codim)[e]`
        has the right ordering w.r.t. the embedding determined by `e_0`, which
        agrees with what is returned by `embeddings(codim)`
        '''
        return self._subentities(codim, subentity_codim)

    @core.interfaces.abstractmethod
    def embeddings(self, codim):
        '''`returns tuple `(A, B)` where `A[e]` and `B[e]` are the linear part
        and the translation part of the map from the reference element of `e`
        to `e`.

        For `codim > 0`, we provide a default implementation by
        taking the embedding of the codim-1 parent entity `e_0` of `e` with
        lowest global index and composing it with the subentity_embedding of `e`
        into `e_0` determined by the reference element.
        '''
        return self._embeddings(codim)

    def jacobian_inverse_transposed(self, codim):
        '''`retval[e]` is the transposed (pseudo-)inverse of the jacobian
        of `embeddings(codim)[e].`
        '''
        return self._jacobian_inverse_transposed(codim)

    def integration_element(self, codim):
        '''`retval[e]` is given as `sqrt(det(A^T*A))`, where
        `A = embeddings(codim)[0][e]`.
        '''
        return self._integration_element(codim)

    def volumes(self, codim):
        '''`retval[e]` is the (dim-codim)-dimensional volume of the
        codim-`codim` entity with global index `e`.
        '''
        return self._volumes(codim)

    def volumes_inverse(self, codim):
        '''`retval[e] = 1 / volumes(codim)[e]`.
        '''
        return self._volumes_inverse(codim)

    def unit_outer_normals(self):
        '''`retval[e]` is the unit outer-normal vector to the codim-1 subentity
        with global index `e`.
        '''
        return self._unit_outer_normals()

    def centers(self, codim):
        '''`retval[e]` is the barycenter of the codim-`codim` entity with global
        index `e`.
        '''
        return self._centers(codim)

    def diameters(self, codim):
        '''`retval[e]` is the diameter of the codim-`codim` entity with global
        index `e`.
        '''
        return self._diameters(codim)

    def quadrature_points(self, codim, order=None, npoints=None, quadrature_type='default'):
        '''`retval[e]` is an array of quadrature points in global coordinates
        for the codim-`codim` entity with global index `e`.

        The quadrature is of order `order` or has `npoints` integration points. To
        integrate a function `f` over `e` one has to form

        ``np.dot(f(quadrature_points(codim, order)[e]), reference_element(codim).quadrature(order)[1]) * integration_element(codim)[e]``.  # NOPEP8
        '''
        return self._quadrature_points(codim, order, npoints, quadrature_type)
<|endoftext|>


<commit_before>import re, time
from Popen_noblock import Popen_async, PIPE, STDOUT, Empty

__all__ = ["join_definitions", "split_statements_to_definitions"]

DEFAULT_VERBOSITY=1

def DEFAULT_LOG(text):
    print(text)

def get_all_nowait_iter(q):
    try:
        while True:
            yield q.get_nowait()
    except Empty:
        pass

def get_all_nowait(q):
    return ''.join(get_all_nowait_iter(q))

def get_all_semiwait_iter(q, verbose=DEFAULT_VERBOSITY, log=DEFAULT_LOG):
    def log_and_return(val):
        if verbose >= 5:
            log(val)
        return val
    try:
        # this is blocking; TODO(jgross): Figure out how to get coqtop
        # to tell us if it's finished computing
        yield log_and_return(q.get(True))
        while True:
            yield log_and_return(q.get(True, 0.1))
    except Empty:
        pass

def get_all_semiwait(q, verbose=DEFAULT_VERBOSITY, log=DEFAULT_LOG):
    return ''.join(get_all_semiwait_iter(q, verbose=verbose, log=log))

def get_definitions_diff(previous_definition_string, new_definition_string):
    """Returns a triple of lists (definitions_removed,
    definitions_shared, definitions_added)"""
    old_definitions = [i for i in previous_definition_string.split('|') if i]
    new_definitions = [i for i in new_definition_string.split('|') if i]
    return (tuple(i for i in old_definitions if i not in new_definitions),
            tuple(i for i in old_definitions if i in new_definitions),
            tuple(i for i in new_definitions if i not in old_definitions))

#def split_coq_code_to_definitions(code, verbose=1, log=DEFAULT_LOG, coqtop='coqtop'):
#    """Splits coq code into chunks which make up
#    independent definitions/hints/etc, of the form
#
#    {
#     'statements': <list of runnable statements>,
#     'statement':  <entire chunk of code>,
#     'terms_defined': <tuple of terms defined by this chunk of code>,
#     'times': <a list of times for each statement>
#     'output': <a string of the response from coqtop>
#    }"""
#    p = Popen_async([coqtop, '-emacs', '-time'], stdout=PIPE, stderr=STDOUT, stdin=PIPE)
#    time.sleep(1)

def split_statements_to_definitions(statements, verbose=DEFAULT_VERBOSITY, log=DEFAULT_LOG, coqtop='coqtop', coqtop_args=tuple()):
    """Splits a list of statements into chunks which make up
    independent definitions/hints/etc."""
    p = Popen_async([coqtop, '-emacs'] + list(coqtop_args), stdout=PIPE, stderr=STDOUT, stdin=PIPE)
    time.sleep(1)
    prompt_reg = re.compile(r'<prompt>([^<]*?) < ([0-9]+) ([^<]*?) ([0-9]+) < ([^<]*?)</prompt>'.replace(' ', r'\s*'))
    defined_reg = re.compile(r'^([^\s]+) is (?:defined|assumed)$', re.MULTILINE)
    # aborted_reg = re.compile(r'^Current goal aborted$', re.MULTILINE)
    # goal_reg = re.compile(r'^\s*=+\s*$', re.MULTILINE)
    # goals and definitions are on stdout, prompts are on stderr
    # clear stdout
    get_all_semiwait(p.stdout, verbose=verbose, log=log)
    # clear stderr
    # get_all_nowait(p.stderr)

    rtn = []
    cur_definition = {}
    last_definitions = '||'
    cur_definition_names = '||'
    for statement in statements:
        if not statement.strip():
            continue
        if verbose >= 4:
            log('Write: %s\n\nWait to read...' % statement)
        p.stdin.write(statement + '\n\n')
        stdout = get_all_semiwait(p.stdout, verbose=verbose, log=log)
        stderr = stdout # ''.join(get_all_semiwait(p.stderr))

        terms_defined = defined_reg.findall(prompt_reg.sub('', stdout))
        # print((statement, stdout, terms_defined))
        prompt_match = prompt_reg.search(stderr)

        if not prompt_match or len(prompt_match.groups()) != 5:
            if not prompt_match:
                if verbose:
                    log('Likely fatal warning: I did not recognize the output from coqtop:')
                    log('stdout: %s\nstderr: %s' % (repr(stdout), repr(stderr)))
                    log("I will append the current statement (%s) to the list of definitions as-is, but I don't expect this to work." % statement)
            else:
                if verbose:
                    log("Crazy things are happening; the number of groups isn't what it should be (should be 5 groups):")
                    log("prompt_match.groups(): %s\nstdout: %s\nstderr: %s\nstatement: %s\n" % (repr(prompt_match.groups()), repr(stdout), repr(stderr), repr(statement)))

            if verbose >= 2: log((statement, terms_defined, cur_definition_names, cur_definition.get(cur_definition_names, [])))
            if cur_definition_names.strip('|'):
                cur_definition[cur_definition_names]['statements'].append(statement)
                cur_definition[cur_definition_names]['terms_defined'] += terms_defined
            else:
                rtn.append({'statements':(statement,),
                            'statement':statement,
                            'terms_defined':tuple(terms_defined)})
        else:
            cur_name, line_num1, cur_definition_names, line_num2, unknown = prompt_reg.search(stderr).groups()
            definitions_removed, definitions_shared, definitions_added = get_definitions_diff(last_definitions, cur_definition_names)

            # first, to be on the safe side, we add the new
            # definitions key to the dict, if it wasn't already there.
            if cur_definition_names.strip('|') and cur_definition_names not in cur_definition:
                cur_definition[cur_definition_names] = {'statements':[], 'terms_defined':[]}

            if verbose >= 2: log((statement, terms_defined, last_definitions, cur_definition_names, cur_definition.get(last_definitions, []), cur_definition.get(cur_definition_names, [])))

            # first, we handle the case where we have just finished
            # defining something.  This should correspond to
            # len(definitions_removed) > 0 and len(terms_defined) > 0.
            # If only len(definitions_removed) > 0, then we have
            # aborted something.  If only len(terms_defined) > 0, then
            # we have defined something with a one-liner.
            if definitions_removed:
                cur_definition[last_definitions]['statements'].append(statement)
                cur_definition[last_definitions]['terms_defined'] += terms_defined
                if cur_definition_names.strip('|'):
                    # we are still inside a definition.  For now, we
                    # flatten all definitions.
                    #
                    # TODO(jgross): Come up with a better story for
                    # nested definitions.
                    cur_definition[cur_definition_names]['statements'] += cur_definition[last_definitions]['statements']
                    cur_definition[cur_definition_names]['terms_defined'] += cur_definition[last_definitions]['terms_defined']
                    del cur_definition[last_definitions]
                else:
                    # we're at top-level, so add this as a new
                    # definition
                    rtn.append({'statements':tuple(cur_definition[last_definitions]['statements']),
                                'statement':'\n'.join(cur_definition[last_definitions]['statements']),
                                'terms_defined':tuple(cur_definition[last_definitions]['terms_defined'])})
                    del cur_definition[last_definitions]
                    #print('Adding:')
                    #print(rtn[-1])
            elif terms_defined:
                if cur_definition_names.strip('|'):
                    # we are still inside a definition.  For now, we
                    # flatten all definitions.
                    #
                    # TODO(jgross): Come up with a better story for
                    # nested definitions.
                    cur_definition[cur_definition_names]['statements'].append(statement)
                    cur_definition[cur_definition_names]['terms_defined'] += terms_defined
                else:
                    # we're at top level, so add this as a new
                    # definition
                    rtn.append({'statements':(statement,),
                                'statement':statement,
                                'terms_defined':tuple(terms_defined)})

            # now we handle the case where we have just opened a fresh
            # definition.  We've already added the key to the
            # dictionary.
            elif definitions_added:
                #print(definitions_added)
                cur_definition[cur_definition_names]['statements'].append(statement)
            else:
                # if we're in a definition, append the statement to
                # the queue, otherwise, just add it as it's own
                # statement
                if cur_definition_names.strip('|'):
                    cur_definition[cur_definition_names]['statements'].append(statement)
                else:
                    rtn.append({'statements':(statement,),
                                'statement':statement,
                                'terms_defined':tuple()})
        last_definitions = cur_definition_names

    if verbose >= 2: log((last_definitions, cur_definition_names))
    if last_definitions.strip('||'):
        rtn.append({'statements':tuple(cur_definition[cur_definition_names]['statements']),
                    'statement':'\n'.join(cur_definition[cur_definition_names]['statements']),
                    'terms_defined':tuple(cur_definition[cur_definition_names]['terms_defined'])})
        del cur_definition[last_definitions]
    #for i in rtn:
        #print(i)
    p.stdin.close()
    return rtn

def join_definitions(definitions):
    return '\n'.join(i['statement'] for i in definitions)
<commit_msg>We need to manually flush stdin on windows<commit_after>import re, time
from Popen_noblock import Popen_async, PIPE, STDOUT, Empty

__all__ = ["join_definitions", "split_statements_to_definitions"]

DEFAULT_VERBOSITY=1

def DEFAULT_LOG(text):
    print(text)

def get_all_nowait_iter(q):
    try:
        while True:
            yield q.get_nowait()
    except Empty:
        pass

def get_all_nowait(q):
    return ''.join(get_all_nowait_iter(q))

def get_all_semiwait_iter(q, verbose=DEFAULT_VERBOSITY, log=DEFAULT_LOG):
    def log_and_return(val):
        if verbose >= 5:
            log(val)
        return val
    try:
        # this is blocking; TODO(jgross): Figure out how to get coqtop
        # to tell us if it's finished computing
        yield log_and_return(q.get(True))
        while True:
            yield log_and_return(q.get(True, 0.1))
    except Empty:
        pass

def get_all_semiwait(q, verbose=DEFAULT_VERBOSITY, log=DEFAULT_LOG):
    return ''.join(get_all_semiwait_iter(q, verbose=verbose, log=log))

def get_definitions_diff(previous_definition_string, new_definition_string):
    """Returns a triple of lists (definitions_removed,
    definitions_shared, definitions_added)"""
    old_definitions = [i for i in previous_definition_string.split('|') if i]
    new_definitions = [i for i in new_definition_string.split('|') if i]
    return (tuple(i for i in old_definitions if i not in new_definitions),
            tuple(i for i in old_definitions if i in new_definitions),
            tuple(i for i in new_definitions if i not in old_definitions))

#def split_coq_code_to_definitions(code, verbose=1, log=DEFAULT_LOG, coqtop='coqtop'):
#    """Splits coq code into chunks which make up
#    independent definitions/hints/etc, of the form
#
#    {
#     'statements': <list of runnable statements>,
#     'statement':  <entire chunk of code>,
#     'terms_defined': <tuple of terms defined by this chunk of code>,
#     'times': <a list of times for each statement>
#     'output': <a string of the response from coqtop>
#    }"""
#    p = Popen_async([coqtop, '-emacs', '-time'], stdout=PIPE, stderr=STDOUT, stdin=PIPE)
#    time.sleep(1)

def split_statements_to_definitions(statements, verbose=DEFAULT_VERBOSITY, log=DEFAULT_LOG, coqtop='coqtop', coqtop_args=tuple()):
    """Splits a list of statements into chunks which make up
    independent definitions/hints/etc."""
    p = Popen_async([coqtop, '-emacs'] + list(coqtop_args), stdout=PIPE, stderr=STDOUT, stdin=PIPE)
    time.sleep(1)
    prompt_reg = re.compile(r'<prompt>([^<]*?) < ([0-9]+) ([^<]*?) ([0-9]+) < ([^<]*?)</prompt>'.replace(' ', r'\s*'))
    defined_reg = re.compile(r'^([^\s]+) is (?:defined|assumed)$', re.MULTILINE)
    # aborted_reg = re.compile(r'^Current goal aborted$', re.MULTILINE)
    # goal_reg = re.compile(r'^\s*=+\s*$', re.MULTILINE)
    # goals and definitions are on stdout, prompts are on stderr
    # clear stdout
    get_all_semiwait(p.stdout, verbose=verbose, log=log)
    # clear stderr
    # get_all_nowait(p.stderr)

    rtn = []
    cur_definition = {}
    last_definitions = '||'
    cur_definition_names = '||'
    for statement in statements:
        if not statement.strip():
            continue
        if verbose >= 4:
            log('Write: %s\n\nWait to read...' % statement)
        p.stdin.write(statement + '\n\n')
        p.stdin.flush()
        stdout = get_all_semiwait(p.stdout, verbose=verbose, log=log)
        stderr = stdout # ''.join(get_all_semiwait(p.stderr))

        terms_defined = defined_reg.findall(prompt_reg.sub('', stdout))
        # print((statement, stdout, terms_defined))
        prompt_match = prompt_reg.search(stderr)

        if not prompt_match or len(prompt_match.groups()) != 5:
            if not prompt_match:
                if verbose:
                    log('Likely fatal warning: I did not recognize the output from coqtop:')
                    log('stdout: %s\nstderr: %s' % (repr(stdout), repr(stderr)))
                    log("I will append the current statement (%s) to the list of definitions as-is, but I don't expect this to work." % statement)
            else:
                if verbose:
                    log("Crazy things are happening; the number of groups isn't what it should be (should be 5 groups):")
                    log("prompt_match.groups(): %s\nstdout: %s\nstderr: %s\nstatement: %s\n" % (repr(prompt_match.groups()), repr(stdout), repr(stderr), repr(statement)))

            if verbose >= 2: log((statement, terms_defined, cur_definition_names, cur_definition.get(cur_definition_names, [])))
            if cur_definition_names.strip('|'):
                cur_definition[cur_definition_names]['statements'].append(statement)
                cur_definition[cur_definition_names]['terms_defined'] += terms_defined
            else:
                rtn.append({'statements':(statement,),
                            'statement':statement,
                            'terms_defined':tuple(terms_defined)})
        else:
            cur_name, line_num1, cur_definition_names, line_num2, unknown = prompt_reg.search(stderr).groups()
            definitions_removed, definitions_shared, definitions_added = get_definitions_diff(last_definitions, cur_definition_names)

            # first, to be on the safe side, we add the new
            # definitions key to the dict, if it wasn't already there.
            if cur_definition_names.strip('|') and cur_definition_names not in cur_definition:
                cur_definition[cur_definition_names] = {'statements':[], 'terms_defined':[]}

            if verbose >= 2: log((statement, terms_defined, last_definitions, cur_definition_names, cur_definition.get(last_definitions, []), cur_definition.get(cur_definition_names, [])))

            # first, we handle the case where we have just finished
            # defining something.  This should correspond to
            # len(definitions_removed) > 0 and len(terms_defined) > 0.
            # If only len(definitions_removed) > 0, then we have
            # aborted something.  If only len(terms_defined) > 0, then
            # we have defined something with a one-liner.
            if definitions_removed:
                cur_definition[last_definitions]['statements'].append(statement)
                cur_definition[last_definitions]['terms_defined'] += terms_defined
                if cur_definition_names.strip('|'):
                    # we are still inside a definition.  For now, we
                    # flatten all definitions.
                    #
                    # TODO(jgross): Come up with a better story for
                    # nested definitions.
                    cur_definition[cur_definition_names]['statements'] += cur_definition[last_definitions]['statements']
                    cur_definition[cur_definition_names]['terms_defined'] += cur_definition[last_definitions]['terms_defined']
                    del cur_definition[last_definitions]
                else:
                    # we're at top-level, so add this as a new
                    # definition
                    rtn.append({'statements':tuple(cur_definition[last_definitions]['statements']),
                                'statement':'\n'.join(cur_definition[last_definitions]['statements']),
                                'terms_defined':tuple(cur_definition[last_definitions]['terms_defined'])})
                    del cur_definition[last_definitions]
                    #print('Adding:')
                    #print(rtn[-1])
            elif terms_defined:
                if cur_definition_names.strip('|'):
                    # we are still inside a definition.  For now, we
                    # flatten all definitions.
                    #
                    # TODO(jgross): Come up with a better story for
                    # nested definitions.
                    cur_definition[cur_definition_names]['statements'].append(statement)
                    cur_definition[cur_definition_names]['terms_defined'] += terms_defined
                else:
                    # we're at top level, so add this as a new
                    # definition
                    rtn.append({'statements':(statement,),
                                'statement':statement,
                                'terms_defined':tuple(terms_defined)})

            # now we handle the case where we have just opened a fresh
            # definition.  We've already added the key to the
            # dictionary.
            elif definitions_added:
                #print(definitions_added)
                cur_definition[cur_definition_names]['statements'].append(statement)
            else:
                # if we're in a definition, append the statement to
                # the queue, otherwise, just add it as it's own
                # statement
                if cur_definition_names.strip('|'):
                    cur_definition[cur_definition_names]['statements'].append(statement)
                else:
                    rtn.append({'statements':(statement,),
                                'statement':statement,
                                'terms_defined':tuple()})
        last_definitions = cur_definition_names

    if verbose >= 2: log((last_definitions, cur_definition_names))
    if last_definitions.strip('||'):
        rtn.append({'statements':tuple(cur_definition[cur_definition_names]['statements']),
                    'statement':'\n'.join(cur_definition[cur_definition_names]['statements']),
                    'terms_defined':tuple(cur_definition[cur_definition_names]['terms_defined'])})
        del cur_definition[last_definitions]
    #for i in rtn:
        #print(i)
    p.stdin.close()
    return rtn

def join_definitions(definitions):
    return '\n'.join(i['statement'] for i in definitions)
<|endoftext|>


<commit_before># This file is part of the pyMor project (http://www.pymor.org).
# Copyright Holders: Felix Albrecht, Rene Milk, Stephan Rave
# License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

from __future__ import absolute_import, division, print_function

import numpy as np

import pymor.core as core
from pymor.la import NumpyVectorArray
from pymor.core.cache import Cachable, NO_CACHE_CONFIG
from pymor.operators import rb_project_operator

class GenericRBReconstructor(core.BasicInterface):

    def __init__(self, RB):
        self.RB = RB

    def reconstruct(self, U):
        assert isinstance(U, NumpyVectorArray)
        return self.RB.lincomb(U._array)

def reduce_generic_rb(discretization, RB, product=None, disable_caching=True):
    '''Generic reduced basis reductor.

    Reduces a discretization by applying `operators.project_operator` to
    each of its `operators`.

    Parameters
    ----------
    discretization
        The discretization which is to be reduced.
    RB
        The reduced basis (i.e. an array of vectors) on which to project.
    product
        Scalar product for the projection. (See
        `operators.constructions.ProjectedOperator`)
    disable_caching
        If `True`, caching of the solutions of the reduced discretization
        is disabled.

    Returns
    -------
    rd
        The reduced discretization.
    rc
        The reconstructor providing a `reconstruct(U)` method which reconstructs
        high-dimensional solutions from solutions U of the reduced discretization.
    '''

    if RB is None:
        RB = NumpyVectorArray.empty(max(op.dim_source for op in discretization.operators.itervalues() if op))

    projected_operators = {k: rb_project_operator(op, RB, product=product)
                           for k, op in discretization.operators.iteritems()}

    if discretization.products is not None:
        projected_products = {k: rb_project_operator(op, RB, product=product)
                              for k, op in discretization.products.iteritems()}
    else:
        projected_products = None

    caching = None if disable_caching else discretization.caching

    rd = discretization.with_(operators=projected_operators, products=projected_products, visualizer=None,
                              caching=caching, name=discretization.name + '_reduced')
    rd.disable_logging()
    rc = GenericRBReconstructor(RB)

    return rd, rc
<commit_msg>documentation update<commit_after># This file is part of the pyMor project (http://www.pymor.org).
# Copyright Holders: Felix Albrecht, Rene Milk, Stephan Rave
# License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

from __future__ import absolute_import, division, print_function

import numpy as np

import pymor.core as core
from pymor.la import NumpyVectorArray
from pymor.core.cache import Cachable, NO_CACHE_CONFIG
from pymor.operators import rb_project_operator

class GenericRBReconstructor(core.BasicInterface):

    def __init__(self, RB):
        self.RB = RB

    def reconstruct(self, U):
        assert isinstance(U, NumpyVectorArray)
        return self.RB.lincomb(U._array)

def reduce_generic_rb(discretization, RB, product=None, disable_caching=True):
    '''Generic reduced basis reductor.

    Reduces a discretization by applying `operators.rb_project_operator` to
    each of its `operators`.

    Parameters
    ----------
    discretization
        The discretization which is to be reduced.
    RB
        The reduced basis (i.e. an array of vectors) on which to project.
    product
        Scalar product for the projection. (See
        `operators.constructions.ProjectedOperator`)
    disable_caching
        If `True`, caching of the solutions of the reduced discretization
        is disabled.

    Returns
    -------
    rd
        The reduced discretization.
    rc
        The reconstructor providing a `reconstruct(U)` method which reconstructs
        high-dimensional solutions from solutions U of the reduced discretization.
    '''

    if RB is None:
        RB = NumpyVectorArray.empty(max(op.dim_source for op in discretization.operators.itervalues() if op))

    projected_operators = {k: rb_project_operator(op, RB, product=product)
                           for k, op in discretization.operators.iteritems()}

    if discretization.products is not None:
        projected_products = {k: rb_project_operator(op, RB, product=product)
                              for k, op in discretization.products.iteritems()}
    else:
        projected_products = None

    caching = None if disable_caching else discretization.caching

    rd = discretization.with_(operators=projected_operators, products=projected_products, visualizer=None,
                              caching=caching, name=discretization.name + '_reduced')
    rd.disable_logging()
    rc = GenericRBReconstructor(RB)

    return rd, rc
<|endoftext|>


<commit_before>"""
Created on 26.02.2014

@author: jpi
"""

from django.utils.translation import ugettext as _
from django.db import models
from django.db.models.signals import post_delete
from django.conf import settings
from django.dispatch import receiver
from django.contrib.auth import get_user_model
import os.path
import mimetypes

class Location(models.Model):
    """
    A Location with a geoposition
    """
    label = models.CharField(max_length=150)
    description = models.TextField(null=True, blank=True)
    latitude = models.DecimalField(decimal_places=15, max_digits=18)
    longitude = models.DecimalField(decimal_places=15, max_digits=18)
    altitude = models.DecimalField(decimal_places=5, max_digits=10)
    created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
    modified = models.DateTimeField(auto_now=True, null=True, blank=True)
    dbpedia_link = models.CharField(max_length=500, null=True, blank=True)

    def __unicode__(self):
        return self.label + " [" + str(self.latitude) + ", " + str(self.longitude) + "]"

class Category(models.Model):
    """
    One Category to be assigned to a story or asset
    """
    created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
    modified = models.DateTimeField(auto_now=True, null=True, blank=True)
    name = models.CharField(max_length=150)
    description = models.TextField(null=True, blank=True)

class Story(models.Model):
    """
    One entry
    """
    categories = models.ManyToManyField(Category)
    title = models.CharField(max_length=150)
    abstract = models.TextField()
    text = models.TextField(null=True, blank=True)
    sources = models.TextField(null=True, blank=True)
    author = models.ForeignKey(settings.AUTH_USER_MODEL)
    time_start = models.DateField()
    time_end = models.DateField(null=True, blank=True)
    created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
    modified = models.DateTimeField(auto_now=True, null=True, blank=True)
    location = models.ForeignKey(Location, on_delete=models.PROTECT, null=True, blank=True, related_name="stories")
    assets = models.ManyToManyField("Asset", related_name="assets")

    def __unicode__(self):
        return self.title + " (" + unicode(self.author) + ")"

    def get_additional_images(self):
        """
        Returns a list of additional images for this entry
        """
        result = list()
        for index, asset in enumerate(self.assets.all()):
            if index > 0 and asset.type == Asset.IMAGE:
                result.append(asset)

        return result

    def get_additional_media(self):
        """
        Returns a list of additional media for this entry (no images)
        """
        result = list()
        for asset in self.assets.all():
            if asset.type != Asset.IMAGE:
                result.append(asset)

        return result

class Asset(models.Model):
    """
    Media Object to save images, videos or audio files that belong to an entry,
    a location or an entry type
    """
    VIDEO = "vid"
    IMAGE = "img"
    SOUND = "aud"
    TEXT = "txt"
    MEDIA_TYPES = (
        (VIDEO, _("Video")),
        (IMAGE, _("Bild")),
        (SOUND, _("Audio")),
        (TEXT, _("Text"))
    )
    created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
    modified = models.DateTimeField(auto_now=True, null=True, blank=True)
    categories = models.ManyToManyField(Category, null=True, blank=True)
    type = models.CharField(max_length=3, choices=MEDIA_TYPES, default=IMAGE)
    alt = models.CharField(max_length=300)
    description = models.TextField(null=True, blank=True)
    width = models.IntegerField(null=True, blank=True)
    height = models.IntegerField(null=True, blank=True)
    resolution = models.IntegerField(null=True, blank=True)
    device = models.CharField(max_length=300)
    length = models.IntegerField(null=True, blank=True)
    is_readable = models.BooleanField(default=False)
    stories = models.ManyToManyField(Story, related_name="stories", through=Story.assets.through)
    location = models.ForeignKey(Location, on_delete=models.PROTECT, null=True, blank=True)

    def __unicode__(self):
        return self.alt + " (" + str(self.id) + ")"

class MediaSource(models.Model):
    """
    One Source file that belongs to a media object
    """

    def get_upload_path(self, filename):
        i = 0
        while os.path.isfile(settings.MEDIA_ROOT + str(self.asset.id) + "/" + str(i) + filename):
            i += 1
        return str(self.asset.id) + "/" + str(i) + filename

    created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
    modified = models.DateTimeField(auto_now=True, null=True, blank=True)
    asset = models.ForeignKey(Asset, related_name="sources")
    file = models.FileField(upload_to=get_upload_path)

    def __unicode__(self):
        return self.file.name

    def get_mime_type(self):
        return mimetypes.guess_type(self.file.url)[0]

@receiver(post_delete, sender=MediaSource)
def delete_file(sender, instance, **kwargs):
    if instance.file is not None:
        instance.file.delete(False)

def find_user_by_name(query_name):
    """
    Finds a user by its full name
    :param query_name: full name to query
    :return: a list of users matching the query
    """
    qs = get_user_model().objects.all()
    for term in query_name.split():
        qs = qs.filter(models.Q(first_name__icontains=term) | models.Q(last_name__icontains=term))
    if len(qs) == 0:
        raise get_user_model().DoesNotExist
    return qs<commit_msg>Increase max_length<commit_after>"""
Created on 26.02.2014

@author: jpi
"""

from django.utils.translation import ugettext as _
from django.db import models
from django.db.models.signals import post_delete
from django.conf import settings
from django.dispatch import receiver
from django.contrib.auth import get_user_model
import os.path
import mimetypes

class Location(models.Model):
    """
    A Location with a geoposition
    """
    label = models.CharField(max_length=500)
    description = models.TextField(null=True, blank=True)
    latitude = models.DecimalField(decimal_places=15, max_digits=18)
    longitude = models.DecimalField(decimal_places=15, max_digits=18)
    altitude = models.DecimalField(decimal_places=5, max_digits=10)
    created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
    modified = models.DateTimeField(auto_now=True, null=True, blank=True)
    dbpedia_link = models.CharField(max_length=500, null=True, blank=True)

    def __unicode__(self):
        return self.label + " [" + str(self.latitude) + ", " + str(self.longitude) + "]"

class Category(models.Model):
    """
    One Category to be assigned to a story or asset
    """
    created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
    modified = models.DateTimeField(auto_now=True, null=True, blank=True)
    name = models.CharField(max_length=150)
    description = models.TextField(null=True, blank=True)

class Story(models.Model):
    """
    One entry
    """
    categories = models.ManyToManyField(Category)
    title = models.CharField(max_length=500)
    abstract = models.TextField()
    text = models.TextField(null=True, blank=True)
    sources = models.TextField(null=True, blank=True)
    author = models.ForeignKey(settings.AUTH_USER_MODEL)
    time_start = models.DateField()
    time_end = models.DateField(null=True, blank=True)
    created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
    modified = models.DateTimeField(auto_now=True, null=True, blank=True)
    location = models.ForeignKey(Location, on_delete=models.PROTECT, null=True, blank=True, related_name="stories")
    assets = models.ManyToManyField("Asset", related_name="assets")

    def __unicode__(self):
        return self.title + " (" + unicode(self.author) + ")"

    def get_additional_images(self):
        """
        Returns a list of additional images for this entry
        """
        result = list()
        for index, asset in enumerate(self.assets.all()):
            if index > 0 and asset.type == Asset.IMAGE:
                result.append(asset)

        return result

    def get_additional_media(self):
        """
        Returns a list of additional media for this entry (no images)
        """
        result = list()
        for asset in self.assets.all():
            if asset.type != Asset.IMAGE:
                result.append(asset)

        return result

class Asset(models.Model):
    """
    Media Object to save images, videos or audio files that belong to an entry,
    a location or an entry type
    """
    VIDEO = "vid"
    IMAGE = "img"
    SOUND = "aud"
    TEXT = "txt"
    MEDIA_TYPES = (
        (VIDEO, _("Video")),
        (IMAGE, _("Bild")),
        (SOUND, _("Audio")),
        (TEXT, _("Text"))
    )
    created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
    modified = models.DateTimeField(auto_now=True, null=True, blank=True)
    categories = models.ManyToManyField(Category, null=True, blank=True)
    type = models.CharField(max_length=3, choices=MEDIA_TYPES, default=IMAGE)
    alt = models.CharField(max_length=500)
    description = models.TextField(null=True, blank=True)
    width = models.IntegerField(null=True, blank=True)
    height = models.IntegerField(null=True, blank=True)
    resolution = models.IntegerField(null=True, blank=True)
    device = models.CharField(max_length=300)
    length = models.IntegerField(null=True, blank=True)
    is_readable = models.BooleanField(default=False)
    stories = models.ManyToManyField(Story, related_name="stories", through=Story.assets.through)
    location = models.ForeignKey(Location, on_delete=models.PROTECT, null=True, blank=True)

    def __unicode__(self):
        return self.alt + " (" + str(self.id) + ")"

class MediaSource(models.Model):
    """
    One Source file that belongs to a media object
    """

    def get_upload_path(self, filename):
        i = 0
        while os.path.isfile(settings.MEDIA_ROOT + str(self.asset.id) + "/" + str(i) + filename):
            i += 1
        return str(self.asset.id) + "/" + str(i) + filename

    created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
    modified = models.DateTimeField(auto_now=True, null=True, blank=True)
    asset = models.ForeignKey(Asset, related_name="sources")
    file = models.FileField(upload_to=get_upload_path)

    def __unicode__(self):
        return self.file.name

    def get_mime_type(self):
        return mimetypes.guess_type(self.file.url)[0]

@receiver(post_delete, sender=MediaSource)
def delete_file(sender, instance, **kwargs):
    if instance.file is not None:
        instance.file.delete(False)

def find_user_by_name(query_name):
    """
    Finds a user by its full name
    :param query_name: full name to query
    :return: a list of users matching the query
    """
    qs = get_user_model().objects.all()
    for term in query_name.split():
        qs = qs.filter(models.Q(first_name__icontains=term) | models.Q(last_name__icontains=term))
    if len(qs) == 0:
        raise get_user_model().DoesNotExist
    return qs<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from itertools import chain
from functools import wraps
from pyqp.tables import Abstract as TableFilterable

def csv_dumper(table):
    """Dumps given table to CSV format

    @param  table -- table to be dumped
    @type   table -- pyqp.table.Abstract

    Usage:
    >>> from pyqp.table import Table
    >>> t = Table('foo', ['column_1', 'column_2'])
    >>> t.add_value(1, 'column_1', 2).add_value(1, 'column_2', 3) #doctest: +ELLIPSIS
    <pyqp.table.Table object at 0x...>
    >>> csv_dumper(t)
    'column_1,column_2\\nstr,str\\n"column_1","column_2"\\n2,3'
    """
    return "\n".join(chain([\
        ','.join([column.name for column in table.columns]),\
        ','.join([column.type_name for column in table.columns]),\
        ','.join(['"%s"' % column.desc for column in table.columns])],\
        [','.join(map(str, row)) for row in table]))

def filterable_dumper(base_dumper, col_filter=None, row_filter=None):

    @wraps(filterable_dumper)
    def _dumper(table):
        return base_dumper(TableFilterable(table, col_filter, row_filter))
    return _dumper

def decorated_dumper(base_dumper, decorators):
    """Dumps given table using predefined base_dumper.
    Then each of given decorators is applied to received output

    @param  base_dumper -- base dumper to perform table dump
    @type   base_dumper -- callable
    @param  decorators  -- list of decorators to be applied to base_dumper output
    @type   decorators  -- list
    @return type
    """

    def _reduce(data, filter_func):
        return filter_func(data)

    @wraps(decorated_dumper)
    def _dump(table):
        return reduce(_reduce, decorators, base_dumper(table))
    return _dump
<commit_msg>Fixed doctests to pyqp.dumpers<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from itertools import chain
from functools import wraps
from pyqp.tables import Abstract as TableFilterable

def csv_dumper(table):
    """Dumps given table to CSV format

    @param  table -- table to be dumped
    @type   table -- pyqp.table.Abstract

    Usage:
    >>> from pyqp.tables import Table
    >>> t = Table('foo', ['column_1', 'column_2'])
    >>> t.add_value(1, 'column_1', 2).add_value(1, 'column_2', 3) #doctest: +ELLIPSIS
    <pyqp.tables.Table object at 0x...>
    >>> csv_dumper(t)
    'column_1,column_2\\nstr,str\\n"column_1","column_2"\\n2,3'
    """
    return "\n".join(chain([\
        ','.join([column.name for column in table.columns]),\
        ','.join([column.type_name for column in table.columns]),\
        ','.join(['"%s"' % column.desc for column in table.columns])],\
        [','.join(map(str, row)) for row in table]))

def filterable_dumper(base_dumper, col_filter=None, row_filter=None):

    @wraps(filterable_dumper)
    def _dumper(table):
        return base_dumper(TableFilterable(table, col_filter, row_filter))
    return _dumper

def decorated_dumper(base_dumper, decorators):
    """Dumps given table using predefined base_dumper.
    Then each of given decorators is applied to received output

    @param  base_dumper -- base dumper to perform table dump
    @type   base_dumper -- callable
    @param  decorators  -- list of decorators to be applied to base_dumper output
    @type   decorators  -- list
    @return type
    """

    def _reduce(data, filter_func):
        return filter_func(data)

    @wraps(decorated_dumper)
    def _dump(table):
        return reduce(_reduce, decorators, base_dumper(table))
    return _dump
<|endoftext|>