Skip to content

Commit 61d8413

Browse files
author
Martin O'Hanlon
authored
Merge pull request #7 from martinohanlon/dev
v0.1.0
2 parents aefd7d2 + 337da39 commit 61d8413

File tree

8 files changed

+465
-28
lines changed

8 files changed

+465
-28
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
*.py[cdo]
22
pythonhosted/
3+
.pytest_cache/
34

45
# Editor detritus
56
*.vim

README.rst

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
quickdraw
22
=========
33

4+
|pypibadge| |docsbadge|
5+
46
`Quick Draw`_ is a drawing game which is training a neural network to recognise doodles.
57

68
|quickdraw|
@@ -128,7 +130,7 @@ The drawings have been moderated but there is no guarantee it'll actually be a p
128130
Status
129131
------
130132

131-
**Alpha** - under active dev, the API may change, problems might occur.
133+
**Beta** - stable, under active dev, the API may change.
132134

133135

134136
.. |quickdraw| image:: https://raw.githubusercontent.com/martinohanlon/quickdraw_python/master/docs/images/quickdraw.png
@@ -143,6 +145,13 @@ Status
143145
:scale: 100 %
144146
:alt: quickdraw_preview
145147

148+
.. |pypibadge| image:: https://badge.fury.io/py/quickdraw.svg
149+
:target: https://badge.fury.io/py/quickdraw
150+
:alt: Latest Version
151+
152+
.. |docsbadge| image:: https://readthedocs.org/projects/quickdraw/badge/
153+
:target: https://readthedocs.org/projects/quickdraw/
154+
:alt: Docs
146155

147156
.. _Martin O'Hanlon: https://github.com/martinohanlon
148157
.. _stuffaboutco.de: http://stuffaboutco.de

docs/changelog.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ Change log
33

44
.. currentmodule:: quickdraw
55

6+
0.1.0
7+
-----
8+
9+
+ Beta
10+
+ Bug fixes
11+
+ Additional properties methods and stuff
12+
+ Tests
13+
614
0.0.1 > 0.0.4
715
-------------
816

docs/getstarted.rst

Whitespace-only changes.

quickdraw/data.py

Lines changed: 170 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import unicode_literals
2+
13
import struct
24
from random import choice
35
from os import path, makedirs
@@ -28,17 +30,22 @@ class QuickDrawData():
2830
anvil = qd.get_drawing("anvil")
2931
anvil.image.save("my_anvil.gif")
3032
33+
:param bool recognized:
34+
If ``True`` only recognized drawings will be loaded, if ``False``
35+
only unrecognized drawings will be loaded, if ``None`` (the default)
36+
both recognized and unrecognized drawings will be loaded.
37+
3138
:param int max_drawings:
3239
The maximum number of drawings to be loaded into memory,
3340
defaults to 1000.
3441
3542
:param bool refresh_data:
36-
If `True` forces data to be downloaded even if it has been
37-
downloaded before, defaults to `False`.
43+
If ``True`` forces data to be downloaded even if it has been
44+
downloaded before, defaults to ``False``.
3845
3946
:param bool jit_loading:
40-
If `True` (the default) only downloads and loads data into
41-
memory when it is required (jit = just in time). If `False`
47+
If ``True`` (the default) only downloads and loads data into
48+
memory when it is required (jit = just in time). If ``False``
4249
all drawings will be downloaded and loaded into memory.
4350
4451
:param bool print_messages:
@@ -49,7 +56,16 @@ class QuickDrawData():
4956
Specify a cache directory to use when downloading data files,
5057
defaults to `./.quickdrawcache`.
5158
"""
52-
def __init__(self, max_drawings=1000, refresh_data=False, jit_loading=True, print_messages=True, cache_dir=CACHE_DIR):
59+
def __init__(
60+
self,
61+
recognized=None,
62+
max_drawings=1000,
63+
refresh_data=False,
64+
jit_loading=True,
65+
print_messages=True,
66+
cache_dir=CACHE_DIR):
67+
68+
self._recognized = recognized
5369
self._print_messages = print_messages
5470
self._refresh_data = refresh_data
5571
self._max_drawings = max_drawings
@@ -74,7 +90,7 @@ def get_drawing(self, name, index=None):
7490
:param int index:
7591
The index of the drawing to get.
7692
77-
If `None` (the default) a random drawing will be returned.
93+
If ``None`` (the default) a random drawing will be returned.
7894
"""
7995
return self.get_drawing_group(name).get_drawing(index)
8096

@@ -91,6 +107,7 @@ def get_drawing_group(self, name):
91107
if name not in self._drawing_groups.keys():
92108
drawings = QuickDrawDataGroup(
93109
name,
110+
recognized=self._recognized,
94111
max_drawings=self._max_drawings,
95112
refresh_data=self._refresh_data,
96113
print_messages=self._print_messages,
@@ -99,11 +116,58 @@ def get_drawing_group(self, name):
99116

100117
return self._drawing_groups[name]
101118

119+
def search_drawings(self, name, key_id=None, recognized=None, countrycode=None, timestamp=None):
120+
"""
121+
Search the drawings.
122+
123+
Returns an list of :class:`QuickDrawing` instances representing the
124+
matched drawings.
125+
126+
Note - search criteria are a compound.
127+
128+
Search for all the drawings with the ``countrycode`` "PL" ::
129+
130+
from quickdraw import QuickDrawDataGroup
131+
132+
anvils = QuickDrawDataGroup("anvil")
133+
results = anvils.search_drawings(countrycode="PL")
134+
135+
:param string name:
136+
The name of the drawings (anvil, ant, aircraft, etc)
137+
to search.
138+
139+
:param int key_id:
140+
The ``key_id`` to such for. If ``None`` (the default) the
141+
``key_id`` is not used.
142+
143+
:param bool recognized:
144+
To search for drawings which were ``recognized``. If ``None``
145+
(the default) ``recognized`` is not used.
146+
147+
:param str countrycode:
148+
To search for drawings which with the ``countrycode``. If
149+
``None`` (the default) ``countrycode`` is not used.
150+
151+
:param int countrycode:
152+
To search for drawings which with the ``timestamp``. If ``None``
153+
(the default) ``timestamp`` is not used.
154+
"""
155+
return self.get_drawing_group(name).search_drawings(key_id, recognized, countrycode, timestamp)
156+
102157
def load_all_drawings(self):
103158
"""
104159
Loads (and downloads if required) all drawings into memory.
105160
"""
106-
for drawing_group in QUICK_DRAWING_NAMES:
161+
self.load_drawings(self.drawing_names)
162+
163+
def load_drawings(self, list_of_drawings):
164+
"""
165+
Loads (and downloads if required) all drawings into memory.
166+
167+
:param list list_of_drawings:
168+
A list of the drawings to be loaded (anvil, ant, aircraft, etc).
169+
"""
170+
for drawing_group in list_of_drawings:
107171
self.get_drawing_group(drawing_group)
108172

109173
@property
@@ -113,6 +177,13 @@ def drawing_names(self):
113177
"""
114178
return QUICK_DRAWING_NAMES
115179

180+
@property
181+
def loaded_drawings(self):
182+
"""
183+
Returns a list of drawing which have been loaded into memory.
184+
"""
185+
return list(self._drawing_groups.keys())
186+
116187

117188
class QuickDrawDataGroup():
118189
"""
@@ -130,12 +201,17 @@ class QuickDrawDataGroup():
130201
:param string name:
131202
The name of the drawings to be loaded (anvil, ant, aircraft, etc).
132203
204+
:param bool recognized:
205+
If ``True`` only recognized drawings will be loaded, if ``False``
206+
only unrecognized drawings will be loaded, if ``None`` (the default)
207+
both recognized and unrecognized drawings will be loaded.
208+
133209
:param int max_drawings:
134210
The maximum number of drawings to be loaded into memory,
135211
defaults to 1000.
136212
137213
:param bool refresh_data:
138-
If `True` forces data to be downloaded even if it has been
214+
If ``True`` forces data to be downloaded even if it has been
139215
downloaded before, defaults to `False`.
140216
141217
:param bool print_messages:
@@ -144,9 +220,16 @@ class QuickDrawDataGroup():
144220
145221
:param string cache_dir:
146222
Specify a cache directory to use when downloading data files,
147-
defaults to `./.quickdrawcache`.
223+
defaults to ``./.quickdrawcache``.
148224
"""
149-
def __init__(self, name, max_drawings=1000, refresh_data=False, print_messages=True, cache_dir=CACHE_DIR):
225+
def __init__(
226+
self,
227+
name,
228+
recognized=None,
229+
max_drawings=1000,
230+
refresh_data=False,
231+
print_messages=True,
232+
cache_dir=CACHE_DIR):
150233

151234
if name not in QUICK_DRAWING_NAMES:
152235
raise ValueError("{} is not a valid google quick drawing".format(name))
@@ -155,6 +238,7 @@ def __init__(self, name, max_drawings=1000, refresh_data=False, print_messages=T
155238
self._print_messages = print_messages
156239
self._max_drawings = max_drawings
157240
self._cache_dir = cache_dir
241+
self._recognized = recognized
158242

159243
self._drawings = []
160244

@@ -227,21 +311,27 @@ def _load_drawings(self, filename):
227311
y = struct.unpack(fmt, binary_file.read(n_points))
228312
image.append((x, y))
229313

230-
self._drawings.append({
231-
'key_id': key_id,
232-
'countrycode': countrycode,
233-
'recognized': recognized,
234-
'timestamp': timestamp,
235-
'n_strokes': n_strokes,
236-
'image': image
237-
})
314+
append_drawing = True
315+
if self._recognized is not None:
316+
if bool(recognized) != self._recognized:
317+
append_drawing = False
318+
319+
if append_drawing:
320+
self._drawings.append({
321+
'key_id': key_id,
322+
'countrycode': countrycode,
323+
'recognized': recognized,
324+
'timestamp': timestamp,
325+
'n_strokes': n_strokes,
326+
'image': image
327+
})
328+
329+
self._drawing_count += 1
238330

239331
# nothing left to read
240332
except struct.error:
241333
break
242334

243-
self._drawing_count += 1
244-
245335
self._print_message("load complete")
246336

247337
def _print_message(self, message):
@@ -270,7 +360,7 @@ def drawings(self):
270360
"""
271361
while True:
272362
self._current_drawing += 1
273-
if self._current_drawing == self._drawing_count - 1:
363+
if self._current_drawing > self._drawing_count - 1:
274364
# reached the end to the drawings
275365
self._current_drawing = 0
276366
raise StopIteration()
@@ -295,16 +385,72 @@ def get_drawing(self, index=None):
295385
:param int index:
296386
The index of the drawing to get.
297387
298-
If `None` (the default) a random drawing will be returned.
388+
If ``None`` (the default) a random drawing will be returned.
299389
"""
300390
if index is None:
301391
return QuickDrawing(self._name, choice(self._drawings))
302392
else:
303-
if index < self.drawing_count - 1:
393+
if index < self.drawing_count:
304394
return QuickDrawing(self._name, self._drawings[index])
305395
else:
306396
raise IndexError("index {} out of range, there are {} drawings".format(index, self.drawing_count))
307397

398+
def search_drawings(self, key_id=None, recognized=None, countrycode=None, timestamp=None):
399+
"""
400+
Searches the drawings in this group.
401+
402+
Returns an list of :class:`QuickDrawing` instances representing the
403+
matched drawings.
404+
405+
Note - search criteria are a compound.
406+
407+
Search for all the drawings with the ``countrycode`` "PL" ::
408+
409+
from quickdraw import QuickDrawDataGroup
410+
411+
anvils = QuickDrawDataGroup("anvil")
412+
results = anvils.search_drawings(countrycode="PL")
413+
414+
:param int key_id:
415+
The ``key_id`` to such for. If ``None`` (the default) the
416+
``key_id`` is not used.
417+
418+
:param bool recognized:
419+
To search for drawings which were ``recognized``. If ``None``
420+
(the default) ``recognized`` is not used.
421+
422+
:param str countrycode:
423+
To search for drawings which with the ``countrycode``. If
424+
``None`` (the default) ``countrycode`` is not used.
425+
426+
:param int countrycode:
427+
To search for drawings which with the ``timestamp``. If ``None``
428+
(the default) ``timestamp`` is not used.
429+
"""
430+
results = []
431+
432+
for drawing in self.drawings:
433+
match = True
434+
if key_id is not None:
435+
if key_id != drawing.key_id:
436+
match = False
437+
438+
if recognized is not None:
439+
if recognized != drawing.recognized:
440+
match = False
441+
442+
if countrycode is not None:
443+
if countrycode != drawing.countrycode:
444+
match = False
445+
446+
if timestamp is not None:
447+
if timestamp != drawing.timestamp:
448+
match = False
449+
450+
if match:
451+
results.append(drawing)
452+
453+
return results
308454

309455
class QuickDrawing():
310456
"""
@@ -335,7 +481,7 @@ def countrycode(self):
335481
"""
336482
Returns the country code for the drawing.
337483
"""
338-
return self._drawing_data["countrycode"]
484+
return self._drawing_data["countrycode"].decode("utf-8")
339485

340486
@property
341487
def recognized(self):

setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
__project__ = 'quickdraw'
1111
__desc__ = 'An API for downloading and reading the google quickdraw data.'
12-
__version__ = '0.0.4'
12+
__version__ = '0.1.0'
1313
__author__ = "Martin O'Hanlon"
1414
__author_email__ = '[email protected]'
1515
__license__ = 'MIT'
@@ -63,8 +63,8 @@
6363
"""
6464

6565
__classifiers__ = [
66-
"Development Status :: 3 - Alpha",
67-
# "Development Status :: 4 - Beta",
66+
# "Development Status :: 3 - Alpha",
67+
"Development Status :: 4 - Beta",
6868
# "Development Status :: 5 - Production/Stable",
6969
"Intended Audience :: Education",
7070
"Intended Audience :: Developers",

0 commit comments

Comments
 (0)