Completed
Push — master ( 8acb27...e9665f )
by Osma
20s queued 11s
created

annif.util.identity()   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nop 1
1
"""Utility functions for Annif"""
2
3
import glob
4
import os
5
import os.path
6
import tempfile
7
import numpy as np
8
from annif import logger
9
from annif.suggestion import VectorSuggestionResult
10
11
12
def atomic_save(obj, dirname, filename, method=None):
13
    """Save the given object (which must have a .save() method, unless the
14
    method parameter is given) into the given directory with the given
15
    filename, using a temporary file and renaming the temporary file to the
16
    final name."""
17
18
    prefix, suffix = os.path.splitext(filename)
19
    tempfd, tempfilename = tempfile.mkstemp(
20
        prefix=prefix, suffix=suffix, dir=dirname)
21
    os.close(tempfd)
22
    logger.debug('saving %s to temporary file %s', str(obj), tempfilename)
23
    if method is not None:
24
        method(obj, tempfilename)
25
    else:
26
        obj.save(tempfilename)
27
    for fn in glob.glob(tempfilename + '*'):
28
        newname = fn.replace(tempfilename, os.path.join(dirname, filename))
29
        logger.debug('renaming temporary file %s to %s', fn, newname)
30
        os.rename(fn, newname)
31
32
33
def cleanup_uri(uri):
34
    """remove angle brackets from a URI, if any"""
35
    if uri.startswith('<') and uri.endswith('>'):
36
        return uri[1:-1]
37
    return uri
38
39
40
def merge_hits(weighted_hits, subject_index):
41
    """Merge hits from multiple sources. Input is a sequence of WeightedSuggestion
42
    objects. A SubjectIndex is needed to convert between subject IDs and URIs.
43
    Returns an SuggestionResult object."""
44
45
    weights = [whit.weight for whit in weighted_hits]
46
    scores = [whit.hits.vector for whit in weighted_hits]
47
    result = np.average(scores, axis=0, weights=weights)
48
    return VectorSuggestionResult(result, subject_index)
49
50
51
def parse_sources(sourcedef):
52
    """parse a source definition such as 'src1:1.0,src2' into a sequence of
53
    tuples (src_id, weight)"""
54
55
    sources = []
56
    for srcdef in sourcedef.strip().split(','):
57
        srcval = srcdef.strip().split(':')
58
        src_id = srcval[0]
59
        if len(srcval) > 1:
60
            weight = float(srcval[1])
61
        else:
62
            weight = 1.0
63
        sources.append((src_id, weight))
64
    return sources
65
66
67
def boolean(val):
68
    """Convert the given value to a boolean True/False value, if it isn't already.
69
    True values are '1', 'yes', 'true', and 'on' (case insensitive), everything
70
    else is False."""
71
72
    return str(val).lower() in ('1', 'yes', 'true', 'on')
73
74
75
def identity(x):
76
    """Identity function: return the given argument unchanged"""
77
    return x
78