Skip to content

Commit 90469de

Browse files
committed
Enhancement: configuration of serialization for single element strings
1 parent 9d404e8 commit 90469de

14 files changed

+216
-143
lines changed

CHANGELOG.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1+
------------------------------------------------------------------------------
2+
qPython 1.0.2 [2015.09.03]
3+
------------------------------------------------------------------------------
4+
5+
- Enhancement: configuration of serialization for single element strings
6+
17
------------------------------------------------------------------------------
28
qPython 1.0.1 [2015.08.11]
39
------------------------------------------------------------------------------
410

5-
- Fix: serialization of indexed Pandas.DataFrames
11+
- Fix: serialization of indexed Pandas.DataFrames
612

713
------------------------------------------------------------------------------
814
qPython 1.0.0 [2015.04.10]

conda.recipe/meta.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package:
22
name: qpython
3-
version: 1.0.1
3+
version: 1.0.2
44

55
build:
66
number: 1

doc/source/conf.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,11 @@ def __getattr__(cls, name):
7070
# |version| and |release|, also used in various other places throughout the
7171
# built documents.
7272
#
73+
from qpython import __version__
7374
# The short X.Y version.
74-
version = '1.0'
75+
version = __version__
7576
# The full version, including alpha/beta/rc tags.
76-
release = '1.0.1'
77+
release = __version__
7778

7879
# The language for content autogenerated by Sphinx. Refer to documentation
7980
# for a list of supported languages.
@@ -261,7 +262,7 @@ def __getattr__(cls, name):
261262
# dir menu entry, description, category)
262263
texinfo_documents = [
263264
('index', 'qPython', u'qPython Documentation',
264-
u'DEVnet', 'qPython', 'One line description of project.',
265+
u'DEVnet', 'qPython', 'Interprocess communication between Python and kdb+',
265266
'Miscellaneous'),
266267
]
267268

doc/source/connection.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ can be used with a ``with`` statement:
3030
print q('{`int$ til x}', 10)
3131

3232

33-
Q parser configuration
34-
**********************
33+
Types conversion configuration
34+
******************************
3535

3636
Connection can be preconfigured to parse IPC messages according to a specified
3737
settings, e.g.: temporal vectors can be represented as raw vectors or converted
@@ -45,6 +45,7 @@ to numpy `datetime64`/`timedelta64` representation.
4545
q = qconnection.QConnection(host = 'localhost', port = 5000, numpy_temporals = True)
4646

4747

48-
Parsing options can be also overwritten while executing synchronous query
49-
(:meth:`~qpython.qconnection.QConnection.sync`) or retrieving data from q
48+
Conversion options can be also overwritten while executing
49+
synchronous/asynchronous queries (:meth:`~qpython.qconnection.QConnection.sync`,
50+
:meth:`~qpython.qconnection.QConnection.async`) or retrieving data from q
5051
(:meth:`~qpython.qconnection.QConnection.receive`).

doc/source/queries.rst

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,16 @@ QMessage: message type: 2, data size: 13, is_compressed: False, data: 10
106106
fa0a000000
107107

108108

109-
Q parser configuration
110-
**********************
109+
Type conversions configuration
110+
******************************
111111

112-
Parsing options can be overwritten while:
112+
Type conversion options can be overwritten while:
113113

114114
- executing synchronous query: :meth:`~qpython.qconnection.QConnection.sync`
115+
- executing asynchronous query: :meth:`~qpython.qconnection.QConnection.async`
115116
- retrieving data from q: :meth:`~qpython.qconnection.QConnection.receive`
116117

117-
Both methods accepts the `options` keywords arguments::
118+
These methods accepts the `options` keywords arguments::
118119

119120
>>> query = "{[x] 0Nd, `date$til x}"
120121
@@ -133,4 +134,10 @@ Both methods accepts the `options` keywords arguments::
133134
[NaT [metadata(qtype=-14)] 2000-01-01 [metadata(qtype=-14)]
134135
2000-01-02 [metadata(qtype=-14)] 2000-01-03 [metadata(qtype=-14)]]
135136
136-
137+
>>> # serialize single element strings as q characters
138+
>>> print q.sync('{[x] type each x}', ['one', 'two', '3'], single_char_strings = False)
139+
[ 10, 10, -10]
140+
141+
>>> # serialize single element strings as q strings
142+
>>> print q.sync('{[x] type each x}', ['one', 'two', '3'], single_char_strings = True)
143+
[10, 10, 10]

doc/source/type-conversion.rst

Lines changed: 63 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ to this table:
2222
=============== ============ =====================================
2323
q type q num type Python type
2424
=============== ============ =====================================
25-
``bool`` -1 ``numpy.bool_``
25+
``bool`` -1 ``numpy.bool_``
2626
``guid`` -2 ``UUID``
27-
``byte`` -4 ``numpy.byte``
28-
``short`` -5 ``numpy.int16``
29-
``integer`` -6 ``numpy.int32``
30-
``long`` -7 ``numpy.int64``
31-
``real`` -8 ``numpy.float32``
32-
``float`` -9 ``numpy.float64``
27+
``byte`` -4 ``numpy.byte``
28+
``short`` -5 ``numpy.int16``
29+
``integer`` -6 ``numpy.int32``
30+
``long`` -7 ``numpy.int64``
31+
``real`` -8 ``numpy.float32``
32+
``float`` -9 ``numpy.float64``
3333
``character`` -10 single element ``str``
3434
``timestamp`` -12 ``QTemporal numpy.datetime64 ns``
3535
``month`` -13 ``QTemporal numpy.datetime64 M``
@@ -54,31 +54,35 @@ described in the table:
5454
===================================== ================ ============
5555
Python type q type q num type
5656
===================================== ================ ============
57-
``bool`` ``bool`` -1
58-
--- ``byte`` -4
59-
--- ``short`` -5
60-
``int`` ``int`` -6
61-
``long`` ``long`` -7
62-
--- ``real`` -8
63-
``double`` ``float`` -9
64-
``numpy.bool`` ``bool`` -1
65-
``numpy.byte`` ``byte`` -4
66-
``numpy.int16`` ``short`` -5
67-
``numpy.int32`` ``int`` -6
68-
``numpy.int64`` ``long`` -7
69-
``numpy.float32`` ``real`` -8
70-
``numpy.float64`` ``float`` -9
71-
single element ``str`` ``character`` -10
72-
``QTemporal numpy.datetime64 ns`` ``timestamp`` -12
73-
``QTemporal numpy.datetime64 M`` ``month`` -13
74-
``QTemporal numpy.datetime64 D`` ``date`` -14
75-
``QTemporal numpy.datetime64 ms`` ``datetime`` -15
76-
``QTemporal numpy.timedelta64 ns`` ``timespan`` -16
77-
``QTemporal numpy.timedelta64 m`` ``minute`` -17
78-
``QTemporal numpy.timedelta64 s`` ``second`` -18
79-
``QTemporal numpy.timedelta64 ms`` ``time`` -19
57+
``bool`` ``bool`` -1
58+
--- ``byte`` -4
59+
--- ``short`` -5
60+
``int`` ``int`` -6
61+
``long`` ``long`` -7
62+
--- ``real`` -8
63+
``double`` ``float`` -9
64+
``numpy.bool`` ``bool`` -1
65+
``numpy.byte`` ``byte`` -4
66+
``numpy.int16`` ``short`` -5
67+
``numpy.int32`` ``int`` -6
68+
``numpy.int64`` ``long`` -7
69+
``numpy.float32`` ``real`` -8
70+
``numpy.float64`` ``float`` -9
71+
single element ``str`` ``character`` -10
72+
``QTemporal numpy.datetime64 ns`` ``timestamp`` -12
73+
``QTemporal numpy.datetime64 M`` ``month`` -13
74+
``QTemporal numpy.datetime64 D`` ``date`` -14
75+
``QTemporal numpy.datetime64 ms`` ``datetime`` -15
76+
``QTemporal numpy.timedelta64 ns`` ``timespan`` -16
77+
``QTemporal numpy.timedelta64 m`` ``minute`` -17
78+
``QTemporal numpy.timedelta64 s`` ``second`` -18
79+
``QTemporal numpy.timedelta64 ms`` ``time`` -19
8080
===================================== ================ ============
8181

82+
.. note:: By default, single element strings are serialized as q characters.
83+
This setting can be modified (`single_char_strings = True`) and
84+
and single element strings are represented as q strings.
85+
8286

8387
String and symbols
8488
******************
@@ -98,6 +102,20 @@ apply:
98102
'quick brown fox jumps over a lazy dog'
99103

100104

105+
.. note:: By default, single element strings are serialized as q characters.
106+
This setting can be modified (`single_char_strings = True`) and
107+
and single element strings are represented as q strings.
108+
109+
::
110+
111+
>>> # serialize single element strings as q characters
112+
>>> print(q.sync('{[x] type each x}', ['one', 'two', '3'], single_char_strings = False))
113+
[ 10, 10, -10]
114+
115+
>>> # serialize single element strings as q strings
116+
>>> print(q.sync('{[x] type each x}', ['one', 'two', '3'], single_char_strings = True))
117+
[10, 10, 10]
118+
101119

102120
Lists
103121
*****
@@ -350,22 +368,22 @@ Complete null mapping between q and Python is represented in the table:
350368
============== ============== =======================
351369
``bool`` ``0b`` ``_QNULL_BOOL``
352370
``guid`` ``0Ng`` ``_QNULL_GUID``
353-
``byte`` ``0x00`` ``_QNULL1``
354-
``short`` ``0Nh`` ``_QNULL2``
355-
``int`` ``0N`` ``_QNULL4``
356-
``long`` ``0Nj`` ``_QNULL8``
357-
``real`` ``0Ne`` ``_QNAN32``
358-
``float`` ``0n`` ``_QNAN64``
359-
``string`` ``" "`` ``' '``
371+
``byte`` ``0x00`` ``_QNULL1``
372+
``short`` ``0Nh`` ``_QNULL2``
373+
``int`` ``0N`` ``_QNULL4``
374+
``long`` ``0Nj`` ``_QNULL8``
375+
``real`` ``0Ne`` ``_QNAN32``
376+
``float`` ``0n`` ``_QNAN64``
377+
``string`` ``" "`` ``' '``
360378
``symbol`` \` ``_QNULL_SYM``
361-
``timestamp`` ``0Np`` ``_QNULL8``
362-
``month`` ``0Nm`` ``_QNULL4``
363-
``date`` ``0Nd`` ``_QNULL4``
364-
``datetime`` ``0Nz`` ``_QNAN64``
365-
``timespan`` ``0Nn`` ``_QNULL8``
366-
``minute`` ``0Nu`` ``_QNULL4``
367-
``second`` ``0Nv`` ``_QNULL4``
368-
``time`` ``0Nt`` ``_QNULL4``
379+
``timestamp`` ``0Np`` ``_QNULL8``
380+
``month`` ``0Nm`` ``_QNULL4``
381+
``date`` ``0Nd`` ``_QNULL4``
382+
``datetime`` ``0Nz`` ``_QNAN64``
383+
``timespan`` ``0Nn`` ``_QNULL8``
384+
``minute`` ``0Nu`` ``_QNULL4``
385+
``second`` ``0Nv`` ``_QNULL4``
386+
``time`` ``0Nt`` ``_QNULL4``
369387
============== ============== =======================
370388

371389
The :py:mod:`qtype` provides two utility functions to work with null values:

qpython/__init__.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
__all__ = ['qconnection', 'qtype', 'qtemporal', 'qcollection']
1818

1919

20-
__version__ = '1.0.1'
20+
__version__ = '1.0.2'
2121

2222
try:
2323
from qpython.fastutils import uncompress
@@ -56,4 +56,11 @@ def as_dict(self):
5656
return self.__dict__.copy()
5757

5858
def union_dict(self, **kw):
59-
return dict(self.as_dict().items() + kw.items())
59+
return dict(list(self.as_dict().items()) + list(kw.items()))
60+
61+
62+
CONVERSION_OPTIONS = MetaData(raw = False,
63+
numpy_temporals = False,
64+
pandas = False,
65+
single_char_strings = False
66+
)

qpython/_pandas.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from collections import OrderedDict
2121

2222
from qpython import MetaData
23-
from qpython.qreader import QReader, READER_CONFIGURATION, QReaderException
23+
from qpython.qreader import QReader, QReaderException
2424
from qpython.qcollection import QDictionary, qlist
2525
from qpython.qwriter import QWriter, QWriterException
2626
from qpython.qtype import *
@@ -32,10 +32,10 @@ class PandasQReader(QReader):
3232
parse = Mapper(QReader._reader_map)
3333

3434
@parse(QDICTIONARY)
35-
def _read_dictionary(self, qtype = QDICTIONARY, options = READER_CONFIGURATION):
36-
if options.pandas:
37-
keys = self._read_object(options = options)
38-
values = self._read_object(options = options)
35+
def _read_dictionary(self, qtype = QDICTIONARY):
36+
if self._options.pandas:
37+
keys = self._read_object()
38+
values = self._read_object()
3939

4040
if isinstance(keys, pandas.DataFrame):
4141
if not isinstance(values, pandas.DataFrame):
@@ -58,17 +58,17 @@ def _read_dictionary(self, qtype = QDICTIONARY, options = READER_CONFIGURATION):
5858
values = values if not isinstance(values, pandas.Series) else values.as_matrix()
5959
return QDictionary(keys, values)
6060
else:
61-
return QReader._read_dictionary(self, qtype = qtype, options = options)
61+
return QReader._read_dictionary(self, qtype = qtype)
6262

6363

6464
@parse(QTABLE)
65-
def _read_table(self, qtype = QTABLE, options = READER_CONFIGURATION):
66-
if options.pandas:
65+
def _read_table(self, qtype = QTABLE):
66+
if self._options.pandas:
6767
self._buffer.skip() # ignore attributes
6868
self._buffer.skip() # ignore dict type stamp
6969

70-
columns = self._read_object(options = options)
71-
data = self._read_object(options = options)
70+
columns = self._read_object()
71+
data = self._read_object()
7272

7373
odict = OrderedDict()
7474
meta = MetaData(qtype = QTABLE)
@@ -91,16 +91,16 @@ def _read_table(self, qtype = QTABLE, options = READER_CONFIGURATION):
9191
df.meta = meta
9292
return df
9393
else:
94-
return QReader._read_table(self, qtype = qtype, options = options)
94+
return QReader._read_table(self, qtype = qtype)
9595

9696

97-
def _read_list(self, qtype, options):
98-
if options.pandas:
99-
options.numpy_temporals = True
97+
def _read_list(self, qtype):
98+
if self._options.pandas:
99+
self._options.numpy_temporals = True
100100

101-
list = QReader._read_list(self, qtype = qtype, options = options)
101+
list = QReader._read_list(self, qtype = qtype)
102102

103-
if options.pandas:
103+
if self._options.pandas:
104104
if -abs(qtype) not in [QMONTH, QDATE, QDATETIME, QMINUTE, QSECOND, QTIME, QTIMESTAMP, QTIMESPAN, QSYMBOL]:
105105
null = QNULLMAP[-abs(qtype)][1]
106106
ps = pandas.Series(data = list).replace(null, numpy.NaN)
@@ -114,9 +114,9 @@ def _read_list(self, qtype, options):
114114

115115

116116
@parse(QGENERAL_LIST)
117-
def _read_general_list(self, qtype = QGENERAL_LIST, options = READER_CONFIGURATION):
118-
list = QReader._read_general_list(self, qtype, options)
119-
if options.pandas:
117+
def _read_general_list(self, qtype = QGENERAL_LIST):
118+
list = QReader._read_general_list(self, qtype)
119+
if self._options.pandas:
120120
return [numpy.nan if isinstance(element, basestring) and element == ' ' else element for element in list]
121121
else:
122122
return list

0 commit comments

Comments
 (0)