Coder Social home page Coder Social logo

vijinho / stormyglass Goto Github PK

View Code? Open in Web Editor NEW
0.0 1.0 0.0 4.85 MB

PHP CLI script and webservice to fetch, save and output data from the stormglass Global Marine Weather Forecast API weather API https://docs.stormglass.io/?shell#point-request and cache/save results, outputting in JSON format

PHP 100.00%
weather-api weather-app weather-data weather-conditions webservice-client php-weather marine-data marine-resources weather-forecaster-webapp weather-forecast-application json-api stormglass microservice storm

stormyglass's Introduction

# stormyglass - a command-line php script for Storm Glass - The Global Marine Weather Forecast API

CLI script stormyglass.php calls the stormglass weather API and writes the JSON to a file if successful. Optionally will output the result to stdout.

The script can also be run as a web-service with PHP's in-built webserver for testing the JSON request/responses.

Features

  • Runs on the command-line
  • Uses a simple stormyglass.ini configuration file for options
  • Uses command-line curl
  • Can be called as a stand-alone webservice using the php command line built-in server
  • Validates parameters before sending
  • Provided with global city data (populations > 15000) from http://download.geonames.org/export/dump/ (cities15000.zip) listed/saved as JSON using --cities option, see also data/cities15000.txt
  • When calling with a city-id, adds the city information to the 'meta' information returned in the JSON result
  • Option to search for city information with --search-city
  • Caches the result (json-encoded) to avoiding sending repeat-requests with configurable cache age time (in seconds)
  • Cache filename is human-readable - format is: keys-values ie. cache/lat-lng-57.7333333_10.6.json
  • Option to return results averaged-out across sources
  • All messages when running with --debug or --verbose are to stderr to avoid interference with stdout
  • Can output the result if successful to stdout
  • Errors are output in JSON as 'errors' with just a bunch of strings with each error message as opposed to errors => param => array(0 => error) format, e.g.:
{
    "errors": [
        "Unknown param(s) specified: 'humiditys'. Must be at least one of (airPressure, airTemperature, cloudCover, currentDirection, currentSpeed, gust, humidity, precipitation, seaLevel, swellDirection, swellHeight, swellPeriod, visiblity, waterTemperature, waveDirection, waveHeight, wavePeriod, windDirection, windSpeed, windWaveDirection, windWaveHeight, windWavePeriod)"
    ]
}

## Returned results fields/columns/keys

  • time - Timestamp in UTC
  • airTemperature - Air temperature in degrees celsius
  • airPressure - Air pressure in hPa
  • cloudCover - Total cloud coverage in percent
  • currentDirection -Direction of current.
  • currentSpeed - Speed of current in meters per second.
  • gust - Wind gust in m/s
  • humidity - Relative humidity in percent
  • iceCover - Proportion, 0-1
  • precipitation - Mean precipitation in kg/m²
  • seaLevel - Height of sea level in MLLW (tides).
  • snowDepth - Depth of snow in meters
  • swellDirection - Direction of swell waves. 0° indicates swell coming from north
  • swellHeight - Height of swell waves in meters
  • swellPeriod - Period of swell waves in seconds
  • visiblity Horizontal - visibility in km
  • waterTemperature - Water temperature in degrees celsius
  • waveDirection - Direction of combined wind and swell waves. 0° indicates waves coming from north
  • waveHeight - Height of combined wind and swell waves
  • wavePeriod - Period of combined wind and swell waves
  • windWaveDirection - Direction of wind waves. 0° indicates waves coming from north
  • windWaveHeight - Height of wind waves
  • windWavePeriod - Period of wind waves
  • windDirection - Direction of wind. 0° indicates wind coming from north
  • windSpeed - Speed of wind in meters per second

Instructions

Command-line options

Usage: php stormyglass.php
Call to the stormglass API - https://docs.stormglass.io
(Specifying any other unknown argument options will be ignored.)

        -h,  --help                   Display this help and exit
        -v,  --verbose                Run in verbose mode
        -d,  --debug                  Run in debug mode (implies also -v, --verbose)
        -t,  --test                   Run in test mode, using co-ordinates for Skagen, Denmark from stormyglass.ini file by default.
        -o,  --offline                Do not go-online when performing tasks (only use local files for url resolution for example)
        -e,  --echo                   (Optional) Echo/output the result to stdout if successful
             --cities                 List known cities with id, names and geolocation co-ordinates then exit.
             --search-city=<text>     Search for city using supplied text.
        -r,  --refresh                (Optional) Force cache-refresh
        -k,  --key={api key}          (Required) Stormglass API key (loaded from stormyglass.ini if not set)'
             --city-id={city_id}      (Optional) Specify GeoNames city id (in cities.json file) for required latitude/longitude values
             --latitude={-90 - 90}    (Required) Latitude (decimal degrees)
             --longitude={-180 - 180} (Required) Longitude (decimal degrees)
             --source={all}           (Optional) Source. Default: 'all'.  One of (all, dwd, fcoo, fmi, meteo, meto, noaa, sg, smhi, wt, yr)
             --params={}              (Optional) Param(s). Comma-separated. (airPressure, airTemperature, cloudCover, currentDirection, currentSpeed, gust, humidity, precipitation, seaLevel, swellDirection, swellHeight, swellPeriod, visiblity, waterTemperature, waveDirection, waveHeight, wavePeriod, windDirection, windSpeed, windWaveDirection, windWaveHeight, windWavePeriod)
             --date-from={now}        (Optional) Start date/time (at most 48 hours before current UTC), default 'today 00:00:00' see: https://secure.php.net/manual/en/function.strtotime.php
             --date-to={all}          (Optional) End date/time for last forecast, default 'all' see: https://secure.php.net/manual/en/function.strtotime.php
             --average                Return the average of the combined results from across the various sources.
             --dir={}                 (Optional) Directory for storing files (sys_get_temp_dir() if not specified)
        -f,  --filename={output.}     (Optional) Filename for output data from operation
             --format={json}          (Optional) Output format for output filename (reserved for future): json (default)

### Requirements/Installation

  • An API key from stormglass (free sign-up is 50 request/daily)
  • PHP7
  • curl (command-line)
  • Copy the stormyglass.ini.dist to stormyglass.ini and add your API key there.
  • Run php stormyglass.php --cities to generate temp file cities.json file from data/cities15000.tsv

Testing Example

Run the following to run the test and view in 'less' text viewer:

php stormyglass.php --debug --test 2>&1 | less

This will use the default co-ordinates of Skagen, Denmark and if successful will write-out a json file to the cache directory.

Running the same command-line again will retrieve the data from the cached file, e.g. this, which will write the result also to a file called skagen.json

php stormyglass.php --verbose --filename=skagen.json --test 2>&1 | less

Output result to stdout

php stormyglass.php --filename=skagen.json --test --echo

Output the result to stdout, view messages whilst running, and redirect to into another file:

php stormyglass.php --filename=skagen.json --test --debug --echo 2>&1 >myfile.json

Search city example

php stormyglass.php --echo --search-city=birmingham

Results:

{
    "2655603": {
        "id": 2655603,
        "country_code": "GB",
        "state": "ENG",
        "city": "Birmingham",
        "ascii": "Birmingham",
        "names": [
            "BHX",
            "Birmin'gxam",
            "Birmingam",
            "Birmingamas",
            "Birmingem",
            "Birmingema",
            "Birmingham",
            "Birminghamia",
            "Birminghem",
            "Gorad Birmingem",
            "Mpermincham",
            "bamingamu",
            "barming'hyam",
            "barmingahama",
            "barmingahema",
            "barmingham",
            "barminghama",
            "beoming-eom",
            "birmingemi",
            "bo ming han",
            "bo ming han shi",
            "brmngm",
            "brmynghham",
            "byrmngam",
            "parminkam"
        ],
        "latitude": 52.48142,
        "longitude": -1.89983,
        "elevation": 149,
        "population": null,
        "timezone": "Europe\/London"
    },
    "4049979": {
        "id": 4049979,
        "country_code": "US",
        "state": "AL",
        "city": "Birmingham",
        "ascii": "Birmingham",
        "names": [
            "BHM",
            "Bermincham",
            "Bermingkham",
            "Birmingam",
            "Birmingamas",
            "Birmingem",
            "Birmingema",
            "Birmingham",
            "Birmingham i Alabama",
            "Birminhem",
            "Gorad Birmingem",
            "baminguhamu",
            "baminhamu",
            "barmingahema",
            "barmingahyama",
            "beominghaem",
            "birmingemi",
            "bo ming han",
            "brmnghham",
            "brmyngm  alabama",
            "parminkam"
        ],
        "latitude": 33.52066,
        "longitude": -86.80249,
        "elevation": 187,
        "population": 187,
        "timezone": "America\/Chicago"
    },
    "4986172": {
        "id": 4986172,
        "country_code": "US",
        "state": "MI",
        "city": "Birmingham",
        "ascii": "Birmingham",
        "names": [
            "Bermingkham",
            "Birmingem",
            "Birmingkham",
            "brmnghham",
            "byrmngam  myshygan"
        ],
        "latitude": 42.5467,
        "longitude": -83.21132,
        "elevation": 241,
        "population": 237,
        "timezone": "America\/Detroit"
    }
}

Test using averaged-out results

Return averaged-out results across sources, using 'unixtime' as the index for 'hours'

php stormyglass.php --debug --test --average

{
    "hours": {
        "1539302400": {
            "airTemperature": 13,
            "cloudCover": 0,
            "currentDirection": 230,
            "currentSpeed": 0,
            "gust": 10,
            "humidity": 85,
            "precipitation": 0,
            "pressure": 1016,
            "seaLevel": 0,
            "swellDirection": 182,
            "swellHeight": 0,
            "swellPeriod": 3,
            "time": "2018-10-12T00:00:00+00:00",
            "visibility": 26,
            "waterTemperature": 11,
            "waveDirection": 134,
            "waveHeight": 1,
            "wavePeriod": 3,
            "windDirection": 144,
            "windSpeed": 6,
            "windWaveDirection": 138,
            "windWaveHeight": 1,
            "windWavePeriod": 3,
            "unixtime": 1539302400
        },
        "1539306000": {
            "airTemperature": 13,
            "cloudCover": 0,
            "currentDirection": 220,
            "currentSpeed": 0,
            "gust": 9,
            "humidity": 86,
            "precipitation": 0,
            "pressure": 1017,
            "seaLevel": 0,
            "swellDirection": 161,
            "swellHeight": 0,
            "swellPeriod": 3,
            "time": "2018-10-12T01:00:00+00:00",
            "visibility": 25,
            "waterTemperature": 11,
            "waveDirection": 134,
            "waveHeight": 1,
            "wavePeriod": 3,
            "windDirection": 150,
            "windSpeed": 5,
            "windWaveDirection": 138,
            "windWaveHeight": 1,
            "windWavePeriod": 3,
            "unixtime": 1539306000
        },
<!--- SNIP --->
    },
    "meta": {
        "cost": 1,
        "dailyQuota": 50,
        "end": "2018-10-22 00:00",
        "lat": 57,
        "lng": 10,
        "params": [
            "waterTemperature",
            "wavePeriod",
            "waveDirection",
            "waveDirection",
            "waveHeight",
            "windWaveDirection",
            "windWaveHeight",
            "windWavePeriod",
            "swellPeriod",
            "swellDirection",
            "swellHeight",
            "windSpeed",
            "windDirection",
            "airTemperature",
            "precipitation",
            "gust",
            "cloudCover",
            "humidity",
            "pressure",
            "visibility",
            "seaLevel",
            "currentSpeed",
            "currentDirection"
        ],
        "requestCount": 5,
        "start": "2018-10-12 00:00"
    }
}

Test example using GeoNames City ID

Searches for city with ID '8349222'

php stormyglass.php --city-id=8349222 --debug

Debug data of city result:

Array
(
    [8349222] => Array
        (
            [id] => 8349222
            [country_code] => AU
            [state] => 2
            [city] => Punchbowl
            [ascii] => Punchbowl
            [names] => Array
                (
                    [0] =>
                )

            [latitude] => -33.92893
            [longitude] => 151.05111
            [elevation] => 19
            [population] =>
            [timezone] => Australia/Sydney
        )

)

Data saved in: cache/lat-lng--33.92893_151.05111.json

Test example using GeoNames CityID and data from today until next Sunday

This will search the data for Barcelona (city id 3128760) from today (00:00) until 'next Sunday (00:00)', save the result to 'barcelona.json' and also echo the output and debug information, piping it into 'less' to view on the command line.

php stormyglass.php --city-id=3128760 --average --filename=barcelona.json --date-from=today --date-to='next sunday' --echo --debug 2>&1 | less

Offline mode debugging example

An example for debugging - get the wave-height and humidity for Liverpool, UK using data from The Met Office for yesterday 7am until next thursday, 2230 and display the request that would be sent:

php stormyglass.php --debug --filename=liverpool.json --source=met --latitude=53.416667 --longitude=-2.9779400 --params=waveHeight,humidity --date-from='yesterday, 7am' --date-to='next Friday, 2230' --echo 2>&1 | less

Note the V is (--verbose) mode output, and the D is (--debug) mode output, and the numbers following in format 9/9 are memory (used/peak memory used) in script

Result:

[D 1/1] CONFIG
Array
(
    [timezone] => UTC
    [cache] => Array
        (
            [seconds] => 86400
        )

    [key] => **<API_KEY>**
    [url] => Array
        (
            [point] => https://api.stormglass.io/point
            [area] => https://api.stormglass.io/area
        )

    [sources] => Array
        (
            [0] => all
            [1] => dwd
            [2] => fcoo
            [3] => fmi
            [4] => meteo
            [5] => meto
            [6] => noaa
            [7] => sg
            [8] => smhi
            [9] => wt
            [10] => yr
        )

    [params] => Array
        (
            [0] => airPressure
            [1] => airTemperature
            [2] => cloudCover
            [3] => currentDirection
            [4] => currentSpeed
            [5] => gust
            [6] => humidity
            [7] => precipitation
            [8] => seaLevel
            [9] => swellDirection
            [10] => swellHeight
            [11] => swellPeriod
            [12] => visiblity
            [13] => waterTemperature
            [14] => waveDirection
            [15] => waveHeight
            [16] => wavePeriod
            [17] => windDirection
            [18] => windSpeed
            [18] => windSpeed
            [19] => windWaveDirection
            [20] => windWaveHeight
            [21] => windWavePeriod
        )

    [latitude] => 57.7333333
    [longitude] => 10.6
)
[D 1/1] COMMANDS:
Array
(
    [curl] => /usr/local/bin/curl
)
[D 1/1] OPTIONS:
Array
(
    [debug] => 1
    [echo] => 1
    [offline] => 1
    [test] => 0
    [verbose] => 1
)
[V 1/1] OUTPUT_FORMAT: json
[D 1/1] Using API key: **<API_KEY>**
[V 1/1] Latitude: 53.416667
[V 1/1] Longitude: -2.97794
[V 1/1] Param(s):
Array
(
    [0] => waveHeight
    [1] => humidity
)
[V 1/1] Filtering tweets FROM date/time 'yesterday, 7am': Wed, 10 Oct 2018 07:00:00 +0000
[V 1/1] Filtering tweets TO date/time 'next Friday, 2230': Fri, 12 Oct 2018 22:30:00 +0000
[V 1/1] Request params:
Array
(
    [lat] => 53.416667
    [lng] => -2.97794
    [params] => waveHeight,humidity
    [start] => 2018-10-10T07:00:00+00:00
    [end] => 2018-10-12T22:30:00+00:00
)
[D 1/1] Cached file data not found for: /Users/vijay/src/stormyglass/cache/e5afc408fd978d2a46783cc3f770fdcf1821ec5b.json
[D 1/1] OFFLINE MODE! Can't request:
        curl -H "Authorization: **<API_KEY>**" --connect-timeout 3 --max-time 30 --ciphers ALL -k -L -s 'https://api.stormglass.io/point?lat=53.416667&lng=-2.97794&params=waveHeight%2Chumidity&start=2018-10-10T07%3A00%3A00%2B00%3A00&end=2018-10-12T22%3A30%3A00%2B00%3A00'

Error(s):
        - Request failed:

The request obviously failed because we used --offline! Remove it to actually perform the request.

The actual result:

{
    "hours": [
        {
            "humidity": [
                {
                    "source": "sg",
                    "value": 89.98
                },
                {
                    "source": "noaa",
                    "value": 94.16
                },
                {
                    "source": "wrf",
                    "value": 73.94
                },
                {
                    "source": "dwd",
                    "value": 89.98
                }
            ],
            "time": "2018-10-10T07:00:00+00:00",
            "waveHeight": [
                {
                    "source": "sg",
                    "value": 0.3
                },
                {
                    "source": "meto",
                    "value": 0.3
                },
                {
                    "source": "dwd",
                    "value": 0.25
                },
                {
                    "source": "meteo",
                    "value": 0.3
                }
            ]
        },
<---- SNIP!!! ---->
    ],
    "meta": {
        "cost": 1,
        "dailyQuota": 50,
        "end": "2018-10-12 22:30",
        "lat": 53.416667,
        "lng": -2.97794,
        "params": [
            "waveHeight",
            "humidity"
        ],
        "requestCount": 14,
        "start": "2018-10-10 07:00"
    }
}

Updating cities list

Running as a webservice

### Starting the service

  1. Start the PHP webserver with php -S 127.0.0.1:12312
  2. Browse the URL: http://127.0.0.1:12312/stormyglass.php with GET/POST parameters as required.

NOTE: The webservice only allows the following parameters which will be filtered and passed to the command-line script:

  • 'key'
  • 'date-from'
  • 'date-to'
  • 'latitude'
  • 'longitude'
  • 'source'
  • 'params'
  • 'refresh'
  • 'cities'
  • 'city-id'
  • 'search-city'
  • 'average'

Webservice Example 1

e.g. For -id 999999 http://127.0.0.1:12312/stormyglass.php?city-id=999999

http://127.0.0.1:12312/stormyglass.php?city-id=999999

Returns:

{
    "errors": [
        "City not found with id: 292672222"
    ]
}

Webservice Example 2

Search for city 'wolverhampton'

http://127.0.0.1:12312/stormyglass.php?search-city=wolverhampton

Result:

{
    "2633691": {
        "id": 2633691,
        "country_code": "GB",
        "state": "ENG",
        "city": "Wolverhampton",
        "ascii": "Wolverhampton",
        "names": [
            "Goulverchampton",
            "Heantun",
            "Ulvurkhamptun",
            "Vulvergempton",
            "Vulverhamptonas",
            "Vulverhempton",
            "Vulverhemptona",
            "Vulverkhempton",
            "Wolverhampton",
            "Wulfrunehantona",
            "XVW",
            "ulbeohaempeuteon",
            "u~oruvu~ahanputon",
            "wlwrhmptwn",
            "wu er fu han pu dun",
            "wwlbrhmptwn",
            "wwlfrhambtwn",
            "\u0393\u03bf\u03c5\u03bb\u03b2\u03b5\u03c1\u03c7\u03ac\u03bc\u03c0\u03c4\u03bf\u03bd",
            "\u0412\u0443\u043b\u0432\u0435\u0440\u0433\u0435\u043c\u043f\u0442\u043e\u043d",
            "\u0412\u0443\u043b\u0432\u0435\u0440\u0445\u0435\u043c\u043f\u0442\u043e\u043d",
            "\u0423\u043b\u0432\u044a\u0440\u0445\u0430\u043c\u043f\u0442\u044a\u043d",
            "\u054e\u0578\u0582\u056c\u057e\u0565\u0580\u0570\u0565\u0574\u057a\u057f\u0578\u0576",
            "\u05d5\u05d5\u05d0\u05dc\u05d5\u05d5\u05e2\u05e8\u05d4\u05d0\u05de\u05e4\u05d8\u05d0\u05df",
            "\u05d5\u05d5\u05dc\u05d1\u05e8\u05d4\u05de\u05e4\u05d8\u05d5\u05df",
            "\u0648\u0644\u0648\u0631\u0647\u0645\u067e\u062a\u0648\u0646",
            "\u0648\u0648\u0644\u0641\u0631\u0647\u0627\u0645\u0628\u062a\u0648\u0646",
            "\u0648\u0648\u0644\u0648\u0631\u06c1\u06cc\u0645\u067e\u0679\u0646",
            "\u0e27\u0e38\u0e25\u0e40\u0e27\u0e2d\u0e23\u0e4c\u0e41\u0e2e\u0e21\u0e1b\u0e4c\u0e15\u0e31\u0e19",
            "\u10d5\u10e3\u10da\u10d5\u10d4\u10e0\u10f0\u10d4\u10db\u10de\u10e2\u10dd\u10dc\u10d8",
            "\u30a6\u30a9\u30eb\u30f4\u30a1\u30fc\u30cf\u30f3\u30d7\u30c8\u30f3",
            "\u4f0d\u723e\u5f17\u6f22\u666e\u9813",
            "\uc6b8\ubc84\ud584\ud504\ud134"
        ],
        "latitude": 52.58547,
        "longitude": -2.12296,
        "elevation": 160,
        "population": null,
        "timezone": "Europe\/London"
    }
}

The ID 2633691 can then be used to fetch the data for that city.

Webservice Example 3

Get averaged-out results from the web-service for city 1120985:

http://127.0.0.1:12312/stormyglass.php?city-id=1120985&average

Results:

{
    "hours": {
        "1539388800": {
            "airTemperature": 21.07,
            "cloudCover": 0,
            "currentDirection": 0,
            "currentSpeed": 0,
            "gust": 5.88,
            "humidity": 14.35,
            "precipitation": 0,
            "pressure": 1014.57,
            "seaLevel": 0,
            "swellDirection": 0,
            "swellHeight": 0,
            "swellPeriod": 0,
            "time": "2018-10-13T00:00:00+00:00",
            "visibility": 24.1,
            "waterTemperature": 18.55,
            "waveDirection": 0,
            "waveHeight": 0,
            "wavePeriod": 0,
            "windDirection": 0,
            "windSpeed": 0,
            "windWaveDirection": 0,
            "windWaveHeight": 0,
            "windWavePeriod": 0,
            "unixtime": 1539388800
        },
<!--- SNIP --->
    "meta": {
        "cost": 1,
        "dailyQuota": 50,
        "end": "2018-10-23 00:00",
        "lat": 30.95962,
        "lng": 61.86037,
        "params": [
            "airTemperature",
            "cloudCover",
            "currentDirection",
            "currentSpeed",
            "gust",
            "humidity",
            "precipitation",
            "pressure",
            "seaLevel",
            "swellDirection",
            "swellHeight",
            "swellPeriod",
            "visibility",
            "waterTemperature",
            "waveDirection",
            "waveDirection",
            "waveHeight",
            "wavePeriod",
            "windDirection",
            "windSpeed",
            "windWaveDirection",
            "windWaveHeight",
            "windWavePeriod"
        ],
        "requestCount": 4,
        "start": "2018-10-13 00:00",
        "city": {
            "id": 1120985,
            "country_code": "AF",
            "state": 19,
            "city": "Zaranj",
            "ascii": "Zaranj",
            "names": [
                "Sarandsch",
                "ZAJ",
                "Zaranas",
                "Zarandj",
                "Zarandz",
                "Zarandzas",
                "Zarandzh",
                "Zarand\u017c",
                "Zarand\u017eas",
                "Zarang",
                "Zarani",
                "Zaranj",
                "Zaran\u011d",
                "Zerenc",
                "Zhazang",
                "Z\u0259r\u0259nc",
                "zaranja",
                "zha lan ji",
                "zrnj",
                "\u0417\u0430\u0440\u0430\u043d\u0434\u0436",
                "\u0417\u0430\u0440\u0430\u043d\u0438",
                "\u0417\u0430\u0440\u0430\u043d\u04b7",
                "\u0632\u0631\u0646\u062c",
                "\u091c\u093c\u0930\u0902\u091c",
                "\u624e\u5170\u5b63"
            ],
            "latitude": 30.95962,
            "longitude": 61.86037,
            "elevation": 489,
            "population": null,
            "timezone": "Asia\/Kabul"
        }
    }
}

See also

To do

  • Area Request - not yet implemented due to limited API account (uses up requests!)

-- [email protected]

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.