Completed
Pull Request — master (#22)
by Jerome
44s
created

BackedUpDict   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 55
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 55
rs 10
wmc 16

8 Methods

Rating   Name   Duplication   Size   Complexity  
A get() 0 6 2
A __init__() 0 9 2
A __iter__() 0 2 1
A __contains__() 0 2 1
A __getitem__() 0 11 3
A __setitem__() 0 7 2
A __len__() 0 2 1
A keys() 0 8 4
1
import os
2
from itertools import repeat
3
from itertools import takewhile
4
from sys import version_info
5
if version_info[0] == 2:
6
    from itertools import izip_longest as zip_longest
7
elif version_info[0] == 3:
8
    from itertools import zip_longest
9
import sqlite3
10
11
12
class BackedUpDict(object):
13
    def __init__(self,path):
14
        self.typemapping = {int:"int",str:"str",float:"float"}
15
        self.conn = sqlite3.connect(path)
16
        c = self.conn.cursor()
17
        for name,type_ in [("str","text"),("int","integer"),("float","real")]:
18
            c.execute("""CREATE TABLE IF NOT EXISTS data_{}_str (key {}, value text);""".format(name,type_))
19
            c.execute("""CREATE TABLE IF NOT EXISTS data_{}_int (key {}, value integer);""".format(name,type_))
20
            c.execute("""CREATE TABLE IF NOT EXISTS data_{}_float (key {}, value real);""".format(name,type_))
21
        self.conn.commit()
22
23
    def __getitem__(self, item):
24
        c = self.conn.cursor()
25
        res = list()
26
        for i in ["str","int","float"]:
27
            c.execute("""SELECT value FROM data_{}_{} where key=?;""".format(self.typemapping[type(item)],i),(item,))
28
            res += c.fetchall()
29
30
        if len(res) == 1:
31
            return res[0][0]
32
        else:
33
            raise KeyError
34
35
    def get(self,item,default=None):
36
        try:
37
            res = self.__getitem__(item)
38
            return res
39
        except KeyError:
40
            return default
41
42
    def __setitem__(self, key, value):
43
        res = self.get(key,None)
44
        c = self.conn.cursor()
45
        if res is not None:
46
            c.execute("""DELETE FROM data_{}_{} WHERE key =?;""".format(self.typemapping[type(key)],self.typemapping[type(res)]),(key,))
47
        c.execute("""INSERT INTO data_{}_{} VALUES (?,?);""".format(self.typemapping[type(key)],self.typemapping[type(value)]),(key,value))
48
        self.conn.commit()
49
50
    def keys(self):
51
        c = self.conn.cursor()
52
        res = list()
53
        for i in ["str", "int", "float"]:
54
            for j in ["str","int","float"]:
55
                c.execute("""SELECT key FROM data_{}_{};""".format(i,j))
56
                res += c.fetchall()
57
        return [i[0] for i in res]
58
59
    def __len__(self):
60
        return len(self.keys())
61
62
    def __contains__(self, item):
63
        return item in self.keys()
64
65
    def __iter__(self):
66
        return iter(self.keys())
67
68
def obtain(filename):
69
    with open(filename, 'r') as file_:
70
        categories = []
71
        res = []
72
        for i, line in enumerate(file_):
73
            if i == 0:
74
                categories = list(map(str.strip, line.strip().split("\t")))
75
            else:
76
                res.append(dict(zip_longest(categories, map(str.strip, line.split("\t")), fillvalue="")))
77
    return res
78
79
80
def persist(filename, dict_, mode="a", split="\t"):
81
    order = None
82
    if filename in os.listdir(os.getcwd()):
83
        with open(filename) as file_:
84
            order = file_.readline().strip().split(split)
85
    with open(filename, mode) as file_:
86
        if order is None:
87
            order = list(dict_.keys())
88
            file_.write(split.join(order))
89
            file_.write("\n")
90
        file_.write(split.join([str(dict_[i]) for i in order]))
91
        file_.write("\n")
92
93
94
def count(filename):
95
    """Credits to Michael Bacon/Quentin Pradet from Stackoverflow
96
97
    filename -- Name of the file, of which the amount of lines shall be counted
98
    """
99
    f = open(filename, 'rb')
100
    bufgen = takewhile(lambda x: x, (f.raw.read(1024*1024) for _ in repeat(None)))
101
    return sum(buf.count(b'\n') for buf in bufgen)
102