Skip to content

Instantly share code, notes, and snippets.

@mrprajesh
Created September 22, 2022 17:22
Show Gist options
  • Save mrprajesh/9bf82f512ae57adb611a97203bdd508b to your computer and use it in GitHub Desktop.
Save mrprajesh/9bf82f512ae57adb611a97203bdd508b to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[![xeus-cling](images/xeus-cling.png)](https://github.com/jupyter-xeus/xeus-cling/)\n",
"\n",
"A Jupyter kernel for C++ based on the `cling` C++ interpreter and the `xeus` native implementation of the Jupyter protocol, xeus.\n",
"\n",
"- GitHub repository: https://github.com/jupyter-xeus/xeus-cling/\n",
"- Online documentation: https://xeus-cling.readthedocs.io/"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Usage\n",
"\n",
"<div style=\"background: #efffed;\n",
" border: 1px solid grey;\n",
" margin: 8px 0 8px 0;\n",
" text-align: center;\n",
" padding: 8px; \">\n",
" <i class=\"fa-play fa\" \n",
" style=\"font-size: 40px;\n",
" line-height: 40px;\n",
" margin: 8px;\n",
" color: #444;\">\n",
" </i>\n",
" <div>\n",
" To run the selected code cell, hit <pre style=\"background: #efffed\">Shift + Enter</pre>\n",
" </div>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Output and error streams\n",
"\n",
"`std::cout` and `std::cerr` are redirected to the notebook frontend."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#include <iostream>\n",
"\n",
"std::cout << \"some output\" << std::endl;"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"std::cerr << \"some error\" << std::endl;"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#include <stdexcept>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"throw std::runtime_error(\"Unknown exception\");"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Omitting the `;` in the last statement of a cell results in an output being printed"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"int j = 5;"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"j"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Interpreting the C++ programming language\n",
"\n",
"`cling` has a broad support of the features of C++. You can define functions, classes, templates, etc ..."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Functions"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"double sqr(double a)\n",
"{\n",
" return a * a;\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"double a = 2.5;\n",
"double asqr = sqr(a);\n",
"asqr"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Classes"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class Foo\n",
"{\n",
"public:\n",
"\n",
" virtual ~Foo() {}\n",
" \n",
" virtual void print(double value) const\n",
" {\n",
" std::cout << \"Foo value = \" << value << std::endl;\n",
" }\n",
"};"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Foo bar;\n",
"bar.print(1.2);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Polymorphism"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class Bar : public Foo\n",
"{\n",
"public:\n",
"\n",
" virtual ~Bar() {}\n",
" \n",
" virtual void print(double value) const\n",
" {\n",
" std::cout << \"Bar value = \" << 2 * value << std::endl;\n",
" }\n",
"};"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Foo* bar2 = new Bar;\n",
"bar2->print(1.2);\n",
"delete bar2;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Templates"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#include <typeinfo>\n",
"\n",
"template <class T>\n",
"class FooT\n",
"{\n",
"public:\n",
" \n",
" explicit FooT(const T& t) : m_t(t) {}\n",
" \n",
" void print() const\n",
" {\n",
" std::cout << typeid(T).name() << \" m_t = \" << m_t << std::endl;\n",
" }\n",
" \n",
"private:\n",
" \n",
" T m_t;\n",
"};"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"FooT<double> foot(1.2);\n",
"foot.print();"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## C++11 / C++14 support"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class Foo11\n",
"{\n",
"public:\n",
" \n",
" Foo11() { std::cout << \"Foo11 default constructor\" << std::endl; }\n",
" Foo11(const Foo11&) { std::cout << \"Foo11 copy constructor\" << std::endl; }\n",
" Foo11(Foo11&&) { std::cout << \"Foo11 move constructor\" << std::endl; }\n",
"};"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Foo11 f1;\n",
"Foo11 f2(f1);\n",
"Foo11 f3(std::move(f1));"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#include <vector>\n",
"\n",
"std::vector<int> v = { 1, 2, 3};\n",
"auto iter = ++v.begin();\n",
"v"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"*iter"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"... and also lambda, universal references, `decltype`, etc ..."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Documentation and completion\n",
"\n",
" - Documentation for types of the standard library is retrieved on cppreference.com.\n",
" - The quick-help feature can also be enabled for user-defined types and third-party libraries. More documentation on this feature is available at https://xeus-cling.readthedocs.io/en/latest/inline_help.html.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"?std::vector"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Using the `display_data` mechanism"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For a user-defined type `T`, the rich rendering in the notebook and JupyterLab can be enabled by by implementing the function `nl::json mime_bundle_repr(const T& im)`, which returns the JSON mime bundle for that type.\n",
"\n",
"More documentation on the rich display system of Jupyter and Xeus-cling is available at https://xeus-cling.readthedocs.io/en/latest/rich_display.html"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Image example"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#include <string>\n",
"#include <fstream>\n",
"\n",
"#include \"nlohmann/json.hpp\"\n",
"\n",
"#include \"xtl/xbase64.hpp\"\n",
"\n",
"namespace nl = nlohmann;\n",
"\n",
"namespace im\n",
"{\n",
" struct image\n",
" { \n",
" inline image(const std::string& filename)\n",
" {\n",
" std::ifstream fin(filename, std::ios::binary); \n",
" m_buffer << fin.rdbuf();\n",
" }\n",
" \n",
" std::stringstream m_buffer;\n",
" };\n",
" \n",
" nl::json mime_bundle_repr(const image& i)\n",
" {\n",
" auto bundle = nl::json::object();\n",
" bundle[\"image/png\"] = xtl::base64encode(i.m_buffer.str());\n",
" return bundle;\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"im::image marie(\"images/marie.png\");\n",
"marie"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Audio example"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#include <string>\n",
"#include <fstream>\n",
"\n",
"#include \"nlohmann/json.hpp\"\n",
"\n",
"#include \"xtl/xbase64.hpp\"\n",
"\n",
"namespace nl = nlohmann;\n",
"\n",
"namespace au\n",
"{\n",
" struct audio\n",
" { \n",
" inline audio(const std::string& filename)\n",
" {\n",
" std::ifstream fin(filename, std::ios::binary); \n",
" m_buffer << fin.rdbuf();\n",
" }\n",
" \n",
" std::stringstream m_buffer;\n",
" };\n",
" \n",
" nl::json mime_bundle_repr(const audio& a)\n",
" {\n",
" auto bundle = nl::json::object();\n",
" bundle[\"text/html\"] =\n",
" std::string(\"<audio controls=\\\"controls\\\"><source src=\\\"data:audio/wav;base64,\")\n",
" + xtl::base64encode(a.m_buffer.str()) +\n",
" \"\\\" type=\\\"audio/wav\\\" /></audio>\";\n",
" return bundle;\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"au::audio drums(\"audio/audio.wav\");\n",
"drums"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Display"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#include \"xcpp/xdisplay.hpp\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"xcpp::display(drums);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Update-display"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#include <string>\n",
"#include \"xcpp/xdisplay.hpp\"\n",
"\n",
"#include \"nlohmann/json.hpp\"\n",
"\n",
"namespace nl = nlohmann;\n",
"\n",
"namespace ht\n",
"{\n",
" struct html\n",
" { \n",
" inline html(const std::string& content)\n",
" {\n",
" m_content = content;\n",
" }\n",
" std::string m_content;\n",
" };\n",
"\n",
" nl::json mime_bundle_repr(const html& a)\n",
" {\n",
" auto bundle = nl::json::object();\n",
" bundle[\"text/html\"] = a.m_content;\n",
" return bundle;\n",
" }\n",
"}\n",
"\n",
"// A blue rectangle\n",
"ht::html rect(R\"(\n",
"<div style='\n",
" width: 90px;\n",
" height: 50px;\n",
" line-height: 50px;\n",
" background-color: blue;\n",
" color: white;\n",
" text-align: center;'>\n",
"Original\n",
"</div>)\");"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"xcpp::display(rect, \"some_display_id\");"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"// Update the rectangle to be red\n",
"rect.m_content = R\"(\n",
"<div style='\n",
" width: 90px;\n",
" height: 50px;\n",
" line-height: 50px;\n",
" background-color: red;\n",
" color: white;\n",
" text-align: center;'>\n",
"Updated\n",
"</div>)\";\n",
"\n",
"xcpp::display(rect, \"some_display_id\", true);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Clear output"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#include <chrono>\n",
"#include <iostream>\n",
"#include <thread>\n",
"\n",
"#include \"xcpp/xdisplay.hpp\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"std::cout << \"hello\" << std::endl;\n",
"std::this_thread::sleep_for(std::chrono::seconds(1));\n",
"xcpp::clear_output(); // will flicker when replacing \"hello\" with \"goodbye\"\n",
"std::this_thread::sleep_for(std::chrono::seconds(1));\n",
"std::cout << \"goodbye\" << std::endl;"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"std::cout << \"hello\" << std::endl;\n",
"std::this_thread::sleep_for(std::chrono::seconds(1));\n",
"xcpp::clear_output(true); // prevents flickering\n",
"std::this_thread::sleep_for(std::chrono::seconds(1));\n",
"std::cout << \"goodbye\" << std::endl;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Magics\n",
"\n",
"Magics are special commands for the kernel that are not part of the C++ language.\n",
"\n",
"They are defined with the symbol `%` for a line magic and `%%` for a cell magic.\n",
"\n",
"More documentation for magics is available at https://xeus-cling.readthedocs.io/en/latest/magics.html."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#include <algorithm>\n",
"#include <vector>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"std::vector<double> to_shuffle = {1, 2, 3, 4};"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%timeit std::random_shuffle(to_shuffle.begin(), to_shuffle.end());"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[![xtensor](images/xtensor.png)](https://github.com/xtensor-stack/xtensor/)\n",
"\n",
"- GitHub repository: https://github.com/xtensor-stack/xtensor/\n",
"- Online documentation: https://xtensor.readthedocs.io/\n",
"- NumPy to xtensor cheat sheet: http://xtensor.readthedocs.io/en/latest/numpy.html\n",
"\n",
"`xtensor` is a C++ library for manipulating N-D arrays with an API very similar to that of numpy."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#include <iostream>\n",
"\n",
"#include \"xtensor/xarray.hpp\"\n",
"#include \"xtensor/xio.hpp\"\n",
"#include \"xtensor/xview.hpp\"\n",
"\n",
"xt::xarray<double> arr1\n",
" {{1.0, 2.0, 3.0},\n",
" {2.0, 5.0, 7.0},\n",
" {2.0, 5.0, 7.0}};\n",
"\n",
"xt::xarray<double> arr2\n",
" {5.0, 6.0, 7.0};\n",
"\n",
"xt::view(arr1, 1) + arr2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Together with the C++ Jupyter kernel, `xtensor` offers a similar experience as `NumPy` in the Python Jupyter kernel, including broadcasting and universal functions."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#include <iostream>\n",
"#include \"xtensor/xarray.hpp\"\n",
"#include \"xtensor/xio.hpp\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"xt::xarray<int> arr\n",
" {1, 2, 3, 4, 5, 6, 7, 8, 9};\n",
"\n",
"arr.reshape({3, 3});\n",
"\n",
"std::cout << arr;"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#include \"xtensor-blas/xlinalg.hpp\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"xt::xtensor<double, 2> m = {{1.5, 0.5}, {0.7, 1.0}};\n",
"std::cout << \"Matrix rank: \" << std::endl << xt::linalg::matrix_rank(m) << std::endl;\n",
"std::cout << \"Matrix inverse: \" << std::endl << xt::linalg::inv(m) << std::endl;\n",
"std::cout << \"Eigen values: \" << std::endl << xt::linalg::eigvals(m) << std::endl;"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"xt::xarray<double> arg1 = xt::arange<double>(9);\n",
"xt::xarray<double> arg2 = xt::arange<double>(18);\n",
"\n",
"arg1.reshape({3, 3});\n",
"arg2.reshape({2, 3, 3});\n",
"\n",
"std::cout << xt::linalg::dot(arg1, arg2) << std::endl;"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "C++14",
"language": "C++14",
"name": "xcpp14"
},
"language_info": {
"codemirror_mode": "text/x-c++src",
"file_extension": ".cpp",
"mimetype": "text/x-c++src",
"name": "c++",
"version": "14"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment