Giter VIP home page Giter VIP logo

libshared's People

Contributors

dependabot[bot] avatar djmitche avatar felixschurk avatar ivan-cukic avatar janikrabe avatar lauft avatar laurence6 avatar mrossinek avatar neheb avatar oxalica avatar pbeckingham avatar recollir avatar smemsh avatar sruffell avatar tbabej avatar thesamesam avatar vrusinov avatar wictory avatar wodny avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libshared's Issues

Implement Bright Foreground Colors.

The _COLOR_BRIGHT flag should be separated into _COLOR_FGBRIGHT and _COLOR_BGBRIGHT to allow accessing the upper 8 colors in ANSI mode. Particularly this allows access to bright and bold colors.

The output coding currently as:

result += colorstring[(29 + (_value & _COLOR_FG))];
would then be changed to:

    result += colorstring[((_value & _COLOR_FGBRIGHT ? 89 : 29) + (_value & _COLOR_FG))];

Currently it's possible to trick the existing code into giving bright and bold colors by requesting inverse bright bold <background> on <foreground> but this is really quite ugly.

Update Taskwarrior tests

It looks like the GitHub actions for this repo will not run with the current Taskwarrior, as it does not use the out-of-source build and ctest.

cc @felixschurk

work-week ends do not seem to be calculated correctly

Work week endings may be calculated incorrectly. Observe the following:

$ for ww in {s,e}o{,p,n}ww
  do printf "%s\t%s\n" $ww $(
      faketime '2017-03-05 12:34:56' task calc $ww
  ); done

soww    2017-03-13T00:00:00
sopww   2017-02-27T00:00:00
sonww   2017-03-13T00:00:00
eoww    2017-03-10T23:59:59
eopww   2017-03-03T23:59:59
eonww   2017-03-17T23:59:59

with the reference date of 2017-03-05 12:34:56 (a Sunday), and the calendar:

 $ ncal 03 2017
    March 2017        
Mo     6 13 20 27   
Tu     7 14 21 28   
We  1  8 15 22 29   
Th  2  9 16 23 30   
Fr  3 10 17 24 31   
Sa  4 11 18 25      
Su  5 12 19 26      
    9 10 11 12 13   

these do not look right:

  • It seems to consider the next "work week" to have already begun on Saturday, but I should think the next work week doesn't actually begin until Monday. Even though there's no actual work days left, it's still within the same work week.
  • soww and sonww are identical
  • eoww is earlier than soww (!)

This issue was noticed during testing for #47 (a change to comments documenting behavior of eo*) and is forked into a standalone issue as per the discussion there.

(test version of libshared was 591fa58)

src/libshared/src/Datetime.cpp:3047: bad test ?

src/libshared/src/Datetime.cpp:3047]: (warning) Logical disjunction always evaluates to true: number >= 11 || number <= 13.

Source code is

if (((number >= 11 || number <= 13) && suffix == "th") ||

Tests fail in some timezones

$ date                                            
Wed Jul  7 22:18:59 2021

# ^^^ summer time

$ TZ="Europe/Dublin" ./run_all
Passed:                          8283
Failed:                            54
Unexpected successes:               0
Skipped:                            1
Expected failures:                  0
Runtime:                         0.30 seconds

Seems like some actual values about an hour off:

$ make test
<...>
ok 3152 - eoq > now
actual (first - relative:true): 20210731T230000Z now: 20210707T211751Z
ok 3153 - 1st not in same month as now
ok 3154 - 1st day is 1
actual (second - relative:true): 20210801T230000Z now: 20210707T211751Z
ok 3155 - 2nd not in same month as now
ok 3156 - 2nd day is 2
actual (third - relative:true): 20210802T230000Z now: 20210707T211751Z
ok 3157 - 3rd not in same month as now
ok 3158 - 3rd day is 3
actual (fourth - relative:true): 20210803T230000Z now: 20210707T211751Z
ok 3159 - 4th not in same month as now
ok 3160 - 4th day is 4
actual (first - relative:false): 20210630T230000Z now: 20210707T211751Z
ok 3161 - 1st in same month as now
ok 3162 - 1st day is 1
actual (second - relative:false): 20210701T230000Z now: 20210707T211751Z
ok 3163 - 2nd in same month as now
ok 3164 - 2nd day is 2
actual (third - relative:false): 20210702T230000Z now: 20210707T211751Z
ok 3165 - 3rd in same month as now
ok 3166 - 3rd day is 3
actual (fourth - relative:false): 20210703T230000Z now: 20210707T211751Z
ok 3167 - 4th in same month as now
<...>

However:

$ TZ="UTC" ./run_all
Passed:                          8337
Failed:                             0
Unexpected successes:               0
Skipped:                            1
Expected failures:                  0
Runtime:                         0.30 seconds
$ TZ="America/Los_Angeles" ./run_all
Passed:                          8337
Failed:                             0
Unexpected successes:               0
Skipped:                            1
Expected failures:                  0
Runtime:                         0.30 seconds

I didn't dig any further.

format.h doesn't handle `char*` correctly

char *foobar = "lorem ipsum";
format("dolor sit {1} amet", foobar);

Expected result:
"dolor sit lorem ipsum amet"

Actual result:
"dolor sit dolor sit amet amet"

When passing in a char*-type variable to format's varargs list, need to cast the variable to std::string or convert it to a std::string. Not doing so results in fmt variable (first arg) being read a second time as one of the vararg variables.

Not a major issue but this small wart can take people by surprise - if this is wontfix, may I recommend adding a comment in the source?

Keys of parsed JSON objects are escaped

The json::object::parse_pair function calls getQuoted to parse object keys. This means that object::_data contains JSON-escaped keys.

This causes the following issue in timewarrior as of GothenburgBitFactory/timewarrior@bdb28fa:

$ timew start '"a'
  Note: '"\"a"' is a new tag.
  Tracking "\"a"
    […]

$ timew stop
  Trying to decrement non-existent tag '"a'

After timew start is run, the tags.data file contains {"\"a":{"count":1}}. When running timew stop, libshared's parse_pair parses the key "\"a", but does not unescape it. This causes timewarrior not to find "a because the key is internally stored as \"a.

Possible solutions:

  • Add a function to retrieve the key name in unescaped form and change timewarrior to use this function
  • Change the internal representation of _data to store the unescaped string

Possibly related to GothenburgBitFactory/timewarrior#159

Stack exhaustion and crashes with malformed input

Whilst fuzzing with AFL I observed two unique crashes with similar input. Provided to task rc:$file list. As the crash occurred inside libshared I'm reporting the problem here. Please let me know if I should file the bug in the taskwarrior repository instead.

This appears to be an infinite loop through Directory::create which ends up exhausting the stack:

infinite_loop.rc:

data.location=/\
gdb-peda$ run rc:infinite_loop.rc list
Starting program: /home/kali/fuzzing/sessions/taskwarrior/task rc:infinite_loop.rc list
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Warning: AFL++ tools will need to set AFL_MAP_SIZE to 70464 to be able to run this instrumented program!

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
RAX: 0xf9a3
RBX: 0x0
RCX: 0x7ebb00 --> 0x0
RDX: 0xcd
RSI: 0x7fffff7ff090 --> 0x7fffff7ff0a0 --> 0x0
RDI: 0x7fffff7ff048 --> 0x7fffff7ff058 --> 0x0
RBP: 0x7fffff7ff058 --> 0x0
RSP: 0x7fffff7fef90
RIP: 0x6ffb2c (<_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+60>:     mov    QWORD PTR [rsp+0x8],rbx)
R8 : 0x9ff050 --> 0x9fee10 --> 0x9fed50 --> 0xa03ad0 --> 0x9ff7d0 --> 0xa06cd0 (--> ...)
R9 : 0x3
R10: 0xfffffffffffff9dd
R11: 0x246
R12: 0x7fffff7ff0f0 --> 0x0
R13: 0x7fffff7ff090 --> 0x7fffff7ff0a0 --> 0x0
R14: 0x7fffff7ff048 --> 0x7fffff7ff058 --> 0x0
R15: 0x7fffff7ff0a0 --> 0x0
EFLAGS: 0x10282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x6ffb22 <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+50>:        mov    QWORD PTR [rdi],rbp
   0x6ffb25 <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+53>:        mov    r15,QWORD PTR [rsi]
   0x6ffb28 <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+56>:        mov    rbx,QWORD PTR [rsi+0x8]
=> 0x6ffb2c <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+60>:        mov    QWORD PTR [rsp+0x8],rbx
   0x6ffb31 <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+65>:        cmp    rbx,0xf
   0x6ffb35 <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+69>:        jbe    0x6ffb93 <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+163>
   0x6ffb37 <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+71>:        movsxd rax,DWORD PTR [rip+0xe42ba]        # 0x7e3df8
   0x6ffb3e <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+78>:        mov    rcx,QWORD PTR [rip+0xa5c03]        # 0x7a5748 <__afl_area_ptr>
[------------------------------------stack-------------------------------------]
Invalid $SP address: 0x7fffff7fef90
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string (this=0x7fffff7ff048, Python Exception <class 'gdb.error'> There is no member named _M_dataplus.:
__str=) at /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h:451
451           { _M_construct(__str._M_data(), __str._M_data() + __str.length()); }
gdb-peda$

This file seems to trigger a crash inside Path::expand:

path_expand_segv.rc:

data.location=/o
gdb-peda$ run rc:path_expand_segv.rc  list
Starting program: /home/kali/fuzzing/sessions/taskwarrior/task rc:path_expand_segv.rc  list
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Warning: AFL++ tools will need to set AFL_MAP_SIZE to 70464 to be able to run this instrumented program!

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
RAX: 0xf993
RBX: 0x7fffff7ff0b0 --> 0x7fffff7ff0c0 --> 0x7fffff7ff100 --> 0x1
RCX: 0x7ebb00 --> 0x0
RDX: 0xf
RSI: 0x7fffff7ff080 --> 0x7fffff7ff090 --> 0x0
RDI: 0x7fffff7ff038 --> 0x0
RBP: 0x0
RSP: 0x7fffff7ff000 --> 0x7fffff7ff0e0 --> 0x0
RIP: 0x6ffaf9 (<_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+9>:      push   rbx)
R8 : 0x9ff050 --> 0x9fee10 --> 0x9fed50 --> 0xa03ad0 --> 0x9ff7d0 --> 0xa06cd0 (--> ...)
R9 : 0x2
R10: 0xfffffffffffff9dd
R11: 0x246
R12: 0x7fffff7ff0e0 --> 0x0
R13: 0x9ec001 --> 0x9100000000000000
R14: 0x7fffff7ff080 --> 0x7fffff7ff090 --> 0x0
R15: 0x7fffff7ff0c0 --> 0x7fffff7ff100 --> 0x1
EFLAGS: 0x10206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x6ffaf3 <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+3>: push   r14
   0x6ffaf5 <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+5>: push   r13
   0x6ffaf7 <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+7>: push   r12
=> 0x6ffaf9 <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+9>: push   rbx
   0x6ffafa <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+10>:        sub    rsp,0x78
   0x6ffafe <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+14>:        movsxd rax,DWORD PTR [rip+0xe42eb]        # 0x7e3df0
   0x6ffb05 <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+21>:        mov    rcx,QWORD PTR [rip+0xa5c3c]        # 0x7a5748 <__afl_area_ptr>
   0x6ffb0c <_ZN4Path6expandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+28>:        mov    dl,BYTE PTR [rcx+rax*1]
[------------------------------------stack-------------------------------------]
0000| 0x7fffff7ff000 --> 0x7fffff7ff0e0 --> 0x0
0008| 0x7fffff7ff008 --> 0x9ec001 --> 0x9100000000000000
0016| 0x7fffff7ff010 --> 0x7fffff7ff080 --> 0x7fffff7ff090 --> 0x0
0024| 0x7fffff7ff018 --> 0x7fffff7ff0c0 --> 0x7fffff7ff100 --> 0x1
0032| 0x7fffff7ff020 --> 0x0
0040| 0x7fffff7ff028 --> 0x6ff894 (<_ZN4PathC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+100>:     mov    rsi,QWORD PTR [rsp+0x8])
0048| 0x7fffff7ff030 --> 0x0
0056| 0x7fffff7ff038 --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x00000000006ffaf9 in Path::expand (Python Exception <class 'gdb.error'> There is no member named _M_dataplus.:
in=) at /home/kali/fuzzing/victims/taskwarrior/src/libshared/src/FS.cpp:265
265     {
gdb-peda$

`wrapText` with width `1` hangs indefinetly when hyphenation is turned on

This is somehow related to #23 and GothenburgBitFactory/timewarrior#309.

I noticed that when setting the width parameter of wrapText(...) to 1 it fails (hangs indefinetly) when hyphenation is turned on:

  text = "one";
  lines.clear ();
  wrapText (lines, text, 1, true);

Without hyphenation, it passes:

  text = "one";
  lines.clear ();
  wrapText (lines, text, 1, false);
  t.is (lines.size (), (size_t) 3, "wrapText 'one' -> 3 lines");
  t.is (lines[0], "o", "wrapText line 0 -> 'o'");
  t.is (lines[1], "n", "wrapText line 1 -> 'n'");
  t.is (lines[2], "e", "wrapText line 1 -> 'e'");

Wrapping unicode characters causes Timewarrior to hang indefinitely

The following lines will cause Timewarrior 1.3.0 to hang indefinetely (GothenburgBitFactory/timewarrior#309):

$ src/timew track 2016-01-16T08:55:00 - 2016-01-16T09:00:00 "안녕하세요 월드"
Note: '"안녕하세요 월드"' is a new tag.
Recorded "안녕하세요 월드"
  Started 2016-01-16T08:55:00
  Ended              09:00:00
  Total               0:05:00
$ src/timew day 2016-01-16 - 2016-01-17

I can reproduce this by adding the following test to shared.t.cpp:65:

  text = "안녕하세요 월드";
  lines.clear ();
  wrapText (lines, text, 1, false);

This test passes if the width parameter in wrapText(...) gets set to 2:

  text = "안녕하세요 월드";
  lines.clear ();
  wrapText (lines, text, 2, false);
  t.is (lines.size (), (size_t) 7, "wrapText '안녕하세요 월드' -> 8 lines");
  t.is (lines[0], "안", "wrapText line 0 -> '안'");
  t.is (lines[1], "녕", "wrapText line 1 -> '녕'");
  t.is (lines[2], "하", "wrapText line 2 -> '하'");
  t.is (lines[3], "세", "wrapText line 3 -> '세'");
  t.is (lines[4], "요", "wrapText line 4 -> '요'");
  //t.is (lines[5], " ", "wrapText line 5 -> ' '");
  t.is (lines[5], "월", "wrapText line 6 -> '월'");
  t.is (lines[6], "드", "wrapText line 7 -> '드'");

However, the whitespace in 안녕하세요 월드 gets omitted somehow, so there is not empty line 5

sod, som, soy etc do not seem to work as documented

when writing tests for something else I discovered this:

 $ date
Fri Jul 16 21:30:41 PDT 2021

 $ task calc soy
2021-01-01T00:00:00

 $ task calc sod
2021-07-16T00:00:00

 $ task calc som
2021-07-01T00:00:00

(same in 2.5.3 and 2.6.0 trunk) but all the documentation says that soX should be start of the next X. Is this known behavior that has changed somewhere, or am I misunderstanding the description from man page:

            Start  of  next  (work)  week (Monday), calendar week (Sunday or
              Monday), month, quarter and year
                     task ... due:sow
                     task ... due:soww
                     task ... due:socw
                     task ... due:som
                     task ... due:soq
                     task ... due:soy

this seems confusing, there is "start of next ..." and "end of current" documented, but nothing for "start of current" which seems to be the actual behavior (not "next"). The tests in libshared/test/datetime.t.cpp seem to agree with the behavior:

    Datetime r19a ("soy");
    t.ok (r19a.sameYear (now), "soy in same year as now");
    t.ok (r19a < now,          "soy < now");

but my understanding of the phrase "start of next " means that by definition, it's in the future. What am I missing?

Path::expand() doesn't correctly expand some paths

Hello,

Path::expand() doesn't expand .foo, the return value is .foo and it should be /cwd/.foo.

When tilde ~ appears in the middle of the path, it's also expanded as the user's home dir.

I am not sure if it was designed to be able to expand paths like . and ./ because these two paths are not expanded too.

Thank you.

weeks seem to start on Sunday despite weekstart = 1

There seems to be an issue in this library regarding week numbers and starting day of week.

ISO weeks start on Monday. The code seems to agree:

  src/Datetime.cpp:62:int Datetime::weekstart = 1; // Monday, per ISO-8601.

In the tests from test/datetime.t.cpp there are some initialized variables:

  ...
  int year = 2013;
  int mo = 12;
  ...
  local_now->tm_year  = year - 1900;
  local_now->tm_mon   = mo - 1;
  local_now->tm_mday  = 1;
  local_now->tm_isdst = 0;
  time_t local1 = mktime (local_now);
  std::cout << "# local midnight 2013-12-01 " << local1 << '\n';

We can see the local1 date is december 1:

   $ grep local.midnight.2013-12-01 test/all.log
  # local midnight 2013-12-01 1385884800

   $ date -d @1385884800
  Sun Dec  1 00:00:00 PST 2013

Now the following test is performed:

  testParse (t, "2013-W49", 8, year, 0, 49, 0, 0, 0, 0, 0, false, local1);
  ...

  Breakpoint 2, testParse (t=..., input="2013-W49", in_start=8,
    in_year=2013, in_month=0, in_week=49, in_weekday=0, in_julian=0,
    in_day=0, in_seconds=0, in_offset=0, in_utc=false,
    in_date=1385884800)
  at /home/scott/upsrc/libshared/test/datetime.t.cpp:47
  47 {
  (gdb) n
  48        std::string label = std::string ("Datetime::parse (\"") +
                input + "\") --> ";
  (gdb) 
  50        Datetime iso;
  (gdb) 
  51        std::string::size_type start = 0;
  (gdb) 
  53        t.ok (iso.parse (input, start),             label + "true");
  (gdb) 
  ok 147 - Datetime::parse ("2013-W49") --> true
  54        t.is ((int) start,        in_start,         label + "[]");
  (gdb) p iso
  $1 = {static weekstart = 1, static standaloneDateEnabled = true,
    static standaloneTimeEnabled = true, static timeRelative = true,
    _year = 2013, _month = 0, _week = 49, _weekday = 0, _julian = 0,
    _day = 0, _seconds = 0, _offset = 0, _utc = false,
    _date = 1385884800}
  (gdb) n
  ok 148 - Datetime::parse ("2013-W49") --> []
  55        t.is (iso._year,          in_year,          label + "_year");
  (gdb) n
  ok 149 - Datetime::parse ("2013-W49") --> _year
  56        t.is (iso._month,         in_month,         label + "_month");
  (gdb) 
  ok 150 - Datetime::parse ("2013-W49") --> _month
  57        t.is (iso._week,          in_week,          label + "_week");
  (gdb) 
  ok 151 - Datetime::parse ("2013-W49") --> _week

So the test's expectation is that 2013 week 49 is December 1:

   $ task calc 2013-W49
  2013-12-01T00:00:00

Yet, it isn't:

   $ ncal 12 2013
      December 2013
  Mo     2  9 16 23 30
  Tu     3 10 17 24 31
  We     4 11 18 25
  Th     5 12 19 26
  Fr     6 13 20 27
  Sa     7 14 21 28
  Su  1  8 15 22 29
     48 49 50 51 52  1

   $ date -d `task calc 2013-W49` +%V
  48

The week number is wrong, December 1 is still week 48, not week 49. The problem seems to be that it's treating Sunday as the first day of week 49.

Timewarrior does not set or pass weekstart to libshared anywhere, so presumably the libshared default is always used (weekstart = 1, Monday, ISO weeks, as initialized above in Datetime.cpp:62).

Taskwarrior does have an rc.weekstart, but it makes no difference:

   $ for ws in 0 1 Sunday Monday
     do task rc.weekstart=$ws calc 2013-W49
     done
  2013-12-01T00:00:00
  2013-12-01T00:00:00
  2013-12-01T00:00:00
  2013-12-01T00:00:00

This is leading to problems such as in GothenburgBitFactory/timewarrior#595 and GothenburgBitFactory/taskwarrior#2922 with no obvious fix.

I will keep digging into this as time permits. If anyone else knows anything more about this, it would be helpful.

A name colission with `soymuchacho/libshared`

I thought about making this project a standalone lib.
This happened after I saw both Task Warrior and Timewarrior use the same library and that I am building it twice.

And googled this name and I found another project of the same name (born at the similar time, Jul 16, 2016):
https://github.com/soymuchacho/libshared

Would it be acceptable for this project to adjust the name? Just a thought.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.