Giter Club home page Giter Club logo

bcal's Introduction

  • author of buku, nnn, googler...
  • writes high quality tools to optimize productivity
  • wrote them to minimize time at a computer

bcal's People

Contributors

0mp avatar fennm avatar jarun avatar rachmadaniharyono avatar refacto avatar sjmulder avatar sompuz avatar sreekanth370 avatar szlin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bcal's Issues

Convert from hex to dec

It'd be cool if you could convert from hex to dec. As of now, you can only convert from dec to hex.

Add API so this can be used as library?

Hi,

for reference: https://www.reddit.com/r/commandline/comments/elcprz/bcal_storage_expression_and_generalpurpose/fdhwhy0/

We talked about whether it would be a nice idea to provide an API for this software, so it can be used as a library. My special use-case is to provide language bindings for Rust, but others might also create language bindings for other programming languages.

This might be a twofold change:

  • Create a string-in string-out API, where a user of the API can submit a string that gets parsed and calculated and gets back a string that represents the result
  • Provide a higher-level API where the result is an object that has a value and a unit, so others can then continue using these values.
    The end-game would then be to provide a higher-level input library, of course. Where a user of the library would submit an expression object that gets then calculated by the library... so basically the user submits an AST.

If you want help designing the API, I'd be glad to help.

Source code release tarball?

Hi --

Is it possible for you to upload a source tarball alongside your package tarballs, like you do for nnn? I would like to make a package of bcal for OpenBSD, and we have learned that the GitHub auto-generated source tarballs can change unexpectedly.

Four tests fail on Darwin

I am trying to build bcal for x86_64-darwin using Nix. The build with gcc works fine, however four tests are failing, see below. Likewise manually running bcal "(5kb+2mb)/3" and bcal "5 tb / 12" from the CLI examples fails with ERROR: unknown unit.

============================= test session starts ==============================
platform darwin -- Python 3.6.4, pytest-3.4.0, py-1.5.2, pluggy-0.6.0
rootdir: /private/tmp/nix-build-bcal-1.7.drv-0/source, inifile:
collected 42 items

test.py .....FFF.F................................                       [100%]

=================================== FAILURES ===================================
_________________________ test_output[item5-5250880] __________________________

item = ('./bcal', '-m', '0x4         kb   *  2     +   5        mib')
res = b'5250880\n'

    @pytest.mark.parametrize('item, res', zip(test, res))
    def test_output(item, res):
        try:
>           out = subprocess.check_output(item, stderr=subprocess.STDOUT)

test.py:119:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

timeout = None
popenargs = (('./bcal', '-m', '0x4         kb   *  2     +   5        mib'),)
kwargs = {'stderr': -2}

input = None, timeout = None, check = True
popenargs = (('./bcal', '-m', '0x4         kb   *  2     +   5        mib'),)
kwargs = {'stderr': -2, 'stdout': -1}
process = <subprocess.Popen object at 0x108992828>
stdout = b'ERROR: unknown unit\n', stderr = None, retcode = 255

During handling of the above exception, another exception occurred:

item = ('./bcal', '-m', '0x4         kb   *  2     +   5        mib')
res = b'5250880\n'

    @pytest.mark.parametrize('item, res', zip(test, res))
    def test_output(item, res):
        try:
            out = subprocess.check_output(item, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            # print(e.output)
>           assert e.output == res
E           AssertionError: assert b'ERROR: unknown unit\n' == b'5250880\n'
E             At index 0 diff: 69 != 53
E             Left contains more items, first extra item: 110
E             Use -v to get the full diff

test.py:122: AssertionError
________________________ test_output[item6-655360000] _________________________

item = ('./bcal', '-m', '5*5*5*5     mIB'), res = b'655360000\n'

    @pytest.mark.parametrize('item, res', zip(test, res))
    def test_output(item, res):
        try:
>           out = subprocess.check_output(item, stderr=subprocess.STDOUT)

test.py:119:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

timeout = None, popenargs = (('./bcal', '-m', '5*5*5*5     mIB'),)
kwargs = {'stderr': -2}

input = None, timeout = None, check = True
popenargs = (('./bcal', '-m', '5*5*5*5     mIB'),)
kwargs = {'stderr': -2, 'stdout': -1}
process = <subprocess.Popen object at 0x1084e1080>
stdout = b'ERROR: unknown unit\n', stderr = None, retcode = 255

During handling of the above exception, another exception occurred:

item = ('./bcal', '-m', '5*5*5*5     mIB'), res = b'655360000\n'

    @pytest.mark.parametrize('item, res', zip(test, res))
    def test_output(item, res):
        try:
            out = subprocess.check_output(item, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            # print(e.output)
>           assert e.output == res
E           AssertionError: assert b'ERROR: unknown unit\n' == b'655360000\n'
E             At index 0 diff: 69 != 54
E             Left contains more items, first extra item: 110
E             Use -v to get the full diff

test.py:122: AssertionError
________________________ test_output[item7-625000000] _________________________

item = ('./bcal', '-m', '5mb*5*5*5'), res = b'625000000\n'

    @pytest.mark.parametrize('item, res', zip(test, res))
    def test_output(item, res):
        try:
>           out = subprocess.check_output(item, stderr=subprocess.STDOUT)

test.py:119:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

timeout = None, popenargs = (('./bcal', '-m', '5mb*5*5*5'),)
kwargs = {'stderr': -2}

input = None, timeout = None, check = True
popenargs = (('./bcal', '-m', '5mb*5*5*5'),)
kwargs = {'stderr': -2, 'stdout': -1}
process = <subprocess.Popen object at 0x1086a1d30>
stdout = b'ERROR: unknown unit\n', stderr = None, retcode = 255

During handling of the above exception, another exception occurred:

item = ('./bcal', '-m', '5mb*5*5*5'), res = b'625000000\n'

    @pytest.mark.parametrize('item, res', zip(test, res))
    def test_output(item, res):
        try:
            out = subprocess.check_output(item, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            # print(e.output)
>           assert e.output == res
E           AssertionError: assert b'ERROR: unknown unit\n' == b'625000000\n'
E             At index 0 diff: 69 != 54
E             Left contains more items, first extra item: 110
E             Use -v to get the full diff

test.py:122: AssertionError
________________________ test_output[item9-283752000] _________________________

item = ('./bcal', '-m', '2kb+3mb/4*5+5*56mb'), res = b'283752000\n'

    @pytest.mark.parametrize('item, res', zip(test, res))
    def test_output(item, res):
        try:
>           out = subprocess.check_output(item, stderr=subprocess.STDOUT)

test.py:119:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

timeout = None, popenargs = (('./bcal', '-m', '2kb+3mb/4*5+5*56mb'),)
kwargs = {'stderr': -2}

input = None, timeout = None, check = True
popenargs = (('./bcal', '-m', '2kb+3mb/4*5+5*56mb'),)
kwargs = {'stderr': -2, 'stdout': -1}
process = <subprocess.Popen object at 0x108623c18>
stdout = b'ERROR: unknown unit\n', stderr = None, retcode = 255

During handling of the above exception, another exception occurred:

item = ('./bcal', '-m', '2kb+3mb/4*5+5*56mb'), res = b'283752000\n'

    @pytest.mark.parametrize('item, res', zip(test, res))
    def test_output(item, res):
        try:
            out = subprocess.check_output(item, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            # print(e.output)
>           assert e.output == res
E           AssertionError: assert b'ERROR: unknown unit\n' == b'283752000\n'
E             At index 0 diff: 69 != 50
E             Left contains more items, first extra item: 110
E             Use -v to get the full diff

test.py:122: AssertionError
===================== 4 failed, 38 passed in 0.46 seconds ======================

Build error with GCC9: error: '%s' directive argument is null

I have a problem building bcal in Fedora Rawhide using GCC 9.0.1

+ /usr/bin/make -O -j6 bcal
cc -fPIC -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -Wall -Wextra -Wno-unused-parameter -Werror -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Iinc -o bcal src/bcal.c -lreadline
BUILDSTDERR: In file included from src/bcal.c:29:
BUILDSTDERR: src/bcal.c: In function 'evaluate':
BUILDSTDERR: inc/log.h:32:6: error: '%s' directive argument is null [-Werror=format-overflow=]
BUILDSTDERR:    32 |      debug_log(__func__, level, format, ##__VA_ARGS__)
BUILDSTDERR:       |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BUILDSTDERR: src/bcal.c:1926:2: note: in expansion of macro 'log'
BUILDSTDERR:  1926 |  log(DEBUG, "expr: %s\n", expr);
BUILDSTDERR:       |  ^~~
BUILDSTDERR: src/bcal.c:1926:20: note: format string is defined here
BUILDSTDERR:  1926 |  log(DEBUG, "expr: %s\n", expr);
BUILDSTDERR:       |                    ^~
BUILDSTDERR: In file included from src/bcal.c:29:
BUILDSTDERR: inc/log.h:32:6: error: '%s' directive argument is null [-Werror=format-overflow=]
BUILDSTDERR:    32 |      debug_log(__func__, level, format, ##__VA_ARGS__)
BUILDSTDERR:       |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BUILDSTDERR: src/bcal.c:1926:2: note: in expansion of macro 'log'
BUILDSTDERR:  1926 |  log(DEBUG, "expr: %s\n", expr);
BUILDSTDERR:       |  ^~~
BUILDSTDERR: src/bcal.c:1926:20: note: format string is defined here
BUILDSTDERR:  1926 |  log(DEBUG, "expr: %s\n", expr);
BUILDSTDERR:       |                    ^~
BUILDSTDERR: In file included from src/bcal.c:29:
BUILDSTDERR: inc/log.h:32:6: error: '%s' directive argument is null [-Werror=format-overflow=]
BUILDSTDERR:    32 |      debug_log(__func__, level, format, ##__VA_ARGS__)
BUILDSTDERR:       |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BUILDSTDERR: src/bcal.c:1926:2: note: in expansion of macro 'log'
BUILDSTDERR:  1926 |  log(DEBUG, "expr: %s\n", expr);
BUILDSTDERR:       |  ^~~
BUILDSTDERR: src/bcal.c:1926:20: note: format string is defined here
BUILDSTDERR:  1926 |  log(DEBUG, "expr: %s\n", expr);
BUILDSTDERR:       |                    ^~
BUILDSTDERR: In file included from src/bcal.c:29:
BUILDSTDERR: inc/log.h:32:6: error: '%s' directive argument is null [-Werror=format-overflow=]
BUILDSTDERR:    32 |      debug_log(__func__, level, format, ##__VA_ARGS__)
BUILDSTDERR:       |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BUILDSTDERR: src/bcal.c:1926:2: note: in expansion of macro 'log'
BUILDSTDERR:  1926 |  log(DEBUG, "expr: %s\n", expr);
BUILDSTDERR:       |  ^~~
BUILDSTDERR: src/bcal.c:1926:20: note: format string is defined here
BUILDSTDERR:  1926 |  log(DEBUG, "expr: %s\n", expr);
BUILDSTDERR:       |                    ^~
BUILDSTDERR: In file included from src/bcal.c:29:
BUILDSTDERR: inc/log.h:32:6: error: '%s' directive argument is null [-Werror=format-overflow=]
BUILDSTDERR:    32 |      debug_log(__func__, level, format, ##__VA_ARGS__)
BUILDSTDERR:       |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BUILDSTDERR: src/bcal.c:1926:2: note: in expansion of macro 'log'
BUILDSTDERR:  1926 |  log(DEBUG, "expr: %s\n", expr);
BUILDSTDERR:       |  ^~~
BUILDSTDERR: src/bcal.c:1926:20: note: format string is defined here
BUILDSTDERR:  1926 |  log(DEBUG, "expr: %s\n", expr);
BUILDSTDERR:       |                    ^~
BUILDSTDERR: In file included from src/bcal.c:29:
BUILDSTDERR: inc/log.h:32:6: error: '%s' directive argument is null [-Werror=format-overflow=]
BUILDSTDERR:    32 |      debug_log(__func__, level, format, ##__VA_ARGS__)
BUILDSTDERR:       |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BUILDSTDERR: src/bcal.c:1926:2: note: in expansion of macro 'log'
BUILDSTDERR:  1926 |  log(DEBUG, "expr: %s\n", expr);
BUILDSTDERR:       |  ^~~
BUILDSTDERR: src/bcal.c:1926:20: note: format string is defined here
BUILDSTDERR:  1926 |  log(DEBUG, "expr: %s\n", expr);
BUILDSTDERR:       |                    ^~
BUILDSTDERR: cc1: all warnings being treated as errors
BUILDSTDERR: make: *** [Makefile:14: bcal] Error 1

Terminal broken with calc as backend and undefined input

Steps to repro on Ubuntu:

  • Install apcalc on Ubuntu
  • Run the following
$ export BCAL_USE_CALC=1
$ bcal -b
q/double Enter -> quit, ? -> help
calc> qq
"qq" is undefined

calc>

Terminal gets broken ( need to type twice to show a character). Happens with any invalid command.

Note: bc works. Probably calc prints additional blank newline (the blank line) but bcal quits after reading the first line "qq" is undefined.

'quit' and 'exit' yield "ERROR: unknown unit"

Perhaps I'm misunderstanding how this is supposed to work but typing 'quit' or 'exit' at the prompt doesn't exit bcal as the changelog seems to imply:

$ bcal -h | grep Version
Version 2.3
$ bcal
q/double Enter -> quit, ? -> help
bcal> quit
ERROR: unknown unit
bcal> exit
ERROR: unknown unit

^D did work.

Using Debian 11.

One test fails on FreeBSD

./bcal -b '9876543210.987654321 * 123456789.123456789'

returns

bc: stdin:2: syntax error: = unexpected

Here's the failure message from the test suite:

=================================================================================================================================== FAILURES ====================================================================================================================================
______________________________________________________________________________________________________________ test_output[item64-1219326312467611632.3609205901
] ______________________________________________________________________________________________________________

item = ('./bcal', '-b', '9876543210.987654321 * 123456789.123456789'), res = b'1219326312467611632.3609205901\n'

    @pytest.mark.parametrize('item, res', zip(test, res))
    def test_output(item, res):
        try:
            out = subprocess.check_output(item, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            # print(e.output)
            assert e.output == res
        else:
>           assert out == res
E           AssertionError: assert b'bc: stdin:2... unexpected\n' == b'121932631246....3609205901\n'
E             At index 0 diff: 98 != 49
E             Left contains more items, first extra item: 101
E             Use -v to get the full diff

test.py:184: AssertionError
====================================================================================================================== 1 failed, 71 passed in 0.44 seconds ======================================================================================================================
*** Error code 1

32bit compiling error

Not looked into great deal, but I decided to test on 32bit (I really should have before). And it's given an error. Two things, would you like me to disable that arch for now on aur+ppa packages?

And here is the build log https://launchpadlibrarian.net/290184010/buildlog_ubuntu-trusty-i386.bcal_1.4-1_BUILDING.txt.gz

The important part is:

bcal.c: In function ‘converttb’:
bcal.c:406:21: error: ‘__uint128_t’ undeclared (first use in this function)
  maxuint_t bytes = (__uint128_t)(tb * 1000000000000);
                     ^
bcal.c:406:21: note: each undeclared identifier is reported only once for each function it appears in

Build fails on NetBSD 7.1 due to -Werror=char-subscripts

From a bulk build on NetBSD 7.1, an older but still maintained release of NetBSD, a bunch of errors like these:

src/bcal.c:1165:2: error: array subscript has type 'char' [-Werror=char-subscripts]
  while (*s1 && (tolower(*s1) == tolower(*s2))) {
  ^

Full build output here: http://nyftp.netbsd.org/pub/pkgsrc/packages/reports/2019Q1/NetBSD-7.1-x86_64/20190602.1935/bcal-2.1/build.log

My first impression is that we should

  • remove -Werror from CFLAGS, it makes sense in development but not in the wild where you really can't anticipate what warnings could occur
  • add -Wno-char-subscripts

but I'll look into it more deeply later.

just an idea (alternative offering)

Not sure if you've heard of Radare, but they're doing something very close to this with rax2. The whole suite is also focused on storage and reverse engineering. You may want to join forces with them.

OpenBSD needs -lcurses

On OpenBSD 6.4-STABLE, compilation of master fails:

$ gmake
cc -O3 -Wall -Wextra -Wno-unused-parameter -Werror -Iinc -o bcal src/bcal.c -lreadline
/usr/bin/../lib/libreadline.so.4.0: undefined reference to `tgetnum'
/usr/bin/../lib/libreadline.so.4.0: undefined reference to `tgoto'
/usr/bin/../lib/libreadline.so.4.0: undefined reference to `tgetflag'
/usr/bin/../lib/libreadline.so.4.0: undefined reference to `tputs'
/usr/bin/../lib/libreadline.so.4.0: undefined reference to `tgetent'
/usr/bin/../lib/libreadline.so.4.0: undefined reference to `tgetstr'

Adding -lcurses fixes the issue:

$ gmake LDLIBS="-lreadline -lcurses"
cc -O3 -Wall -Wextra -Wno-unused-parameter -Werror -Iinc -o bcal src/bcal.c -lreadline -lcurses
$

Not sure if it's safe to add -lcurses by default.

Redundant spaces in expression should be ignored.

Here's a sample wrong output:

$ ./bcal "5              tb /    12"
UNIT  CONVERSION
                                       0 B

            IEC standard (base 2)

                                       0 KiB
                                       0 MiB
                                       0 GiB
                                       0 TiB

            SI standard (base 10)

                                       0 kB
                                       0 MB
                                       0 GB
                                       0 TB

    ADDRESS
	dec: 0
	hex: 0x0

    LBA:OFFSET
	sector size: 0x200

	dec: 0:0
	hex: 0x0:0x0

Correct output:

$ ./bcal "5 tb /    12"
UNIT  CONVERSION
                            416666666666 B

            IEC standard (base 2)

                        4.0690104167e+08 KiB
                        3.9736429850e+05 MiB
                        3.8805107276e+02 GiB
                        3.7895612574e-01 TiB

            SI standard (base 10)

                        4.1666666667e+08 kB
                        4.1666666667e+05 MB
                        4.1666666667e+02 GB
                        4.1666666667e-01 TB

    ADDRESS
	dec: 416666666666
	hex: 0x610344c6aa

    LBA:OFFSET
	sector size: 0x200

	dec: 813802083:170
	hex: 0x3081a263:0xaa

@SampuZ I am assigning this to you.

pinboost_debug.cc:98:17: error: ‘%s’ directive writing up to 1023 bytes into a region of size 999 [-Werror=format-overflow=]

After doing exactly by tutorial for Sniper-7.2 i encountered with this error during make.
i am running on Linux localhost 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u1 (2019-09-20) x86_64 GNU/Linux
and the gcc is gcc version 8.3.0 (Debian 8.3.0-6)
the output of make in sniper directory is:

Building for x86 (intel64)
[CXX ] sift/recorder/obj-intel64/pinboost_debug.o
pinboost_debug.cc: In function ‘bool pinboost_backtrace(LEVEL_BASE::EXCEPTION_INFO*, LEVEL_VM::PHYSICAL_CONTEXT*)’:
pinboost_debug.cc:98:17: error: ‘%s’ directive writing up to 1023 bytes into a region of size 999 [-Werror=format-overflow=]
sprintf(cmd, "%s/tools/gen_backtrace.py "%s" >&2", getenv("SNIPER_ROOT"), backtrace_filename);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
pinboost_debug.cc:98:11: note: ‘sprintf’ output 31 or more bytes (assuming 1054) into a destination of size 1024
sprintf(cmd, "%s/tools/gen_backtrace.py "%s" >&2", getenv("SNIPER_ROOT"), backtrace_filename);
~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors
make[2]: [makefile.rules:133: obj-intel64/pinboost_debug.o] Error 1
make[1]: [Makefile:50: recorder] Error 2
make: [Makefile:51: /home/ahmad/SOFTWARE/snipersim/sniper-7.2/sift/libsift.a] Error 2

How to overcome with this error?

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.