Giter Club home page Giter Club logo

mytselection / carbu_com Goto Github PK

View Code? Open in Web Editor NEW
18.0 5.0 6.0 813 KB

Home Assistant custom component HACS integration to Carbu.com site to compare and save on your actual fuel oil / heating oil (mazout) and fuel (diesel, super and lpg) purchases in Belgium, France and Luxembourg. Actual fuel prices per gasstation supported for Belgium, France, Luxembourg, Spain, Netherlands, Germany, Italy and US too!

License: MIT License

Python 100.00%
fuel-prices hacs home-assistant homeassistant price-tracker python

carbu_com's Issues

Service to get fuel price on custom postal code

Service that is called with args fuel type, country and postal code should give in return the cheapest fuel price and location.

Can be used to create an automation which compares the fuel cost of your current location with the fuel cost of your home location and notify you if (much) cheaper

Unique ids

Hi
Is it possible to add unique ids to the sensors? Ive tried to add multiple hubs in the carbu integration, so for instance 1 fuel station in NL and 2 in Belgiu 'maasmechelen with zipcode 3630, one in BE is succesfull, the other BE is not:

Platform carbu_com does not generate unique IDs. ID Carbu.com super95 prediction already exists

Platform carbu_com does not generate unique IDs. ID Carbu.com super95 3630 price already exists

Maybe you can add the name of the fuel station after the zipcode in the sensor id/name?

Thanks!

one fuel station is missing & markdown card question

Hi again!
I've got 2 things to mention:

Looks like this fuel station is missing / not listed anymore when I search for it in the dropdown (zip code 3630):

I also try to use the markdown card but I can't get this part to work:
image
The result stays on "none" but the prices differs between the two fuelstations, so I expect to see a result.
any ideas to get this fixed? is your example code still valid?

thanks!

Showing a Fuelstation +30km away as the locale cheapest

Hi,

I've set this up for my current hometown (3650) and then it works perfect. yet for our new town (3960 Bree) it shows a fuelstation +30km away as the "cheapest local"
Bree fuel
here is the Carbu link for the Bocken NV station so you can see the adress : https://carbu.com/belgie/index.php/station/vrijlibre/maasmechelen/3630/2216

Would there be any way to add a check that if it's + xx km's away (free to setup or so I suppose) it will not show up in the integration.

Kind regards,

Jordy

carbu_com does not generate unique IDs

There should be a check in place to filter out existing places/postcoded.

Logger: homeassistant.components.sensor
Source: helpers/entity_platform.py:540
Integration: Sensor (documentation, issues)
First occurred: 9:50:13 AM (1 occurrences)
Last logged: 9:50:13 AM

Platform carbu_com does not generate unique IDs. ID Carbu.com diesel 2470 price already exists - ignoring sensor.carbu_com_diesel_2470_price

Price prediction date

I assume this is a bug since the attributes contain both a 'last update' and 'date' but they're the same. If would be more useful if the latter would indicate when the price will probably change.

Screenshot_20231101-222455.png

URL of 5km & 10km fuel station is NULL/Unknown

There seems to be an issue in the way URL's are generated for fuelstations. See screenshots. Maybe only an NL issue?
When I go to Developer Tools>States and compare the attributes for

  • sensor.carbu_com_super95_3731_ge_10km
  • sensor.carbu_com_super95_3731_ge_5km
  • sensor.carbu_com_super95_3731_ge_price

Only the sensor ending with _price has a valid URL for the fuelstation. The other ones have null as URL.
In this situation the cheapest station for all the 3 sensors are one and the same. So all three should have the same URL

Screenshot 2023-08-06 at 10 40 29 Screenshot 2023-08-06 at 10 40 00 Screenshot 2023-08-06 at 10 39 42

How to get prices for a specific service station?

I really like this integration, but I was wondering if I could select the prices for a specific service station?
I've got several stations nearby, but they are geographically on opposite sides of town (one S, one N), the distance to my home is more or less the same.
It would be great if I could get the prices of both of them and put them next to each other.
Does the service supports the data-id from the source?

Another question more or less related.
I can call the service carbu_com.get_lowest_fuel_price but where is the response going? I just can't find the event in all the other events that are happening at the same time. So I also ask some advice on how to setup an automated service call which collects the results in a sensor so it can be exposed in a Lovelace dashboard.

PostalCode read incorrectly from JSON

While checking the state of the entities of Carbu, it caught my eye that the postal code for Dutch gasstations is wrong. In my entity it reads:
postalcode: NoneNone

I checked utils.py and it reads pc_cijfer and pc_letter (

'postalcode': f"{block.get('station').get('pc_cijfer')}{block.get('station').get('pc_letter')}",
).

I checked the JSON response from the URL and now there is a postcode field in the JSON. I think that's the one you need to get.

Feature Request: Can we have a friendlier friendly_name?

Installed your Custom Component after the provider for Skons "dutch_gas_prices" apparently blocked access to their API.
Living literally on the border between Belgium and the Netherlands, I appreciate very much your components allows to query both sides of the border.
What I really liked about Skons' solution was that it allowed to create a "friendly_name" using any attribute returned in the sensor.
See Skons' DOCS.md for more information.

Thanks for the great work

Edit: I may have been shooting faster than my shadow .... blame it on being a newbie around here. Found this article in HA Configuration .... Would this be the way to provide a friendly name?

Not possible to distinguish between areas with the same postal code

On carbu.com website you can enter a city/village by name, which will yield the correct result. In the integration it's not the case always.

E.g. imagine you live in Vissenaken (3300), a deelgemeente of Tienen, there is currently no way to get results for this location as it will take Tienen.

I believe at the moment it just takes whatever result comes first in the list, V comes after T, so you're out of luck ;-)

Only pulls in 1 station per postcode

Setting up this integration only seems to set up a single device with a single entity.
Not sure if feature or bug.
I don't know what the logic here is: does it currently get the cheapest station, the first station in the list?
Feature request: would be nice if it adds all stations (entities) per postcode (device).

ValueError: could not convert string to float: ''

Location "Lanaken" is not working properly. Upon inspecting I'm guessing it's using the wrong location ID (https://carbu.com//commonFunctions/getlocation/controller.getlocation_JSON.php?location=3620&SHRT=1)
BE_li_635 comes before BE_li_636 (the correct one) here, and the first one gets picked.
Maybe make both postal code and location ID required or at least configurable during setup to prevent this? While adding some documentation on how to find it ofc.

Logger: homeassistant.helpers.entity
Source: custom_components/carbu_com/sensor.py:440
Integration: Carbu.com (documentation, issues)
First occurred: 15:16:01 (4 occurrences)
Last logged: 15:16:01

Update for sensor.carbu_com_super95_3620_5km fails
Update for sensor.carbu_com_super95_3620_10km fails
Update for sensor.carbu_com_diesel_3620_5km fails
Update for sensor.carbu_com_diesel_3620_10km fails
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 550, in async_update_ha_state
await self.async_device_update()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 755, in async_device_update
raise exc
File "/config/custom_components/carbu_com/sensor.py", line 440, in async_update
localPrice = float(self._priceinfo[0].get("price"))
ValueError: could not convert string to float: ''

Service call error

Tried to call the following service:

service: carbu_com.get_lowest_fuel_price_on_route
data:
  fuel_type: diesel
  country: BE
  from_postalcode: '2470'
  to_postalcode: '2490'
  ors_api_key: '123xyz_real_key'

Getting the following errors:

This error originated from a custom integration.

Logger: homeassistant.helpers.script.websocket_api_script
Source: custom_components/carbu_com/utils.py:422
Integration: Carbu.com (documentation, issues)
First occurred: 14:41:48 (2 occurrences)
Last logged: 14:43:08

websocket_api script: Error executing script. Unexpected error for call_service at pos 1:
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 452, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 685, in _async_call_service_step
    await service_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1849, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1889, in _execute_service
    await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
  File "/config/custom_components/carbu_com/__init__.py", line 128, in handle_get_lowest_fuel_price_on_route
    station_info = await hass.async_add_executor_job(lambda: session.getPriceOnRoute(country, fuel_type, from_postalcode, to_postalcode, ors_api_key))
  File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/carbu_com/__init__.py", line 128, in <lambda>
    station_info = await hass.async_add_executor_job(lambda: session.getPriceOnRoute(country, fuel_type, from_postalcode, to_postalcode, ors_api_key))
  File "/config/custom_components/carbu_com/utils.py", line 422, in getPriceOnRoute
    assert from_location is not None
AssertionError

And

Logger: homeassistant.components.websocket_api.http.connection
Source: custom_components/carbu_com/utils.py:422
Integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 14:41:48 (2 occurrences)
Last logged: 14:43:08

[546767443936] Error handling message: Unknown error (unknown_error) Jorim Tielemans from 127.0.0.1 (Mozilla/5.0 (Linux; Android 13; A063 Build/TKQ1.221220.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.53 Mobile Safari/537.36 Home Assistant/beta-10008-d81913b7-10008 (Android 13; A063))
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/decorators.py", line 26, in _handle_async_response
    await func(hass, connection, msg)
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 647, in handle_execute_script
    await script_obj.async_run(msg.get("variables"), context=context)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1533, in async_run
    await asyncio.shield(run.async_run())
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 410, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 454, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 477, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 452, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 685, in _async_call_service_step
    await service_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1849, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1889, in _execute_service
    await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
  File "/config/custom_components/carbu_com/__init__.py", line 128, in handle_get_lowest_fuel_price_on_route
    station_info = await hass.async_add_executor_job(lambda: session.getPriceOnRoute(country, fuel_type, from_postalcode, to_postalcode, ors_api_key))
  File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/carbu_com/__init__.py", line 128, in <lambda>
    station_info = await hass.async_add_executor_job(lambda: session.getPriceOnRoute(country, fuel_type, from_postalcode, to_postalcode, ors_api_key))
  File "/config/custom_components/carbu_com/utils.py", line 422, in getPriceOnRoute
    assert from_location is not None
AssertionError

Error while setting up carbu_com platform for sensor

Seen a few times now, thought it was a network hiccup but happens every once in a while.

Logger: homeassistant.components.sensor
Source: custom_components/carbu_com/utils.py:166
Integration: Sensor (documentation, issues)
First occurred: 22:36:56 (1 occurrences)
Last logged: 22:36:56

Error while setting up carbu_com platform for sensor
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 293, in _async_setup_platform
    await asyncio.shield(task)
  File "/config/custom_components/carbu_com/sensor.py", line 131, in async_setup_entry
    await dry_setup(hass, config, async_add_devices)
  File "/config/custom_components/carbu_com/sensor.py", line 60, in dry_setup
    await componentData._forced_update()
  File "/config/custom_components/carbu_com/sensor.py", line 223, in _forced_update
    prediction_info = await self._hass.async_add_executor_job(lambda: self._session.getFuelPrediction(self._diesel_fueltype_prediction_code))
  File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/carbu_com/sensor.py", line 223, in <lambda>
    prediction_info = await self._hass.async_add_executor_job(lambda: self._session.getFuelPrediction(self._diesel_fueltype_prediction_code))
  File "/config/custom_components/carbu_com/utils.py", line 166, in getFuelPrediction
    return value
UnboundLocalError: local variable 'value' referenced before assignment

Filter suppliers

It would be nice to have an option to pass in suppliers you want/don't want to be included in the search query

Platform carbu_com does not generate unique IDs

Logger: homeassistant.components.sensor
Source: helpers/entity_platform.py:610
Integration: Sensor (documentation, issues)
First occurred: 16:41:27 (2 occurrences)
Last logged: 16:41:27

ID Carbu.com super95 prediction already exists - ignoring sensor.carbu_com_super95_prediction
Platform carbu_com does not generate unique IDs. ID Carbu.com super95 official e10 already exists - ignoring sensor.carbu_com_super95_official_e10

Wrong postcode search

Hi,

Great tool. I given my postcode 1082SG and Amsterdam. Those sensors are created:

sensor.carbu_com_super95_1082sg_10km
sensor.carbu_com_super95_1082sg_5km
sensor.carbu_com_super95_1082sg_price

But the name of sensors show this:

Carbu.com super95 1431WC 10km
Carbu.com super95 1431WC 5km
Carbu.com super95 1431WC price

1431WC is a total different postcode.

attribution: Carbu.com
last update: 2023-08-04T07:46:36.696720
fueltype: super95
fuelname: SUPER95
postalcode: 1431WC
supplier: Aalsmeer
supplier_brand: Tango
url: https://www.brandstof-zoeker.nl/station/tango-aalsmeer-2934
entity_picture: https://www.prezzibenzina.it/www2/marker.php?brand=TA&status=AP&price=2.009&certified=0&marker_type=1
address: Dreef 3
city: Aalsmeer
latitude: 52.256157
longitude: 4.765363
distance: 3.496622887109303km
date: 4 augustus 2023
quantity: 0
score: null
filter: 
country: NL
unit_of_measurement: €/l
device_class: monetary
icon: mdi:gas-station
friendly_name: Carbu.com super95 1431WC price

When I check brandstof zoeker then there are no hits on 1082SG. Maybe that is the issue? Better to make the sensor as: no info yet or something?

State attributes for sensor.carbu_com* exceed maximum size of 16384 bytes

Version 1.0.0:

Logger: homeassistant.components.recorder.db_schema
Source: components/recorder/db_schema.py:491
Integration: Recorder (documentation, issues)
First occurred: 11:57:41 (8 occurrences)
Last logged: 11:57:44

State attributes for sensor.carbu_com_diesel_2440_price exceed maximum size of 16384 bytes. This can cause database performance issues; Attributes will not be stored
State attributes for sensor.carbu_com_diesel_2450_price exceed maximum size of 16384 bytes. This can cause database performance issues; Attributes will not be stored
State attributes for sensor.carbu_com_diesel_2470_price exceed maximum size of 16384 bytes. This can cause database performance issues; Attributes will not be stored
State attributes for sensor.carbu_com_diesel_2400_price exceed maximum size of 16384 bytes. This can cause database performance issues; Attributes will not be stored

fetch prices for selected stations

Thanks for this great integration!

Would it be possible to retrieve and display the price for one or two selected stations in home assistant?
I have a card for one brand (Total Energies) and two stations at about the same distance from my home. Their prices change often and sometimes show quite a nice difference...

Cheers,

Phil

BE-9052 location becomes 9050 sensor

Configuring a 9052 BE postalcode for Carbu.com integration resulted in a sensor.carbu_com_super95_9052_5km sensor in HA, however the name of the sensor became "Carbu.Com Super95 9050 5Km".
So i'm wondering, is the bug in the naming (very small issue) or is the bug in the postalcode used in the algorithmes?

afbeelding

afbeelding

service: carbu_com.get_lowest_fuel_price

Hello, great job.
before this I scraped the sites also.

Quick Q:

I noticed that the service: carbu_com.get_lowest_fuel_price
is only working for BE?
because I only get data when i use like.

service: carbu_com.get_lowest_fuel_price
data: 
  fuel_type: diesel
  country: BE
  postalcode: 3620
  max_distance: 10

if I do

service: carbu_com.get_lowest_fuel_price
data: 
  fuel_type: diesel
  country: NL
  postalcode: 6051 JR
  max_distance: 10

I get errors

thanks for the answer ;)

Warning: Detected code that calls async_forward_entry_setup

Logger: homeassistant.helpers.frame
Source: helpers/frame.py:151
First occurred: 00:28:51 (7 occurrences)
Last logged: 00:30:33

Detected code that calls async_forward_entry_setup for integration carbu_com with title: Diesel Retie and entry_id: 2c1e56b1a30143e38423615c975eb62c, during setup without awaiting async_forward_entry_setup, which can cause the setup lock to be released before the setup is done. This will stop working in Home Assistant 2025.1. Please report this issue.
Detected code that calls async_forward_entry_setup for integration carbu_com with title: Super 95 Meerhout and entry_id: 968a519797b373c44ddda8df1912a031, during setup without awaiting async_forward_entry_setup, which can cause the setup lock to be released before the setup is done. This will stop working in Home Assistant 2025.1. Please report this issue.

AttributeError: 'NoneType' object has no attribute 'lower'

Logger: homeassistant.components.sensor
Source: custom_components/carbu_com/utils.py:46
Integration: Sensor (documentation, issues)
First occurred: 2:19:52 AM (3 occurrences)
Last logged: 2:19:52 AM

Error while setting up carbu_com platform for sensor
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 304, in _async_setup_platform
    await asyncio.shield(task)
  File "/config/custom_components/carbu_com/sensor.py", line 132, in async_setup_entry
    await dry_setup(hass, config, async_add_devices)
  File "/config/custom_components/carbu_com/sensor.py", line 61, in dry_setup
    await componentData._forced_update()
  File "/config/custom_components/carbu_com/sensor.py", line 199, in _forced_update
    self._carbuLocationInfo = await self._hass.async_add_executor_job(lambda: self._session.convertPostalCode(self._postalcode, self._country, self._town))
  File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/carbu_com/sensor.py", line 199, in <lambda>
    self._carbuLocationInfo = await self._hass.async_add_executor_job(lambda: self._session.convertPostalCode(self._postalcode, self._country, self._town))
  File "/config/custom_components/carbu_com/utils.py", line 46, in convertPostalCode
    if info_dict["n"].lower() == town.lower() and info_dict["c"].lower() == country.lower() and info_dict["pc"] == postalcode:
AttributeError: 'NoneType' object has no attribute 'lower'

Trying to adjust radius

Thanks for this great integration. I use carbu.com quite often, nice to have it integrated in HA for further automation possibilities.

I would like to adjust the radius to 10 & 20 km. So I tried in sensor.py to change:

sensorSuper95Neigh = ComponentPriceNeighborhoodSensor(componentData, FuelType.SUPER95, postalcode, 5)
to
sensorSuper95Neigh = ComponentPriceNeighborhoodSensor(componentData, FuelType.SUPER95, postalcode, 10)

but I guess this would have been to simple.. in any case this action wasn't successful, any hints on how to adjust the radius?

Thinking further it would be a 'nice to have' add on for the integration to have this configuration option at the start. But no clue (yet) how to build this.

Again thanks a lot and keep up the good work!

Cheapest fuel price on route service

Service that is called with start and target location (or postal code) should determine all locations on the route and find the cheapest fuel price on the route.

Location as Entity

Hello 👋

Many thanks for this integration ... it looks really nice 👍

I was wondering if it's possible to put the stations on a map widget,
seems i can do that via en template sensor, but i guess it could be handy to add that for others too and put it directly in the integration.
What do you think ?

warning insecure https request

Some warning appear during boot, to be analysed

WARNING (SyncWorker_12) [py.warnings] /usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py:1061: InsecureRequestWarning: Unverified HTTPS request is being made to host 'api.carbu.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  warnings.warn(

[enhancement] Alternative markdown card with prices for local, 5 & 10 km

Carbu

First of all, thank you very much for this impressive and useful integration.
I have redesigned your markdown card a bit in order to display the local, 5 km and 10 km prices next to each other.
Just my small contribution to the community.

type: vertical-stack
cards:
  - type: markdown
    content: >
      ## Super95 benzine

      #### Komende dagen: {% if
      states('sensor.carbu_com_super95_prediction')|float < 0 %}<font
      color=green>{{states('sensor.carbu_com_super95_prediction')}}%</font>{%
      else %}<font
      color=red>{{states('sensor.carbu_com_super95_prediction')}}%</font>{%
      endif %}
  - type: horizontal-stack
    cards:
      - type: markdown
        content: >
          #### <center>lokaal </center>


          <center><img
          src="{{state_attr('sensor.carbu_com_super95_3010_price','logourl')}}"
          width="45"/> </center>


          <center>


          [{{state_attr('sensor.carbu_com_super95_3010_price','supplier')}}]({{state_attr('sensor.carbu_com_super95_3010_5km','url')}})

          ### <center>{{states('sensor.carbu_com_super95_3010_price')}} €/l
      - type: markdown
        content: >
          #### <center>5 km</center>

          <center><img
          src="{{state_attr('sensor.carbu_com_super95_3010_5km','logourl')}}"
          width="45"/></center>


          <center>


          [{{state_attr('sensor.carbu_com_super95_3010_5km','supplier')}}]({{state_attr('sensor.carbu_com_super95_3010_5km','url')}})

          ### <center>{{states('sensor.carbu_com_super95_3010_5km')}} €/l

          Besparing tov lokaal = 
          {{state_attr('sensor.carbu_com_super95_3010_5km','price diff %')}} of
          **{{state_attr('sensor.carbu_com_super95_3010_5km','price diff
          30l')}}** op 30l
      - type: markdown
        content: >
          #### <center>10 km

          <center><img
          src="{{state_attr('sensor.carbu_com_super95_3010_10km','logourl')}}"
          width="45"/></center>


          <center>


          [{{state_attr('sensor.carbu_com_super95_3010_10km','supplier')}}]({{state_attr('sensor.carbu_com_super95_3010_5km','url')}})

          ### <center>{{states('sensor.carbu_com_super95_3010_10km')}} €/l

          Besparing tov lokaal = 
          {{state_attr('sensor.carbu_com_super95_3010_10km','price diff %')}} of
          **{{state_attr('sensor.carbu_com_super95_3010_10km','price diff
          30l')}}** op 30l

Postal code not correct

Asking for postal 9100 and getting 2070 ?
[sensor.carbu_com_super98_9100_price] = Carbu.com super98 2070 price

region 5km & 10km on postal 9100 are correct

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.