jwadhams / json-logic-js Goto Github PK
View Code? Open in Web Editor NEWBuild complex rules, serialize them as JSON, and execute them in JavaScript
License: MIT License
Build complex rules, serialize them as JSON, and execute them in JavaScript
License: MIT License
I'm wrestling with a problem that is really keeping me from just going crazy with json-logic.
I'm performing lookup and matching between data found in item A and data available in item B.
A:
{ id: 1, name: foo, has_category: true }
B:
{ funny: [1,2,3], dumb: [1,4,5] }
The problem is, I want to use a jsonlogic rule to build a jsonlogic rule.
{ if: [
{ var: A.has_category }, { or: [
{ in: [ {var: A.id}, {var: B.funny} ] },
{ in: [ {var: A.id}, {var: B.dumb} ] }
]
}
]
}
So I want to run this if rule against data A, and get back the following result:
{ or: [
{ in: [ 1, {var: funny} ] },
{ in: [ 1, {var: dumb} ] }
]
}
I've played around with a few ideas and I have an ugly work-around, but I'm wondering if you've come across anything like this and have a good alternative.
Great work so far, I'm really interested in seeing where it can go.
I'm interested in formatting some test in a js format, based upon chai. Would it be possible to extend operations to expose chai's API ?
If so, every "parameter" which is not a logic itself would be used in an ordered way by chai's call
Is this possible ?
Thanks ๐
Does anyone know how do I pass in the data by using "var" inside "filter"? because the "var" inside filter alw default to the filtering array elements. Eg the rules and data as below:
Rules:
{ "filter": [ [ { "min": 1, "max": 1, "value": "a" }, { "min": 2, "max": 2, "value": "b" } ], {"<=":[{"var":"min"},{"var": "input"},{"var": "max"}]} ] }
Data:
{input: 1}
Hey,
I created a PR over on the ruby version of this, but I'm not sure that repo is still maintained. It actually doesn't pass the test.json tests you offer, and has many bugs that made it unusable for me.
I forked his version and got it to fully pass your test.json, and fixed a lot of the bugs in the current one which was keeping my production app from working. Can you check it out, or get Kenneth to merge it in so it can help others? I also don't like my Gemfile pointing at a Github repo(my own).
Thanks!
In the playground, I tried:
Rule:
{"max":{"var": "a"}}
Data:
{"a":[1,2,3,4,5]}
Expected Result: 5
Actual Result: null
When using the number comparisons >
, >=
, <
, and <=
will return true for null
values in some cases. For instance:
{"<": [null, 2]} === true
I understand that this is the behavior is consistent for JavaScript, but I can't call this logically consistent. I would call this more of a behavioral quirk of JavaScript.
I believe that the proper response for a null
value in these number comparisons should return false
.
Currently, "in" supports these cases:
Primitive element in array: {"in":[ "Ringo", ["John", "Paul", "George", "Ringo"] ]}
Substring in string: {"in":["Spring", "Springfield"]}
However, if the array you are testing for containment holds objects, in
doesn't work:
{"in": [ {"a": 1}, [ { "a":1 }, { "b":2 } ] ] }
This gives the error Unrecognized operation a
It seems like it could also support testing for the existence of a key in an object:
{"in": [ "a", { "a":1, "b":2 } ] }
Which also gives the same Unrecognized operation a
error.
I am writing a new parser for json-logic in Kotlin, and while studying the code, I come up with this question.
https://github.com/jwadhams/json-logic-js/blob/master/logic.js#L281
Is it possible to use JSONLogic as a query language to filter JSON? Something like this:
var data =
[
{
"id": 1,
"name": "Oliver",
"email": "[email protected]"
},
{
"id": 2,
"name": "Jack",
"email": "[email protected]"
},
{
"id": 3,
"name": "Harry",
"email": "[email protected]"
},
{
"id": 4,
"name": "Jacob",
"email": "[email protected]"
},
{
"id": 5,
"name": "Charlie",
"email": "[email protected]"
},
{
"id": 6,
"name": "Thomas",
"email": "[email protected]"
},
{
"id": 7,
"name": "George",
"email": "[email protected]"
},
{
"id": 8,
"name": "Oscar",
"email": "[email protected]"
},
{
"id": 9,
"name": "James",
"email": "[email protected]"
},
{
"id": 10,
"name": "William",
"email": "[email protected]"
}
]
var filter =
{"or": [
{"and": [
{">=": [
{"var": "id"}, 3
]},
{"<=": [
{"var": "id"}, 5
]}
]},
{">": [
{"var": "id"}, 7
]}
]};
jsonLogic.filter(filter, data);
It should return:
[
{
"id": 3,
"name": "Harry",
"email": "[email protected]"
},
{
"id": 4,
"name": "Jacob",
"email": "[email protected]"
},
{
"id": 5,
"name": "Charlie",
"email": "[email protected]"
},
{
"id": 8,
"name": "Oscar",
"email": "[email protected]"
},
{
"id": 9,
"name": "James",
"email": "[email protected]"
},
{
"id": 10,
"name": "William",
"email": "[email protected]"
}
]
var jsonLogic = require('json-logic-js')
var score = 0
var rule = {
// if count.length > 5 => +10; otherwise -10
"+": [score, {
"if": [{
">": [{
"var": "count.length"
}, 5]
}, 10, -10]
}],
// if count2.length > 5 => +20; otherwise -20
"+": [score, {
"if": [{
">": [{
"var": "count2.length"
}, 5]
}, 20, -20]
}]
};
var data = {
count: [1, 2, 3, 4],
count2: [1, 2, 3, 4, 5, 6, 7]
}
console.log(jsonLogic.apply(rule, data));
I'm getting 20
as output. Any idea how to run this through a set of rules?
For really large rule sets, it might be preferable to change the behavior to only evaluate AND until the first false
, and OR until the first true
. (Right rules are evaluated with depth-first recursion before we even consider what the operator is.)
This changes from a performance opportunity to a genuine problem the moment the library includes state changing operations. e.g., right now both consequents of a ternary are evaluated.
I'm looking to be able to do something like return true for the following:
jsonLogic.apply(
{"===":[null,{"method": [{"method":[{"var":"a"},"match",["(.)(.)(.)?(.)"]]},"slice",[3,4]]}]}
, {"a": "abc"}
);
has anyone been able to integrate this beauty with ionic or angular ? if so how ?
thanks in advance !!
Cheers
Been using the lib nicely in IE and Chrome but found a serious bug in Safari (v9.1.1).
var logic = {
"and": [
{ "==": [ {"var": "foo"}, 0 ] },
{ "==": [ {"var": "bar" }, 0] }
]
};
var data = {
"foo": 0,
"bar": 0
};
jsonLogic.apply(logic, data) // returns 2 in Safari
Change 0 to a 1 returns false. Truthy logic can overcome this issue.
But the real issue is the 'or' operator
var logic = {
"or": [
{ "==": [ {"var": "foo"}, 0 ] },
{ "==": [ {"var": "bar" }, 0] }
]
};
var data = {
"foo": 1,
"bar": 1
};
jsonLogic.apply(logic, data) // should return false but returns 2 in Safari, a truthy value. Ug.
Difficult to trace this given the recursion. Any clues?
Should be able to start the dev process by simply typing "gulp." Would invoke 'watch' on invocation.
Please lint and minify the source code.
Curious about if/how JsonLogic might support regex. For the in
operator, the following example is given:
{"in":[ "Ringo", ["John", "Paul", "George", "Ringo"] ]}
There may be situations where it is more succinct to represent a match by regex (e.g. matching ICD-9 codes). Working with the same example above, is there a way that the current specification would support regex? For example, something like:
{"regex":[ "\w+(ing)\w+", ["John", "Paul", "George", "Ringo"] ]}
Would you consider altering the specification there isn't a way to currently support?
Hi,
New to Github... I'm using a fork of jsonLogic for a product configurator we're developing, which will need regular updates of the rule set, so it fits our needs.
I've added two small features that we found handy: 1) the ability to have comments in the JSON file to explain complex rules and 2) a (still rather coarse) way of reporting which rule(s) fail when the result is false.
Perhaps this may be useful to others too?
Since JSON doesn't allow comments, I've basically just added the operators // and # which don't do anything. This allows me to add 'comments' like this:
{"//": [
"THIS IS A SAMPLE COMMENT",
"AND THE SECOND LINE OF THIS COMMENT. OR EVEN A THIRD...",
"OR A NEW COMMENT, WHATEVER YOU WISH!"
]}
Not a paragon of elegance, but it does the trick.
The trace method I added simply returns a list of the rule(s) that failed with expected value and the actual value.
Cheers,
Elco
What is the current behavior if my rule includes a var
which is not in the data set?
For example in the playground:
{
"<": [{ "var": "LDLDiffPercentage" }, 0.5]
}
Returns true
even without any data. I guess it has a default value of 0
?
Is there a way to make it FAIL when a variable is missing?
Hi,
Thank you for your amazing work.
Since I wasn't successful trying to get what I need, I am posting this here.
Take this data as example:
{
"if": [
{
"and": [
{
"==": [
{
"var": "benefit"
},
"gold"
]
},
{
"==": [
{
"var": "animal"
},
"cat"
]
}
]
},
"Export Rule 1",
{
"and": [
{
"==": [
{
"var": "benefit"
},
"gold"
]
},
{
"==": [
{
"var": "animal"
},
"dog"
]
}
]
},
"Export Rule 2",
"Export Rule Default"
]
}
Now, if I do something like:
{"benefit":"gold", "animal":"cat" }
I'll get the rule "Export Rule 1". Okay, nice, that's the expected behavior.
Now imagine that I need all the rules that have the benefit gold. How I can get it? In this case, I was expecting to get one array or something like that with "Export Rule 1" and "Export Rule 2". Is this possible to do?
I am also defining the data structure, so I am able to change it if necessary (for example, changing the "if" or "and" or something else that makes sense.
Thank you for your reply \o/
https://developers.google.com/blockly/
Would love to see a blockly visual UI for constructing the logic.
Has anyone done any work on this?
This blockly does JSON creation and could be a start...
http://ens-lg4.github.io/MenulyJSON/
I'm curious, what do you think about setting up a wiki page on this repo to collect various operations people come up with? I noticed that there are a few different pull requests where people have offered things, but you haven't opted to put them into the core library. If we had a wiki page where they were all listed, it would be discoverable by new users and if we made some sort of process to vote on them or say whether you were using one, then maybe it would be easier to determine if one should become core eventually?
I have this rule
{"reduce":[
{"var":"myArray"},
{"+":[{"+" : {"var":"current"}}, {"var":"accumulator"}]},
0
]}
Values: {"myArray":[0.1,0.7]}
But Output: 0.7999999999999999
why? should not give 0.8? Is there any expression to round up?
if i have {"myArray":[0.1,0.3]} --> output: 0.4 OK
but if {"myArray":[11.11,22.63]} --> output: 33.739999999999995 ??
Given the following rule:
{ "in": [ "1", { "var": "MyData.Values" } ] }
Using it on the following data will cause an error when, IMO, it should return false;
{
"MyData": {
"Values": null
}
}
Should be easy enough to check for a null/undefined data set before testing the "in" operation and return false if necessary.
This may also be a problem with other supported array operations. Although, I have not tested them to see.
I believe it should be possible to programmatically serialize a subset of Javascript (a function that returns a Number or Boolean and contains no loops or external function calls) into json logic, no?
This would make storing and sandboxed execution of simple things nice.
Any thoughts before I begin work?
Hi,
Is it possible that statement if
render an object ? For example :
{
if : [
test, // true or false
{ myProp : "OK" }
]
}
but json-logic try to apply function myProp.
I've tried Object.defineProperty( {}, "myProp", { value : "OK" })
...
it would be really helpful to have bitwise operations:
https://www.w3schools.com/js/js_bitwise.asp
As example: Currently creating for example XOR is quite complicated.
With "^" xor (javascript operator) and n entries:
{"^":[1,0,0,0,0]} -> 1
{"^":[1,0,0,1,0]} -> 0
Scenario:
Would be super handy to have a function that returns the SQL given a "logic" object!
I have installed json-logic-js like this:
npm install json-logic-js
but how can I import it?
I have tried these but still not working:
import {jsonLogic} from 'json-logic-js/logic.js'
import {jsonLogic} from 'json-logic-js'
It would be nice to have an ability to write a rule like 'if the average of values is > 15'
The license of the project says:
"The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software."
but the main logic.js file does not do that :(
This evaluates to false:
{
"==": [
[ ],
[ ]
]
}
This evaluates to true:
{
"==": [
[ ],
""
]
}
Hi,
I love the idea of json-logic-js.. however, my users might not want the learning curve of having to learn the syntax.
I was wondering if there is anyone that has built some sort of web interface that compiles down to json-logic and could share it, or if something like an 'Excel like' formula builder with autocomplete was something anyone would consider doing.
This might not be the place to ask for this, but could not think of other place.
Thanks!
I found an interesting result after applying the following json object to evaluate non-existing property in some object.
conditions = {
"<": [
{ "var": "userID" },
2
]
}
json_logic.apply( conditions , { "someProperty": 10} );
the apply function returns true. although passed object doens't even contain "userID"!
is there a way to restrict the apply function to match only the data objects that have exactly the set of attributes that i want, and do then my evaluation on theier values?
thanks in advance
Not sure whether this is the correct place to signal this, but I don't really find an alternative channel:
I've wrote a ruby parser for json-logic, it's located here. I'll be releasing a first version of the gem somewhere this week.
Just wanted to point out that I'm very happy to accept PR's and open to suggestions.
Thanks!
Hi,
We are currently using jsonLogic as a rule engine where our customers can inject data and rules.
The method operator creates a security issue as we can not avoid side effects on our back end if java script code is injected.
is it possible to secure this feature ?
regards
Sebastien
eg. I want to have a set of rules and have data running through all of them.
a
== 1 will multiply price by 2b
== 2 will multiply price by 3if i pass data as {a: 1, b: 2, price: 100}, price will be 600.
How can i do this with json-logic?
Could you please rename the main file from logic.js
to json-logic.js
?
Is there a way for my rule to compute some numerical value?
For example imagine an e-commerce computing a percentage discount based on a rule.
I didn't notice whether you had or planned to develop functions that included arrays that contained objects.
So for example if wanted to return true if there is an apple pie in group of pies:
var rules = { "and" : [
{"<" : [ { "var" : "temp" }, 110 ]},
{"==" : [ { "var" : "pies.filling" }, "apple" ] }
] };
var data = { "temp" : 100, "pies" : [{ "filling" : "apple" }, { "filling" : "cherry" }]};
jsonLogic.apply(rules, data);
// true
One of my developers ran into a problem with my API that uses json-logic for parsing.
In the normal case, they might have a query such as these:
{"~": [{"var": "hierarchies"}, "Geo.AMER.USA.*"]}
{"~": [{"var": "hierarchies"}, "Geo.EMEA.*"]}
{"~": [{"var": "hierarchies"}, "Alternate.Favorites.*"]}
And when they read that query in, they can easily re-build the query form by just interpreting the value where the first token is the hierarchy to be selected (Geo or Alternate).
The problem comes when the user builds a query that is selecting individual devices instead of hierarchy folders:
{"and": [{"or": [[{"==": [{"var": "device_id"}, "9895bb67-93a7-4bde-86d8-c9b2fe8d4667"]}]]}]}
If they select a device, we don't care what hierarchy it is in for the query itself, but the user found the device by drilling through the hierarchy, and when we rebuild the query form for them to edit, they should see the same hierarchy they originally selected it from.
So my solution is to add a new operator for json-logic called "meta". The logic for it is that it takes two arguments, and always returns the first argument for further evaluation while the second is completely ignored.
{"and": [{"or": [[{"==": [{"meta":[{"var": "device_id"},{"hierarchy":"Flat_List"}]}, "9895bb67-93a7-4bde-86d8-c9b2fe8d4667"]}]]}]}
// or even
{"meta":[{"and": [{"or": [[{"==": [{"var": "device_id"}, "9895bb67-93a7-4bde-86d8-c9b2fe8d4667"]}]]}]},{"hierarchy":"Flat_List","happy_attr":[1,2,3]}]}
In some ways, this is similar to log, but I didn't want to use log because that has a side-effect of writing stuff to the log. ;)
This seemed like it might be useful enough in the general case so I thought I'd also open an issue for it.
examples like this
jsonLogic.apply(
{ "var" : ["a"] }, // Rule
{ a : 1, b : 2 } // Data
);
// 1
should be written like this
jsonLogic.apply(
{ "var" : ["a"] }, // Rule
{ "a" : 1, "b" : 2 } // Data
);
// 1
so they can be copied and pasted into the "play with it" page
Would be awesome with "selecct examples" dropdown on http://jsonlogic.com/play.html so I dont have to start from scratch - but can poke around with different examples...
Does an official JSON Schema (http://json-schema.org/) currently exists for json-logic syntax?
If not, do you think it would be possible?
Some rules may want to include validation of data types. Imagine:
"typeof": [ "a", "string" ]
-- evaluates to true if "a" is a string or not.
I was trying to find a way to store simple automation rules in the database and pass them between UI and backend. And json-logic seems to be a perfect fit for that purpose.
So I took the Python port of it and found out it was not working as expected in some cases.
Trying to mend the port by creating a pull request I referred to this repo to get the etalon behaviour.
But I soon found out that some operators (only numeric operations so far) behave inconsistently or are dependent on JavaScript logic. While they should probably be following human (or Vulcan :) ) logic to make json-logic language-independent.
Here are some examples that I've tested using the "Play with It" page:
Arithmetic:
"+":
{"+": []} = 0 // Should be null, cannot calculate the sum of nothing
{"+": [2]} = 2 // OK
{"+": [2,3]} = 5 // OK
{"+": [2,3,4]} = 9 // OK, chainable
{"+": [2,3,4,5]} = 14 // OK
{"+": [null]} = null // OK, cannot calculate the sum of nothing
{"+": [2,null,4]} = null // OK, cannot calculate the sum of numbers and nothing
"-":
{"-": []} = null // OK, cannot calculate the difference of nothing
{"-": [10]} = -10 // OK, described in the docs as negation
{"-": [10,2]} = 8 // OK
{"-": [10,2,3]} = 8 // Should be 5, as subtraction should also be "chainable" like addition
{"-": [10,2,3,4]} = 8 // Should be 1, see above
{"-": [null]} = 0 // Should be null, cannot calculate the difference of nothing; compare to results for {"+": [null]}
{"-": [2,null,4]} = 2 // Should be null, cannot calculate the difference of numbers and nothing
"*":
{"*": []} = no output // Should be null, cannot calculate the product of nothing
{"*": [2]} = 2 // OK
{"*": [2,3]} = 6 // OK
{"*": [2,3,4]} = 24 // OK, chainable
{"*": [2,3,4,5]} = 120 // OK
{"*": [null]} = null // OK, cannot calculate the product of nothing; compare to results for {"-": [null]}
{"*": [2,null,4]} = null // OK, cannot calculate the product of numbers and nothing, compare to results for {"-": [2,null,4]}
"/":
{"/": []} = null // OK, cannot calculate the quotient of nothing
{"/": [10]} = null // Should be 10, compare to results for {"*": [2]}
{"/": [10,2]} = 5 // OK
{"/": [10,2,4]} = 5 // Should be 1.25, as division should also be "chainable" like addition or multiplication
{"/": [10,2,4,5]} = 5 // Should be 0.25, see above
{"/": [null]} = null // OK, cannot calculate the quotient of nothing; compare to results for {"-": [null]}
{"/": [2,null,4]} = null // OK, cannot calculate the quotient of numbers and nothing, compare to results for {"-": [2,null,4]}
"%":
{"%": []} = null // OK, cannot divide nothing
{"%": [10]} = null // Should be 10, compare to results for {"*": [2]}
{"%": [10,4]} = 2 // OK
{"%": [10,4,2]} = 2 // Should be 0, as module should also be "chainable"
{"%": [null]} = null // OK, cannot calculate divide nothing
{"%": [2,null]} = null // OK, cannot divide numbers by nothing
{"%": [null,2]} = 0 // Should be null, cannot divide nothing by numbers
Comparison:
">":
{">": []} = false // OK, cannot compare nothing
{">": [5]} = false // OK
{">": [5,2]} = true // OK
{">": [5,2,3]} = true // Should be false, should be chainable, see results of {"<": [2,6,5]}
{">": [5,2,4,3]} = true // Should be false, see above; not sure whether 3+ element chaining should be allowed
{">": [null]} = false // OK, one cannot compare nothing
{">": [5,null]} = true // Should be false, cannot compare numbers to nothing
">=":
{">=": []} = false // OK, cannot compare nothing
{">=": [5]} = false // OK
{">=": [5,2]} = true // OK
{">=": [5,2,3]} = true // Should be false, should be chainable, see results of {"<": [2,6,5]}
{">=": [5,2,4,4]} = true // Should be false, see above; not sure whether 3+ element chaining should be allowed
{">=": [null]} = false // OK, cannot compare nothing
{">=": [5,null]} = true // Should be false, cannot compare numbers to nothing
"<":
{"<": []} = false // OK, cannot compare nothing
{"<": [2]} = false // OK
{"<": [2,5]} = true // OK
{"<": [2,6,5]} = false // OK, chainable, see results of {">": [5,2,3]}
{"<": [2,5,6,1]} = true // Should be false, last element is less than the previous; not sure whether 3+ element chaining should be allowed
{"<": [null]} = false // OK, cannot compare nothing
{"<": [null,2]} = true // Should be false, cannot compare numbers to nothing
"<=":
{"<=": []} = false // OK, cannot compare nothing
{"<=": [2]} = false // OK
{"<=": [2,5]} = true // OK
{"<=": [2,6,5]} = false // OK, chainable, see results of {">": [5,2,3]}
{"<=": [2,5,6,1]} = true // Should be false, last element is less than the previous; not sure whether 3+ element chaining should be allowed
{"<=": [null]} = false // OK, one cannot compare nothing
{"<=": [null,2]} = true // Should be false, cannot compare numbers to nothing
Min/max:
"min":
{"min": []} = null // OK, cannot choose from nothing
{"min": [2]} = 2 // OK
{"min": [3,2]} = 2 // OK
{"min": [4,3,2]} = 2 // OK, chainable
{"min": [5,4,3,2]} = 2 // OK, chainable
{"min": [null]} = 0 // Should be null, null is not 0
{"min": [5,null]} = 0 // Should be null, cannot choose lowest from numbers and nothing
"max":
{"max": []} = null // OK, cannot choose from nothing
{"max": [2]} = 2 // OK
{"max": [2,3]} = 3 // OK
{"max": [2,3,4]} = 4 // OK, chainable
{"max": [2,3,4,5]} = 5 // OK, chainable
{"max": [null]} = 0 // Should be null, null is not 0
{"max": [5,null]} = 5 // Should be null, cannot choose highest from numbers and nothing
P.S.: Comments above assume that all null
values must be treated as bad values for arithmetic. But if users want to treat null
as 0
or 1
they may always use the default value argument for "var"
.
I think that code for those operators should be reviewed to ensure etalon, language/platform-independent behaviour of json-logic.
What's your opinion, @jwadhams?
I'm not sure if you have put supported browsers anywhere. But FYI Array.map is not supported IE8.
The general idea is to support the usage of date variables passed in as strings with some form of operator/type specifier to identify them as dates. The primary goal is to support comparison operators.
Example:
{"<":[{"date": "2016-10-01T03:24:00.000Z"}, {"date": "2016-10-15T03:24:00.000Z"}]}
Prototype:
"date" : function(a) {
return(new Date(a));
}
Example with var - works with date function in place:
rule: {"<":[{"date":{"var":"submitDate"}}, {"date":{"var": "dueDate"}}]}
data: {"submitDate":"2016-10-01T03:24:00.000Z","dueDate":"2016-10-15T03:24:00.000Z"}
I expected the following to evaluate to true
:
Data:
{"input": "x"}
Rule:
{
"and": [
{
"some": [
[
"x",
"y"
],
{
"===": [
{
"var": ""
},
{
"var": "input"
}
]
}
]
}
]
}
If I use a literal value instead of "var": "input"
, it does evaluate to true
:
{
"and": [
{
"some": [
[
"x",
"y"
],
{
"===": [
{
"var": ""
},
"x"
]
}
]
}
]
}
Has there been interest, proposals or work done to port json-logic to golang?
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.