g-node / nixpy Goto Github PK
View Code? Open in Web Editor NEWPython library for NIX
Home Page: https://readthedocs.org/projects/nixpy
License: Other
Python library for NIX
Home Page: https://readthedocs.org/projects/nixpy
License: Other
@Drumstick12 pointed me to an issue related with batch operations on multiple files.
Consider the following code:
import nix
import numpy as np
import glob
def create_files(count):
for i in range(count):
f = nix.File.open("test_"+str(i)+".h5", nix.FileMode.Overwrite)
b = f.create_block("test_block_" + str(i), "test")
da = b.create_data_array("array", "test", data=np.random.rand(1000))
da.append_sampled_dimension(1.)
da.unit = "mV"
da.label = "voltage"
f.close()
da = None # this is essential; code fails, otherwise
b = None # do
def reload_files():
files = glob.glob('test*.h5')
for fi in files:
f = nix.File.open(fi, nix.FileMode.ReadOnly)
b = f.blocks[0]
da = b.data_arrays['array']
data = da[:]
da = None # this is essential
b = None # do
f.close()
if __name__ == "__main__":
create_files(10)
reload_files()
It creates a few files, stores some data and subsequently re-opens them to read the data. Without setting the variables for the block and the data array explicitly to None
the code fails with the same H5Lexists: not a location exception.
Setting everything to None, is ok for a few variables, but is really annoying if you open a lot of entities.
The module commands
is deprecated since python 2.6 and not available on python 3. Should be replaced by module subprocess
.
... due to the latest changes in the Nix library. In particular the pySection.createProperty fails.
The following snippets (kind of) work but produce Type errors I do not understand:
import nix
f = nix.File.open('test.h5', nix.FileMode.Overwrite)
s = f.create_section('test','test')
# the following code works fine, even if data types do not match
p = s.create_property('test_p', nix.DataType.Int32)
p.data_type
nix.core.DataType.Int32
p.values = [nix.Value(1)]
p.data_type
nix.core.DataType.Int64
# here it crashes:
p2 = s.create_property('test_p2', nix.Value(1))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
TypeError: data type not understood
# funny enough p2 exists, has the correct data type and value
p2.data_type
nix.core.DataType.Int64
p2.values
(Value{[DataType::Int64] 1},)
Subclass ProxyList
and add an append method
Write a mixin that paches all subclasses of EntityWithSources
:
Currently the properties of a section can only be listed by _properties. It might be usefull to "really" expose them by a proper method (or by removing the underscore).
Section should have a property inherited_properties
that works like properties
but without delete that provides access to all inherited properties.
Give a section s
and a property called "Type"
that has a value (type str
) of "calcium imaging"
this is how you currently get to it:
v = s['Type'].values[0].value
print(v)
# 'calcium imaging'
I would suggest that we add another way, so we have two ways of getting to properties via dict-like-access: 1) s['key']
and 2) s.props['key']
. One of them (I think the latter) should give you the actual nix.Property
while the other should apply magic[1] to directly give you back the "unpacked" value (or list of values), i.e.:
v = s['key']
print(v)
#1.0 or "str" or [1.0, 2.0, 3.0]
p = s.props['key']
print(p)
Property: {name = Type}
This is python after all. What do you guys think?
[1] with magic I mean logic
On the mission to make working with metadata as close to dicts (and pythonic) as possible there is not that much missing. For the object creation, the properties side of things has been solved with pr #101. The thing that remains is creation of sections, currently done via section.create_section('name', 'type')
Following ideas came to my mind:
Create section via __setitem__
and a tuple, i.e. s['new section'] = ('type')
. If people fear that this is too confusing to value creation (which is done via lists, i.e. s['prop'] = [1, 2, 3]
) then maybe we could introduce a dummy class (e.g. a collections.namedtuple
) with a short name (nix.S
): s['new section'] = nix.S('type')
.
I think I personally prefer the first version, i.e. the tuple based approach.
We should evaluate whether it would be more consistent to use tuple
instead of list
for properties of the python bindings that correspond to std::vector
in the c++ library. This is of course only relevant for cases where we do not use ListProxy
.
Examples:
A maybe possible solution would be to change vector_transmogrify
to convert to tuple instead of list.
Improve data access for the DataArray
and add support for reading and writing numpy arrays.
Would be nice if slicing and writing would work like in h5py.
There still some TODOs in the sphinx documentation. Remove them and replace them with nice text.
This is a list of steps for the alpha release: maybe it would be a good idea to write a shell script that does the version changes, tagging and uploading automatically and add it to the repository (one for nix and one for nixpy).
OS: OS-X
When trying to import nixpy
:
ImportError: dlopen(nix/core.so, 2): Symbol not found: __ZN3nixlsERNSt3__113basic_ostreamIcNS0_11char_traitsIcEEEERKNS_9SimpleTagE
Referenced from: nix/core.so
Expected in: flat namespace
in nix/core.so
Add bindings for DataTag
:
EntityWithSources
patches DataTag
The ZonedIO needs to be exposed in python.
We added the retrieveReference and retrieveFeatureData methods to Tags, these need to added to the bindings.
At the moment, nixpy does not work with a current build of the nix library
The fellowing code:
nix_file = nix.File.open('/home/garbers/foo.h5', nix.FileMode.ReadOnly)
profile.run('nix_file.blocks[0].metadata.has_property_by_name(\'Genotype\')')
profile.run('nix_file.sections[0].has_property_by_name(\'Genotype\')')
print nix_file.blocks[0].metadata == nix_file.sections[0]
nix_file.close()
leads to this output:
15 function calls in 0.120 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
4 0.000 0.000 0.000 0.000 :0(getattr)
1 0.000 0.000 0.000 0.000 :0(hasattr)
2 0.000 0.000 0.000 0.000 :0(isinstance)
1 0.000 0.000 0.000 0.000 :0(setattr)
1 0.000 0.000 0.000 0.000 :0(setprofile)
1 0.120 0.120 0.120 0.120 :1()
1 0.000 0.000 0.000 0.000 file.py:20(init)
1 0.000 0.000 0.000 0.000 file.py:37(blocks)
1 0.000 0.000 0.120 0.120 profile:0(nix_file.blocks[0].metadata.has_property_by_name('Genotype'))
0 0.000 0.000 profile:0(profiler)
1 0.000 0.000 0.000 0.000 proxy_list.py:18(init)
1 0.000 0.000 0.000 0.000 proxy_list.py:27(getitem)
15 function calls in 0.000 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
4 0.000 0.000 0.000 0.000 :0(getattr)
1 0.000 0.000 0.000 0.000 :0(hasattr)
2 0.000 0.000 0.000 0.000 :0(isinstance)
1 0.000 0.000 0.000 0.000 :0(setattr)
1 0.000 0.000 0.000 0.000 :0(setprofile)
1 0.000 0.000 0.000 0.000 :1()
1 0.000 0.000 0.000 0.000 file.py:27(init)
1 0.000 0.000 0.000 0.000 file.py:71(sections)
1 0.000 0.000 0.000 0.000 profile:0(nix_file.sections[0].has_property_by_name('Genotype'))
0 0.000 0.000 profile:0(profiler)
1 0.000 0.000 0.000 0.000 proxy_list.py:18(init)
1 0.000 0.000 0.000 0.000 proxy_list.py:27(getitem)
True
For some reason the call to "has_property_by_name" seems to take (way) longer when invoked through the Blocks metadata compared to being invoked on the same section directly. This issue seems to be dependent on the amount of sections present in the file as it those only "apear" for files with quite a lot of sections (therefore i do not link to foo.h5 here as it is ~150mb; you can find it on gate.g-node under /groups/wachtler/share)
I suggest that we map our nix entities to None if they are not initialized.
Add docstrings for all methods and properties written in python or added via bindings.
C++11 has multi-line string literals, which could be useful for that purpose.
I suggest we use the sphinxy (http://sphinx-doc.org/domains.html#info-field-lists) style for field list descriptions:
def foo(bar, bla):
"""
This does some nice foo.
:param str bar: Your favorite bar
:param int bla: Number of words per second
:return: A suitable foo bar.
:rtype: Bar
"""
pass
``
Implement transmorgify for DataType
to numpy type:
PyArray_DescrConverter
accepts plus DataTypeAdd bindings for SimpleTag
and Feature
:
EntityWithSources
patches SimpleTag
Block and Source should have a find method for sources that works similar to the one on the c++ lib.
Create bindings for file validation
Trying to set the label of a sampled dimension like this fails:
sd = video_data.append_sampled_dimension(1.0)
sd.label("width")
TypeError: 'NoneType' object is not callable
edit: The same applies to unit of range dimension
Dear Nix Developer Team
I was trying to use multi_tag.retrieve_data(). it retrieves wrong data.
Here is the test code.
import nix
import numpy as np
from math import pi as PI
import os
from matplotlib import pyplot as plt
sig1 = np.arange(2, 20)
fle = 'test.h5'
if os.path.isfile(os.path.join(os.getcwd(), fle)):
os.remove(fle)
nixFile = nix.File.open(fle, nix.FileMode.Overwrite)
blk = nixFile.create_block('blk1', 'testBlock')
da1 = blk.create_data_array('sig1', 'test', data=sig1)
dim = da1.append_sampled_dimension(0.1)
dim.unit = 's'
dim.offset = 0.2
pos = blk.create_data_array('pos1', 'test', data=[0.4, 0.8, 1.2])
pos.append_set_dimension()
pos.append_set_dimension()
ext = blk.create_data_array('ext1', 'test', data=[0.2, 0.2, 0.2])
ext.append_set_dimension()
ext.append_set_dimension()
tag1 = blk.create_multi_tag('tag1', 'test', pos)
tag1.extents = ext
tag1.references.append(da1)
snips = [tag1.retrieve_data(p, 0)[:] for p in range(3)]
print(snips)
The expected output here is
[array([4, 5]), array([8, 9]), array([12, 13])]
whereas the output is
[array([6, 7]), array([10, 11]), array([14, 15])]
It seems that the offset hasn't been taken into account.
Please have a look.
Cheers
Ajay
echoing G-Node/nix#542
There is a conflicting package with the name nix
on PyPi. This conflict has to be resolved.
nixpy
nixpy
?Implement an overload for create_data_array
equivalent to the old create_data
method.
The method create_data_array
should either accept a numpy array or type and size.
Probably introduced by commit 83e70c2. On OSX, with homebrew it seems the py2 boost python library is still called libboost_python.dylib
.
Is there a way to properly do this ATM.
Dear Nix Developer team
I tried to use tag.retrieve_data and got a Segmentation Fault . Here is the test code
import nix
import numpy as np
from math import pi as PI
import os
from matplotlib import pyplot as plt
fs = 1000.0
t = np.arange(0, 10, 1 / fs)
sig1 = np.random.rand(t.shape[0])
sig2 = np.sin(2 * PI * 0.5 * t)
fle = 'test.h5'
if os.path.isfile(os.path.join(os.getcwd(), fle)):
os.remove(fle)
nixFile = nix.File.open(fle, nix.FileMode.Overwrite)
blk = nixFile.create_block('blk1', 'testBlock')
da1 = blk.create_data_array('sig1', 'test', data=sig1)
dim = da1.append_sampled_dimension(1 / fs)
dim.unit = 's'
da2 = blk.create_data_array('sig2', 'test', data=sig2)
dim = da2.append_sampled_dimension(1 / fs)
dim.unit = 's'
tag1 = blk.create_tag('tag1', 'test', [2])
tag1.extent = [0.5]
tag1.references.append(da1)
tag1.references.append(da2)
snip1 = tag1.retrieve_data(0)
t1 = np.linspace(0, tag1.extent[0], snip1.shape[0]) + tag1.position[0]
plt.plot(t1, snip1)
plt.show()
Please help me.
Thanks
Ajay
Properties could be accessible directly from the section, further it would be nice to access properties also by their names as it is possible in the python-odml library.
sec = ...
sec.create_property("foo")
p = sec["foo"]
# instead of sec.properties["foo"]
Dear Nix developer team
I tried to build nixpy and a test failed. Here are some details:
nix version installed: commit 7fd231bc753ed4974f5538b3e574c2ef1865bb92
nixpy version tried: commit 4a0e42d
Here is test output:
~/repos/nixpy$ python setup.py test
running test
running egg_info
writing nix.egg-info/PKG-INFO
writing top-level names to nix.egg-info/top_level.txt
writing dependency_links to nix.egg-info/dependency_links.txt
reading manifest file 'nix.egg-info/SOURCES.txt'
writing manifest file 'nix.egg-info/SOURCES.txt'
running build_ext
copying build/lib.linux-x86_64-2.7/nix/core.so -> nix
test_block_data_arrays (nix.test.test_block.TestBlock) ... ok
test_block_definition (nix.test.test_block.TestBlock) ... ok
test_block_eq (nix.test.test_block.TestBlock) ... ok
test_block_find_sources (nix.test.test_block.TestBlock) ... ok
test_block_id (nix.test.test_block.TestBlock) ... ok
test_block_multi_tags (nix.test.test_block.TestBlock) ... ok
test_block_name (nix.test.test_block.TestBlock) ... ok
test_block_sources (nix.test.test_block.TestBlock) ... ok
test_block_tags (nix.test.test_block.TestBlock) ... ok
test_block_timestamps (nix.test.test_block.TestBlock) ... ok
test_block_type (nix.test.test_block.TestBlock) ... ok
test_data_array_coefficients (nix.test.test_data_array.TestDataArray) ... ok
test_data_array_data (nix.test.test_data_array.TestDataArray) ... ok
test_data_array_definition (nix.test.test_data_array.TestDataArray) ... ok
test_data_array_dimensions (nix.test.test_data_array.TestDataArray) ... ok
test_data_array_dtype (nix.test.test_data_array.TestDataArray) ... ok
test_data_array_eq (nix.test.test_data_array.TestDataArray) ... ok
test_data_array_exp_origin (nix.test.test_data_array.TestDataArray) ... ok
test_data_array_id (nix.test.test_data_array.TestDataArray) ... ok
test_data_array_label (nix.test.test_data_array.TestDataArray) ... ok
test_data_array_name (nix.test.test_data_array.TestDataArray) ... ok
test_data_array_sources (nix.test.test_data_array.TestDataArray) ... ok
test_data_array_timestamps (nix.test.test_data_array.TestDataArray) ... ok
test_data_array_type (nix.test.test_data_array.TestDataArray) ... ok
test_data_array_unit (nix.test.test_data_array.TestDataArray) ... ok
test_range_dimension (nix.test.test_dimensions.TestDimensions) ... FAIL
test_sample_dimension (nix.test.test_dimensions.TestDimensions) ... ok
test_set_dimension (nix.test.test_dimensions.TestDimensions) ... ok
test_feature_data (nix.test.test_feature.TestFeature) ... ok
test_feature_eq (nix.test.test_feature.TestFeature) ... ok
test_feature_id (nix.test.test_feature.TestFeature) ... ok
test_feature_link_type (nix.test.test_feature.TestFeature) ... ok
test_file_blocks (nix.test.test_file.TestFile) ... ok
test_file_find_sections (nix.test.test_file.TestFile) ... ok
test_file_format (nix.test.test_file.TestFile) ... ok
test_file_sections (nix.test.test_file.TestFile) ... ok
test_file_timestamps (nix.test.test_file.TestFile) ... ok
test_multi_tag_definition (nix.test.test_multi_tag.TestMultiTag) ... ok
test_multi_tag_eq (nix.test.test_multi_tag.TestMultiTag) ... ok
test_multi_tag_extents (nix.test.test_multi_tag.TestMultiTag) ... ok
test_multi_tag_feature_data (nix.test.test_multi_tag.TestMultiTag) ... ok
test_multi_tag_features (nix.test.test_multi_tag.TestMultiTag) ... ok
test_multi_tag_id (nix.test.test_multi_tag.TestMultiTag) ... ok
test_multi_tag_name (nix.test.test_multi_tag.TestMultiTag) ... ok
test_multi_tag_positions (nix.test.test_multi_tag.TestMultiTag) ... ok
test_multi_tag_references (nix.test.test_multi_tag.TestMultiTag) ... ok
test_multi_tag_retrieve_data (nix.test.test_multi_tag.TestMultiTag) ... ok
test_multi_tag_timestamps (nix.test.test_multi_tag.TestMultiTag) ... ok
test_multi_tag_type (nix.test.test_multi_tag.TestMultiTag) ... ok
test_multi_tag_units (nix.test.test_multi_tag.TestMultiTag) ... ok
test_property_definition (nix.test.test_property.TestProperty) ... ok
test_property_eq (nix.test.test_property.TestProperty) ... ok
test_property_id (nix.test.test_property.TestProperty) ... ok
test_property_mapping (nix.test.test_property.TestProperty) ... ok
test_property_name (nix.test.test_property.TestProperty) ... ok
test_property_values (nix.test.test_property.TestProperty) ... ok
test_value_attrs (nix.test.test_property.TestValue) ... ok
test_value_bool (nix.test.test_property.TestValue) ... ok
test_value_float (nix.test.test_property.TestValue) ... ok
test_value_int (nix.test.test_property.TestValue) ... ok
test_value_str (nix.test.test_property.TestValue) ... ok
test_proxy_list_contains (nix.test.test_proxy_list.TestProxyList) ... ok
test_proxy_list_delitem (nix.test.test_proxy_list.TestProxyList) ... ok
test_proxy_list_getitem (nix.test.test_proxy_list.TestProxyList) ... ok
test_proxy_list_iterators (nix.test.test_proxy_list.TestProxyList) ... ok
test_proxy_list_len (nix.test.test_proxy_list.TestProxyList) ... ok
test_proxy_list_str (nix.test.test_proxy_list.TestProxyList) ... ok
test_section_definition (nix.test.test_section.TestSection) ... ok
test_section_eq (nix.test.test_section.TestSection) ... ok
test_section_find_sections (nix.test.test_section.TestSection) ... ok
test_section_id (nix.test.test_section.TestSection) ... ok
test_section_mapping (nix.test.test_section.TestSection) ... ok
test_section_name (nix.test.test_section.TestSection) ... ok
test_section_properties (nix.test.test_section.TestSection) ... ok
test_section_repository (nix.test.test_section.TestSection) ... ok
test_section_sections (nix.test.test_section.TestSection) ... ok
test_section_type (nix.test.test_section.TestSection) ... ok
test_source_definition (nix.test.test_source.TestSource) ... ok
test_source_eq (nix.test.test_source.TestSource) ... ok
test_source_find_sources (nix.test.test_source.TestSource) ... ok
test_source_id (nix.test.test_source.TestSource) ... ok
test_source_name (nix.test.test_source.TestSource) ... ok
test_source_sources (nix.test.test_source.TestSource) ... ok
test_source_timestamps (nix.test.test_source.TestSource) ... ok
test_source_type (nix.test.test_source.TestSource) ... ok
test_sources_extend (nix.test.test_source.TestSource) ... ok
test_tag_definition (nix.test.test_tag.TestTag) ... ok
test_tag_eq (nix.test.test_tag.TestTag) ... ok
test_tag_extent (nix.test.test_tag.TestTag) ... ok
test_tag_features (nix.test.test_tag.TestTag) ... ok
test_tag_id (nix.test.test_tag.TestTag) ... ok
test_tag_name (nix.test.test_tag.TestTag) ... ok
test_tag_position (nix.test.test_tag.TestTag) ... ok
test_tag_references (nix.test.test_tag.TestTag) ... ok
test_tag_retrieve_feature_data (nix.test.test_tag.TestTag) ... ok
test_tag_timestamps (nix.test.test_tag.TestTag) ... ok
test_tag_type (nix.test.test_tag.TestTag) ... ok
test_tag_units (nix.test.test_tag.TestTag) ... ok
test_name_check (nix.test.test_util.TestUtil) ... ok
test_name_sanitizer (nix.test.test_util.TestUtil) ... ok
test_unit_is_atomic (nix.test.test_util.TestUtil) ... ok
test_unit_is_compound (nix.test.test_util.TestUtil) ... ok
test_unit_is_si (nix.test.test_util.TestUtil) ... ok
test_unit_sanitizer (nix.test.test_util.TestUtil) ... ok
test_unit_scalable (nix.test.test_util.TestUtil) ... ok
test_unit_scaling (nix.test.test_util.TestUtil) ... ok
test_unit_split (nix.test.test_util.TestUtil) ... ok
test_unit_split_compound (nix.test.test_util.TestUtil) ... ok
======================================================================
FAIL: test_range_dimension (nix.test.test_dimensions.TestDimensions)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/ajay/repos/nixpy/nix/test/test_dimensions.py", line 104, in test_range_dimension
assert(self.range_dim.index_of(10.) == (round(10./3.14)))
AssertionError
----------------------------------------------------------------------
Ran 108 tests in 1.113s
FAILED (failures=1)
Please have a look
Thanks
Ajay
We currently cannot handle unicode arguments, e.g.:
da = self._create_data_array(name, array_type, dtype, shape)
Boost.Python.ArgumentError: Python argument types in
Block._create_data_array(Block, unicode, str, numpy.dtype, tuple)
did not match C++ signature:
_create_data_array(nix::Block {lvalue}, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nix::DataType, nix::NDSizeBase<unsigned long long>)
Id like to suggest methods which receive a value and return all sections/blocks/data_arrays that contain that value. Something like:
def get_sections_by_value(value, nix_file):
return nix_file.find_sections(lambda x:any([any([value in i for i in
e.values]) for e in
x._properties]))
def get_blocks_by_value(value, nix_file):
return filter(lambda x:len(get_sections_by_value(value, x.metadata))>0,
nix_file.blocks)
but with all the corner cases and type issues solved and of course, well not in python. I think "give me all recordings in which i wrote something like whatever" is quite a usual use case. (Yes i know that this is most probaly non trivial)
We broke nixpy
Look here:
import nix
fd = nix.File.open('test.h5', nix.FileMode.Overwrite)
b = fd.create_block('b', 'notype')
d = b.create_data_array('da', 'stillnotype')
d = b.create_data_array('da', 'stillnotype', nix.DataType.Double, (0,0))
d[:, :] = np.ones((23, 42))
d[...]
# Out: array([], shape=(0, 0), dtype=float64)
d2 = b.create_data_array('da', 'stillnotype', nix.DataType.Double, (12,13))
d2 = b.create_data_array('da2', 'stillnotype', nix.DataType.Double, (12,13))
d2[:, :] = np.ones((23, 42))
d2[...]
d2.shape
# Out: (12, 13)
Block and Section should have a find method for sections that works similar to the one on the c++ lib.
I came across this error, when I looped over several files, extracted data_arrays from them, and assigned them to the same variable.
Setting them to None solved the problem.
HDF5-DIAG: Error detected in HDF5 (1.8.11) thread 139774801626944:
#000: ../../../src/H5A.c line 2589 in H5Aexists(): not a location
major: Invalid arguments to routine
minor: Inappropriate type
#001: ../../../src/H5Gloc.c line 195 in H5G_loc(): invalid group ID
major: Invalid arguments to routine
minor: Bad value
HDF5-DIAG: Error detected in HDF5 (1.8.11) thread 139774801626944:
#000: ../../../src/H5A.c line 2589 in H5Aexists(): not a location
major: Invalid arguments to routine
minor: Inappropriate type
#001: ../../../src/H5Gloc.c line 195 in H5G_loc(): invalid group ID
major: Invalid arguments to routine
minor: Bad value
HDF5-DIAG: Error detected in HDF5 (1.8.11) thread 139774801626944:
#000: ../../../src/H5A.c line 551 in H5Aopen(): not a location
major: Invalid arguments to routine
minor: Inappropriate type
#001: ../../../src/H5Gloc.c line 195 in H5G_loc(): invalid group ID
major: Invalid arguments to routine
minor: Bad value
Traceback (most recent call last):
File "detect_peak_troughs_hdf5.py", line 47, in <module>
print trough_array
RuntimeError: unidentifiable C++ exception
Dear Nix Developer team
When trying to create a multitag with a name that already exists in the parent block, sometimes I get
RuntimeError: Duplicate name given - names have to be unique for a given entity type & parent. (createMultiTag)
and some other times:
RuntimeError:
Please have a look and fix this.
Thanks
Ajay
nix_file = nix.File.open('foo.h5', nix.FileMode.Overwrite)
nix_file = nix.File.open('foo.h5', nix.FileMode.Overwrite)
Does not happen with ReadWrite or ReadOnly. But happens with combination of the Read* and Overwrite.
Implement bindings for Group as introduced by G-Node/nix#558
the previously reported bug of empty exceptions does no longer exist. Thus, the wrapper can again be simplified.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.