Examples for beginners (#169)

* Add examples folder

* Draft change

* Add draft changes

* Add examples

* Refactor examples

---------

Co-authored-by: Mahbub Alam <alam.mahbub214@gmail.com>
This commit is contained in:
Mahbub Alam 2023-10-24 05:59:58 -04:00 committed by GitHub
parent a98e710fe7
commit 6f8bf82e9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 342 additions and 0 deletions

35
examples/1_type_cast.cpp Normal file
View File

@ -0,0 +1,35 @@
/**
* This example demonstrates the type casting feature of PocketPy.
* It creates a virtual machine and cast PyObject* to different types.
*/
#include "pocketpy.h"
using namespace pkpy;
int main(){
// Create a virtual machine
VM* vm = new VM();
PyObject* str_obj = py_var(vm, "hello world");
// Cast PyObject* to Str type
Str& str = py_cast<Str&>(vm, str_obj);
std::cout << "string: " << str.c_str() << std::endl; // hello world
PyObject* int_obj = py_var(vm, 10);
// Cast PyObject* to Int type
int int_var = py_cast<int>(vm, int_obj);
std::cout << "int: " << int_var << std::endl; // 10
PyObject* float_obj = py_var(vm, 10.5);
// Cast PyObject* to double type
double float_var = py_cast<double>(vm, float_obj);
std::cout << "float: " << float_var << std::endl; // 10.5
// Dispose the virtual machine
delete vm;
return 0;
}

View File

@ -0,0 +1,36 @@
/**
* This example demonstrate the process of creating a python module and
* bind a function to it, as well as the procedure for calling the function.
*/
#include "pocketpy.h"
using namespace pkpy;
int main(){
// Create a virtual machine
VM* vm = new VM();
// Create a module
PyObject* math_module = vm->new_module("math");
// Bind a function named "add" to the module
vm->bind(math_module, "add(a: int, b: int) -> int",
[](VM* vm, ArgsView args){
int a = py_cast<int>(vm, args[0]);
int b = py_cast<int>(vm, args[1]);
return py_var(vm, a + b);
});
// Call the "add" function
PyObject* f_sum = math_module->attr("add");
PyObject* result = vm->call(f_sum, py_var(vm, 4), py_var(vm, 5));
std::cout << "Sum: " << py_cast<int>(vm, result) << std::endl; // 9
// Dispose the virtual machine
delete vm;
return 0;
}

View File

@ -0,0 +1,50 @@
/**
* This example demonstrates how to build a List object and how to access its elements.
* It creates a python module named "math_utils" and bind a function named "average" to it.
* It exercises creating a List and accessing its elements.
* It also demonstrates how to cast a python object to a C++ type.
*/
#include "pocketpy.h"
using namespace pkpy;
int main(){
// Create a virtual machine
VM* vm = new VM();
// Create a module
PyObject* math_utils = vm->new_module("math_utils");
// Bind a function named "average" to the module
vm->bind(math_utils, "average(l: List[float]) -> float",
[](VM* vm, ArgsView args){
// Cast the argument to a list
List& l = py_cast<List&>(vm, args[0]);
double sum = 0;
// Calculate the sum of the list by iterating through the list
for(auto& e : l){
sum += py_cast<double>(vm, e);
}
return py_var(vm, sum / l.size());
});
// Create a list of numbers and covert it to a python object
List numbers;
numbers.push_back(py_var(vm, 1.0));
numbers.push_back(py_var(vm, 2.0));
numbers.push_back(py_var(vm, 3.0));
PyObject* list = py_var(vm, std::move(numbers));
// Call the "average" function
PyObject* f_average = math_utils->attr("average");
PyObject* result = vm->call(f_average, list);
std::cout << "Average: " << py_cast<double>(vm, result) << std::endl; // 2
// Dispose the virtual machine
delete vm;
return 0;
}

View File

@ -0,0 +1,108 @@
/**
* This example illustrate use of Dict in PocketPy.
* It creates a python module named "employee" and bind four functions to it.
* It exercises setting and getting elements in a Dict.
*/
#include "pocketpy.h"
using namespace pkpy;
int main(){
// Create a virtual machine
VM* vm = new VM();
// Create "employee" module
PyObject* employee_module = vm->new_module("employee");
// Bind a function named "get_first_name" to the module
vm->bind(employee_module, "get_first_name(employee: Dict) -> str",
"Returns first_name of the employee", // docstring
[](VM* vm, ArgsView args){
// Cast the argument to a dictionary
Dict& employee = CAST(Dict&, args[0]);
// Access the first_name field and return it
return employee.try_get(VAR("first_name"));
});
// Bind a function named "get_last_name" to the module
vm->bind(employee_module, "get_last_name(employee: Dict) -> str",
"Returns last_name of the employee", // docstring
[](VM* vm, ArgsView args){
// Cast the argument to a dictionary
Dict& employee = CAST(Dict&, args[0]);
// Access the last_name field and return it
return employee.try_get(VAR("last_name"));
});
// Bind a function named "get_salary" to the module
// It accepts a dictionary as argument and returns a float
vm->bind(employee_module, "get_salary(employee: Dict) -> float",
"Returns salary of the employee", // docstring
[](VM* vm, ArgsView args){
// Cast the argument to a dictionary
Dict& employee = CAST(Dict&, args[0]);
// Access the salary field and return it
return employee.try_get(VAR("salary"));
});
// Bind a function named "love_coding" to the module
// It accepts a dictionary as argument and returns a bool
vm->bind(employee_module, "love_coding(employee: Dict) -> bool",
"Returns Yes if the employee loves coding, No otherwise", // docstring
[](VM* vm, ArgsView args){
// Cast the argument to a dictionary
Dict& employee = CAST(Dict&, args[0]);
// Access the hobbies field and cast it to a list
List& hobbies = CAST(List&, employee.try_get(VAR("hobbies")));
// Iterate through the list and check if the employee loves coding
for(auto& e : hobbies){
if(CAST(Str&, e) == Str("Coding")){
return VAR("Yes");
}
}
return VAR("No");
});
// Create employee dictionary covert it to a python object
Dict employee(vm);
employee.set(VAR("first_name"), VAR("John"));
employee.set(VAR("last_name"), VAR("Doe"));
employee.set(VAR("age"), VAR(30));
employee.set(VAR("salary"), VAR(10000.0));
List hobbies;
hobbies.push_back(VAR("Reading"));
hobbies.push_back(VAR("Walking"));
hobbies.push_back(VAR("Coding"));
employee.set(VAR("hobbies"), VAR(std::move(hobbies)));
PyObject* employee_obj = VAR(std::move(employee));
// Call the "get_first_name" function
PyObject* f_get_first_name = employee_module->attr("get_first_name");
PyObject* first_name = vm->call(f_get_first_name, employee_obj);
std::cout << "First name: " << CAST(Str&, first_name) << std::endl; // First name: John
// Call the "get_last_name" function
PyObject* f_get_last_name = employee_module->attr("get_last_name");
PyObject* last_name = vm->call(f_get_last_name, employee_obj);
std::cout << "Last name: " << CAST(Str&, last_name) << std::endl; // Last name: Doe
// Call the "get_salary" function
PyObject* f_get_salary = employee_module->attr("get_salary");
PyObject* salary = vm->call(f_get_salary, employee_obj);
std::cout << "Salary: "<< CAST(double, salary) << std::endl; // Salary: 10000
// Call the "love_coding" function
PyObject* f_love_coding = employee_module->attr("love_coding");
PyObject* love_coding = vm->call(f_love_coding, employee_obj);
std::cout << "Loves coding: " << CAST(Str&, love_coding) << std::endl; // Loves coding: Yes
// Dispose the virtual machine
delete vm;
return 0;
}

View File

@ -0,0 +1,26 @@
/**
* This example demonstrate the use of PocketPy as a scripting language.
* It creates a virtual machine and execute a python script.
*/
#include "pocketpy.h"
using namespace pkpy;
int main(){
// Create a virtual machine
VM* vm = new VM();
// Print "hello world" to the console
vm->exec("print('hello world')"); // hello world
// List comprehension
vm->exec("l = [i*i for i in range(1, 6)]");
vm->exec("print(l)"); // [1, 4, 9, 16, 25]
// Dispose the virtual machine
delete vm;
return 0;
}

View File

@ -0,0 +1,87 @@
/**
* This example demonstrates how to create different types of objects and
* how to check their types.
*/
#include "pocketpy.h"
using namespace pkpy;
int main(){
// Create a virtual machine
VM* vm = new VM();
// Create a module
PyObject* type_checker = vm->new_module("type_checker");
// Bind a function named "get_type" to the module
vm->bind(type_checker, "get_type(obj: object) -> str",
"Returns type of a python object", // docstring
[](VM* vm, ArgsView args){
PyObject* obj = args[0];
if(is_type(obj, vm->tp_int)){
return py_var(vm, "int");
}
else if(is_type(obj, vm->tp_str)){
return py_var(vm, "str");
}
else if(is_type(obj, vm->tp_float)){
return py_var(vm, "float");
}
else if(is_type(obj, vm->tp_bool)){
return py_var(vm, "bool");
}
else if(is_type(obj, vm->tp_dict)){
return py_var(vm, "dict");
}
else if(is_type(obj, vm->tp_list)){
return py_var(vm, "list");
}
else if(is_type(obj, vm->tp_tuple)){
return py_var(vm, "tuple");
}
else{
return py_var(vm, "unknown");
}
});
// Get the "get_type" function
PyObject* f_get_type = type_checker->attr("get_type");
// Create a dictionary
Dict d(vm);
d.set(py_var(vm, "key"), py_var(vm, "value"));
// Create a list
List l;
l.push_back(py_var(vm, "list_element"));
// Declare a two-element tuple
Tuple t(2);
t[0] = py_var(vm, "tuple_element_0");
t[1] = py_var(vm, "tuple_element_1");
// Create different types of objects
PyObject* int_obj = py_var(vm, 1);
PyObject* str_obj = py_var(vm, "hello");
PyObject* float_obj = py_var(vm, 1.0);
PyObject* bool_obj = py_var(vm, true);
PyObject* dict_obj = py_var(vm, std::move(d));
PyObject* list_obj = py_var(vm, std::move(l));
PyObject* tuple_obj = py_var(vm, std::move(t));
// Call the "get_type" function and print type of different objects
std::cout << "Type of 1: " << CAST(Str&, vm->call(f_get_type, int_obj)) << std::endl;
std::cout << "Type of \"hello\": " << CAST(Str&, vm->call(f_get_type, str_obj)) << std::endl;
std::cout << "Type of 1.0: " << CAST(Str&, vm->call(f_get_type, float_obj)) << std::endl;
std::cout << "Type of true: " << CAST(Str&, vm->call(f_get_type, bool_obj)) << std::endl;
std::cout << "Type of {\"key\": \"value\" }: " << CAST(Str&, vm->call(f_get_type, dict_obj)) << std::endl;
std::cout << "Type of [\"list_element\"]: " << CAST(Str&, vm->call(f_get_type, list_obj)) << std::endl;
std::cout << "Type of (\"tuple_element_0\", \"tuple_element_1\"): " << CAST(Str&, vm->call(f_get_type, tuple_obj)) << std::endl;
// Dispose the virtual machine
delete vm;
return 0;
}