alfiopuglisi / guietta Goto Github PK
View Code? Open in Web Editor NEWHome Page: https://guietta.readthedocs.io
License: MIT License
Home Page: https://guietta.readthedocs.io
License: MIT License
Hello there,
first of all, you did an amazing job with this tool, its really easy to use.
Here are my questions;
Thanks for reading, and once again good job.
In https://guietta.readthedocs.io/en/latest/reference.html?highlight=Hseparator#widgets
HSeparator not found, but renaming to Separator?
In "guietta.py"
'''
List of widget shortcuts:
'text' -> QLabel('text')
...
R('text') -> QRadioButton('text')
HS('name') -> QSlider(Qt::Horizontal), name set to 'name'
VS('name') -> QSlider(Qt::Horizontal), name set to 'name'
Separator -> Horizontal separator
VSeparator -> Vertical separator
widget -> any valid QT widget is accepted
...
If I change HSeparator to Separator, it works!
Thank you for your work.
I have implemented three radio buttons with guietta like,
from guietta import _ , Gui , Quit , R1 , R2 , R3
app = Gui(
[ R1( "r1") , R1( "r2" ) , R1( "r3" ) ],
)
How do I check whether which radio button is checked by the user? How do I listen for click events for radio buttons?
I'm not sure if this is a bug or user error. This is on the master branch.
# example.py
from guietta import Gui, CB
def change(gui, value):
print(value)
gui = Gui(
[CB("op", ["a", "b", "c"])]
)
gui.events([change])
gui.run()
Errors with
Traceback (most recent call last):
File "/nix/store/qkci2s9sqjdbr3dlzvlnv7xywma2s296-python3-3.7.6-env/lib/python3.7/site-packages/guietta/guietta.py", line 1387, in _connect
signal = getattr(widget, signal_name)
AttributeError: 'ContextQComboBox' object has no attribute 'textActivated'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "guietta-example.py", line 9, in <module>
gui.events([change])
File "/nix/store/qkci2s9sqjdbr3dlzvlnv7xywma2s296-python3-3.7.6-env/lib/python3.7/site-packages/guietta/guietta.py", line 1631, in events
_connect(self, item, signal_name, slot)
File "/nix/store/qkci2s9sqjdbr3dlzvlnv7xywma2s296-python3-3.7.6-env/lib/python3.7/site-packages/guietta/guietta.py", line 1390, in _connect
(signal_name, str(widget.__class__))) from e
ValueError: No signal textActivated found for widget <class 'guietta.guietta.ContextQComboBox'>
Several MacOS users reported that widgets often do not refresh, and they need to re-focus the window before a change is shown. It appears to be a Qt for Mac bug, and a possible workaround is to call repaint() on the widget.
Need to test it on a recent Mac.
Quickly following the docs examples I got the error bellow. I was hoping for those placeholders to be converted to strings automatically but it seems like they aren't in some cases. Perhaps this is a good area to add some unit testing?
[ _ , _ , _ , replot ],
[ _ , _ , _ , _ ],
[ _ , _ , _ , _ ], )
[ _ , _ , _ , replot ],
NameError: name '_' is not defined
First, I have to say that I love guietta. It indeed makes simple GUIs simple. Yay! I know past jobs that I would have done with it, had it existed earlier. Some of my future jobs will use it I guess!
On https://guietta.readthedocs.io/en/latest/index.html#installation says:
pip install guietta
and on https://guietta.readthedocs.io/en/latest/reference.html#guietta.Gui
class guietta.Gui(*lists, images_dir='.', create_properties=True, exceptions=<Exceptions.POPUP: 3>, persistence=1, title='')
Notice that all pages there mention "guietta 0.3.4 documentation".
Following https://guietta.readthedocs.io/en/latest/index.html#installation :
pip install guietta
Collecting guietta
Using cached guietta-0.3.4-py2.py3-none-any.whl (37 kB)
Requirement already satisfied: PySide2 in _someplace_ (from guietta) (5.15.0)
Requirement already satisfied: shiboken2==5.15.0 in _someplace_ (from PySide2->guietta) (5.15.0)
Installing collected packages: guietta
Successfully installed guietta-0.3.4
Create this file test.py
:
from guietta import Gui
gui = Gui(
[ 'test' ]
)
gui2 = Gui(
[ 'test' ],
title="foo"
)
python test.py
Traceback (most recent call last):
File "test.py", line 7, in <module>
gui2 = Gui(
TypeError: __init__() got an unexpected keyword argument 'title'
(python)
git clone https://github.com/alfiopuglisi/guietta
cd guietta
pip install -e $PWD
Obtaining file:///_someplace_
Requirement already satisfied: PySide2 in _someplace_ (from guietta==0.3.4) (5.15.0)
Requirement already satisfied: shiboken2==5.15.0 in _someplace_ (from PySide2->guietta==0.3.4) (5.15.0)
Installing collected packages: guietta
Attempting uninstall: guietta
Found existing installation: guietta 0.3.4
Uninstalling guietta-0.3.4:
Successfully uninstalled guietta-0.3.4
Running setup.py develop for guietta
Successfully installed guietta
Then back to previous directory:
python test.py
No error!
There are two problems.
pip install guietta
) does not match the documentation content.title
which is not in 0.3.4 and was added two commits later.I can't publish code that relies on title
feature and pip install guietta
, it will break for users.
Three steps:
Thanks!
I need to resize the components in the GUI window.
when I use the resize function:
edit = gui.QPlainTextEdit
edit .resize(800,600)
but the QPlainTextEdit is still very small!!
I cant't resize components??
I need to use QFileDialog in my app. However it needs a handle to call the QFileDialog. How can I access the Qt handle of a Gui instance?
Hi!
Operating System: Windows 8.1
Python version: Python 3.7.4
guietta Port and Version: guietta 0.3.8
Code or partial code causing the problem:
1. How do I AlignTop a subgui? How do I implement AlignTop with the parent main.layout() as default or directly to the subgui.layout()? Please see attached screenshot.
Thank you.
I'm trying to make a gui which has a sub-gui section which changes based on user interaction. For example, the code below:
from guietta import Gui, C, R, III, VS, HS, _, ___, G
main = Gui( [G("Inner GUI") , ["Get Subgui1"]],
[ III , ["Get Subgui2"]])
subgui1 = Gui([C('First') , '__First__'],
[R('First') , ['button1!']])
subgui2 = Gui([VS("Gui 2 Slider") , HS("Gui 2 Slider"), ___],
[III , _ , _ ])
with main.GetSubgui1:
if main.is_running:
main.InnerGUI = subgui1
with main.GetSubgui2:
if main.is_running:
main.InnerGUI = subgui2
main.run()
"subgui1" is shown in the groupbox "Inner GUI" if the appropriate button is pressed. The same is true for "subgui2". On the first press of either option, the appropriate subgui is shown. Pressing the other button after the first subgui has been shown results in no change.
I would expect that clicking on the second button would replace the subgui which is already in the groupbox.
Hi!
Operating System: Windows 8.1
Python version: Python 3.7.4
guietta Port and Version: guietta 0.3.8
Code or partial code causing the problem:
from guietta import _, Gui, Quit
first = True
gui = Gui(
[ "Enter numbers:", "a", "+", "b", ["Calculate"] ],
[ "Result: -->", "result", _, _, _ ],
[ _, _, _, _, Quit ]
)
with gui.Calculate:
if first:
first = False
gui.result = ""
else:
gui.result = float(gui.a) + float(gui.b)
gui.run()
Program code: (I could not get the above code to properly indent so I attached the file.)
gCalculator.txt
Screenshots:
Narrative:
The intention is to initialize gui.result to show blank at the first display of the screen instead of showing "result".
The code above worked but upon clicking the "Calculate" button, with or without entries in the two input fields, I get the error:
"UnBoundLocalError: local variable 'first' referenced before assignment"
Please tell me how to initialize gui.result without causing any error to the program.
Thank you.
Currently, there does not seem to be any way to override the keyPressed event for QLineEdit. Any workarounds available?
Using guietta, a simple password application would look like
from guietta import _, Gui, Quit
gui = Gui(
[ 'Enter Username:', '__username__' , _ , _, ['Login'] ],
[ 'Enter Password:' , '__password__' , _ , _ , _ ],
[ "Access Level: " , "Access_Level" , _ , _ , Quit ]
)
with gui.Login:
if gui.username == "Username" and gui.password == "Password":
gui.Access_Level = "Admin"
else:
gui.Access_Level = "Incorrect Login Entered"
gui.run()
The only problem is that the password is obvious to everyone. Is there any way to hide it?
Python version used : 3.7
kindly help to resolve this issue.
script :
from guietta import _, Gui, Quit
gui = Gui(
[ 'Enter numbers:', 'a' , '+' , 'b', ['Calculate'] ],
[ 'Result: -->' , 'result' , _ , _ , _ ],
[ _ , _ , _ , _ , Quit ]
)
with gui.Calculate:
gui.result = gui.a + gui.b
gui.run()
C:\Users\labuser\Downloads\temp>python cguietta.py
Traceback (most recent call last):
File "cguietta.py", line 11, in
gui.result = gui.a + gui.b
File "C:\Users\labuser\AppData\Local\Programs\Python\Python37\lib\site-packages\guietta\guietta.py", line 159, in exit
raise ValueError('Could not determine the Gui instance identifier')
ValueError: Could not determine the Gui instance identifier
C:\Users\labuser\Downloads\temp>
One of your examples is the matplotlib.py
script, which of course needs to import matplotlib to function, but can't since the file itself in the examples directory is called matplotlib.py
.
The following example causes Python to crash on Windows 10 19041 running Python 3.8.3.
The GUI displays correctly, but when an attempt is made to place the mouse over it, it locks up and Windows offers to close it as Not Responding.
Here is the complete widget set:
from guietta import Gui, B, E, L, HS, VS, HSeparator, VSeparator
from guietta import Yes, No, Ok, Cancel, Quit, _, ___, III
gui = Gui(
[ '<center>A big GUI with all of Guietta''s widgets</center>'],
[ HSeparator ],
[ 'Label' , 'imagelabel.jpeg' , L('another label') , VS('slider1')],
[ _ , ['button'] , B('another button') , III ],
[ '__edit__' , E('an edit box') , _ , VSeparator ],
[ Quit , Ok , Cancel , III ],
[ Yes , No , _ , III ],
[ HS('slider2'), ___ , ___ , _ ] )
gui.show()
I just installed Guietta because i got a new pc, and i tried the example but this exception kept appearing
>>> from guietta import _, Gui, Quit
>>> gui = Gui(
... [ "Enter numbers:", "__a__", "+", "__b__", ["Calculate"] ],
... [ "Result: -->", "result", _, _, _ ],
... [ _, _, _, _, Quit ]
... )
>>>
>>> with gui.Calculate:
... gui.result = float(gui.a) + float(gui.b)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: __enter__
>>> gui.run()
Guietta version is (0.2.3)
Hi!
Operating System: Windows 8.1
Python version: Python 3.7.4
guietta Port and Version: guietta 0.3.8
Code or partial code causing the problem:
Thank you.
Examples:
block = False
, regardless of timeout:
Traceback (most recent call last):
File "gui.py", line 36, in <module>
name, event = gui.get(block=False)
File "/tmp/gui/.pyenv/lib/python3.8/site-packages/guietta/guietta.py", line 1652, in get
QTimer.singleShot(timeout * 1000,
TypeError: 'PySide2.QtCore.QTimer.singleShot' called with wrong argument types:
PySide2.QtCore.QTimer.singleShot(int, TimerType, method)
Supported signatures:
PySide2.QtCore.QTimer.singleShot(int, typing.Callable)
PySide2.QtCore.QTimer.singleShot(int, PySide2.QtCore.QObject, bytes)
PySide2.QtCore.QTimer.singleShot(int, PySide2.QtCore.Qt.TimerType, PySide2.QtCore.QObject, bytes)
shell returned 1
timeout = anything
(even an int):
Traceback (most recent call last):
File "gui.py", line 36, in <module>
name, event = gui.get(timeout=0.1)
File "/tmp/gui/.pyenv/lib/python3.8/site-packages/guietta/guietta.py", line 1652, in get
QTimer.singleShot(timeout * 1000,
TypeError: 'PySide2.QtCore.QTimer.singleShot' called with wrong argument types:
PySide2.QtCore.QTimer.singleShot(float, TimerType, method)
Supported signatures:
PySide2.QtCore.QTimer.singleShot(int, typing.Callable)
PySide2.QtCore.QTimer.singleShot(int, PySide2.QtCore.QObject, bytes)
PySide2.QtCore.QTimer.singleShot(int, PySide2.QtCore.Qt.TimerType, PySide2.QtCore.QObject, bytes)
shell returned 1
On Mac OS, when I try to set a file path value to a label, it can't be displayed. for example
from guietta import Gui, _, QFileDialog, ___
gui = Gui(
['File Name:', 'fileName', ___, ___, ['Open']])
def openFile(gui, *args):
result = QFileDialog.getOpenFileName(parent=None, caption='Select a file', directory='.',
filter="ALL(*.*);;Images(*.png *.jpg);;Python(*.py)")
gui.fileName = result[0]
gui.Open = openFile
gui.run()
After clicking "Open" button and slect a file, I set the return value to gui.fileName, however it shows empty string. But from debugging I can see it does have the value.
HTML can be used to enhance labels in the gui. For example, the following gui:
from guietta import Gui
gui = Gui(
["a boring, normal label"],
["<p style='color:red;font-size:20px'><i>Super cool label"]
)
gui.run()
Guietta's magic properties dutifully gives me two names, one for each of these labels. The first, "aboringnormallabel", and the second, "pstylecolorredfontsize20pxiSupercoollabel".
"pstylecolorredfontsize20pxiSupercoollabel" is 41 characters long.
It would be nice to be able to make the magic properties ignore the html tags, or to set the widget name myself.
input:
from guietta import _, Gui, Quit
output:
qt.qpa.plugin: Could not load the Qt platform plugin "windows" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
Available platform plugins are: direct2d, minimal, offscreen, windows.```
Hi
Is there a way to create a plot with a projection in guietta, e.g. for a polar or 3d plot?
I believe the corresponding projection keyword has to be supplied to matplotlib's add_subplot, which is currently not implemented in guietta. Maybe one can add the projection keyword to the MatplotlibWidget? It would be quite a simple change to enhance the plot types available. And because the keyword is optional, it would be backward compatible.
Cheers!
Given the incompatibility of pip's QT implementation with conda as mentioned by documentation, will a dedicated build for conda make more sense for other packages to properly depend on guietta?
Some reasons why this approach may make sense:
pyinstaller app.py --name=MyApp
Traceback (most recent call last):
File "app.py", line 45, in <module>
some_gui = Gui(['status', ___],
File "lib\site-packages\guietta\guietta.py", line 1509, in __init__
IndexError: ___ at the beginning of a row
[13116] Failed to execute script app
To workaround this issue, you can replace all ___ (three underscores - Horizontal widget span) with something else. Your GUI will not look the same, but after running pyinstaller again, the application works.
Possible solution would be to replace the ___ (three underscores) with some other set of characters (for example: HHH).
Hi,
First, this project is really awesome! I think it will help a lot introducing GUI programming to a larger audience, specially for scientific software.
But most important, the www.guietta.com page seems to lead to a weird ad page? Is that intented, or did the domain expire or something similar? From a quick search in name and namecheap it seems to be the case. Would it be possible to maybe remove it from the about section of the repo?
Thanks for your attention,
Worked in 0.3.3, broken in 0.3.4.
MWE:
from guietta import Gui
from PySide2.QtWidgets import QProgressBar
gui = [(QProgressBar(), "progress")]
gui.progress.SetFormat("%p% of files")
gui.progress.setValue(0.4)
Tracebacks:
Traceback (most recent call last):
File "gui.py", line 65, in <module>
MyApp("My Fancy App").run()
File "gui.py", line 30, in __init__
self.set_progress(0, 0)
File "gui.py", line 38, in set_progress
self.progress.setFormat(f"{i} / {n} (%p%)")
AttributeError: '_ContextInt' object has no attribute 'setFormat'
Traceback (most recent call last):
File "gui.py", line 65, in <module>
MyApp("My Fancy App").run()
File "gui.py", line 30, in __init__
self.set_progress(0, 0)
File "gui.py", line 39, in set_progress
self.progress.setValue(100 * i / n if n != 0 else 0)
AttributeError: '_ContextInt' object has no attribute 'setValue'
Hi.
I was learning with python 3.11, code :
from guietta import _, Gui, Quit
gui = Gui(
['Enter numbers:', '__a__', '+', '__b__', ['Calculate']],
['Result: -->', 'result', _, _, _],
[_, _, _, _, Quit])
with gui.Calculate:
gui.result = float(gui.a) + float(gui.b)
gui.run()
the result:
Traceback (most recent call last):
File "C:\Users\app.py", line 9, in <module>
gui.result = float(gui.a) + float(gui.b)
^^^^^^^^^^^^
ValueError: could not convert string to float: ''
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\app.py", line 8, in <module>
with gui.Calculate:
File "D:\Anaconda3\envs\app\Lib\site-packages\guietta\guietta.py", line 164, in __exit__
tree = ast.parse(withsource)
^^^^^^^^^^^^^^^^^^^^^
File "D:\Anaconda3\envs\app\Lib\ast.py", line 50, in parse
return compile(source, filename, mode, flags,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<unknown>", line 1
with gui.Calculate:
^
IndentationError: expected an indented block after 'with' statement on line 1
Is with statement not working in python 3.11 ? Or is there an alternative way of doing that? Thanks
>>> import matplotlib
>>> matplotlib.__version__
'2.0.2'
>>> from guietta import Gui, M
>>> a= Gui([M('a')])
ValueError: Element (<guietta.guietta_matplotlib.MatplotlibWidget object at 0x7f6a6f74bca8>, 'a') must be a widget or a (widget, name) tuple
Same code with matplotlib v3.x works.
Apparently the problem is that the FigureCanvas widget is a QWidget in matplotlib v3.x, but not in matplotlib v2.x
A rough TODO list:
password field
We can add an automatic "if gui.is_running" to all with blocks before eval()ing them, in order to avoid executing the code the first time.
Better image support: instead of just files, allow QImages to be passed as arguments, or maybe even image URLs. QPixmap has several possible constructors. Also allow a image label or button to start with an empty image - don't know if it is possible.
Add optional astropy units for values, maybe extending the tuple syntax: ('__a__', u.km)
.More difficult than it seems, because one needs to parse input strings. But very useful in a scientific environment. Another idea is to mimic the astropy quantity unit assignment, i.e. '__a__' * u.km
- don't know if it is possible.
Update docs with the new features like ValueSlider, background processing, GUI persistence, file open dialogs, Qt namespace available in Guietta, PyQt5 fallback for older systems.
Unit tests almost completely missing, no idea how to properly test GUI code.
Optional PEP8 mode for widget properties: make sure that the property names, derived from widget text, respect PEP8. Should be "just" translating everything to lowercase and converting spaces to underscores.
pyside2/pyqt5 dependency hell: probably the best way is to package an independent guietta_pyqt5 wheel.
Optional 'columns' argument for labels, to display the dict/lists over multiple columns instead of just two, useful for widgets that have a lot of horizontal space available.
Hi,
https://github.com/alfiopuglisi/guietta says:
Installation
pip install guietta
On a Rasbperry Pi running recent version of Raspberry Pi OS:
$ uname -a
(various values returned depending on Pi used)
Linux somepi1 4.19.118+ #1311 Mon Apr 27 14:16:15 BST 2020 armv6l GNU/Linux
Linux somepi3 4.19.66-v7+ #1253 SMP Thu Aug 15 11:49:46 BST 2019 armv7l GNU/Linux
Linux somepi4 4.19.118-v7l+ #1311 SMP Mon Apr 27 14:26:42 BST 2020 armv7l GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description: Raspbian GNU/Linux 10 (buster)
Release: 10
Codename: buster
$ pip3 install guietta
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting guietta
Using cached https://files.pythonhosted.org/packages/80/08/08b9e63c7aba8652284d4dafe5b60a6ad68741a4b7cac74fe9e894c74b7f/guietta-0.3.5-py2.py3-none-any.whl
Collecting PySide2 (from guietta)
Could not find a version that satisfies the requirement PySide2 (from guietta) (from versions: )
No matching distribution found for PySide2 (from guietta)
Installing PySide2 on the Pi was discussed in several places:
Tried the provided steps (below) on a Pi 1, Pi 3 a Pi 4, the original symptom remains.
sudo apt-get install python3-pyside2.qt3dcore python3-pyside2.qt3dinput python3-pyside2.qt3dlogic python3-pyside2.qt3drender python3-pyside2.qtcharts python3-pyside2.qtconcurrent python3-pyside2.qtcore python3-pyside2.qtgui python3-pyside2.qthelp python3-pyside2.qtlocation python3-pyside2.qtmultimedia python3-pyside2.qtmultimediawidgets python3-pyside2.qtnetwork python3-pyside2.qtopengl python3-pyside2.qtpositioning python3-pyside2.qtprintsupport python3-pyside2.qtqml python3-pyside2.qtquick python3-pyside2.qtquickwidgets python3-pyside2.qtscript python3-pyside2.qtscripttools python3-pyside2.qtsensors python3-pyside2.qtsql python3-pyside2.qtsvg python3-pyside2.qttest python3-pyside2.qttexttospeech python3-pyside2.qtuitools python3-pyside2.qtwebchannel python3-pyside2.qtwebsockets python3-pyside2.qtwidgets python3-pyside2.qtx11extras python3-pyside2.qtxml python3-pyside2.qtxmlpatterns python3-pyside2uic
Other attempts:
python3-qtpy
sudo apt-get install python3-qtpy
PySide2
are replaced by qtpy
(done it for all code, documentation should be updated, not done).git clone -b qt_via_qtpy https://github.com/fidergo-stephane-gourichon
cd guietta
pip3 install -e $PWD
cd ../my_app_using_guietta
python3 my_app_using_guietta.py
Not sure this is the best thing to do, anyway it works for me.
Will open PR if you want to follow this. It might help adoption of guietta, perhaps a lot, I don't know.
I use another thread to change the color of the widgets['result'] , but I found that the programmer will crash when I change the stylesteet of 'result' 20~120 times.
Maybe this is a multiprocessing problem, the another thread possibly casue some memory error.
Here is a example code:
from guietta import _, Gui
import threading
import time
gui = Gui(
['result']
)
def startWS():
while True:
gui.widgets['result'].setStyleSheet('color:rgb(255, 0, 0);')
time.sleep(0.1)
gui.widgets['result'].setStyleSheet('color:rgb(0, 176, 52);')
time.sleep(0.1)
threading.Thread(target=startWS).start()
gui.run()
I'm trying to write a gui with a function similar to the one below.
from guietta import Gui
import time
gui = Gui(
[["Start"]],
[["Stop"] ],
["Result" ]
)
def count(*args):
i = 0
while True:
gui.Result = i
i += 1
time.sleep(1)
def start_counting(*args):
gui.execute_in_background(func=count)
def stop_counting(*args):
pass
gui.Start = start_counting
gui.Stop = stop_counting
gui.run()
This function just counts the number of seconds since the "Start" button was pressed. This function will continue till it halted by an outside source. Is there some function which can halt the background execution of the count function without halting the entire program?
How can we package and distribute the app made with guietta ?
I was able to build a GUI in no more than 2 hours, this is incredible, thks !!!!
Now we need to build a binary (for OSX) and distribute to our (internal) users.
Thanks
Radio Buttons which have spaces in their name, like the first button below, are referred to by the name with no spaces, while keeping the case. This isn't in the documentation.
gui = Gui(
[R("This is the first Button"), R("second")],
)
with gui.ThisisthefirstButton as a:
print("Apple", a.isChecked())
with gui.second as b:
print("Sauce", b.isChecked())
Thank you so much for working on this! I like guietta a lot more than tkinter or other gui's.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.