# PyCell Example
```elixir
Mix.install([
{:py_cell, github: "NduatiK/py_cell"}
])
```
## Section
<!-- livebook:{"attrs":"eyJmdW5jdGlvbl9uYW1lIjoiYWRkIiwicHl0aG9uX2NvZGUiOiJkZWYgYWRkKGEsIGIpOlxuICByZXR1cm4gYSArIGIifQ","chunks":null,"kind":"Elixir.PyCell","livebook_object":"smart_cell"} -->
```elixir
require PyCell
code = """
def add(a, b):
return a + b
"""
PyCell.open_port("add", code)
```
```elixir
PyCell.run("add", [1, 2])
```
## A more complex example
<!-- livebook:{"attrs":"eyJmdW5jdGlvbl9uYW1lIjoic3ViIiwicHl0aG9uX2NvZGUiOiIjIFlvdSBjYW4gZGVmaW5lIGNsYXNzZXNcbmNsYXNzIFN1YnRyYWN0ZXI6XG4gIGRlZiBfX2luaXRfXyhzZWxmKTpcbiAgICBzZWxmLnplcm8gPSAwXG5cbiAgZGVmIHN1YihzZWxmLCBhLCBiKTpcbiAgICByZXR1cm4gYSAtIGIgKyBzZWxmLnplcm9cblxuIyBZb3UgY2FuIGRlZmluZSBnbG9iYWxzXG5zdWJ0cmFjdGVyID0gU3VidHJhY3RlcigpXG5cbiMgT25seSBgc3ViYCB3aWxsIGJlIGV4cG9zZWRcbmRlZiBzdWIoYSwgYik6XG4gIHJldHVybiBzdWJ0cmFjdGVyLnN1YihhLCBiKVxuIn0","chunks":null,"kind":"Elixir.PyCell","livebook_object":"smart_cell"} -->
```elixir
require PyCell
code = """
# You can define classes
class Subtracter:
def __init__(self):
self.zero = 0
def sub(self, a, b):
return a - b + self.zero
# You can define globals
subtracter = Subtracter()
# Only `sub` will be exposed
def sub(a, b):
return subtracter.sub(a, b)
"""
PyCell.open_port("sub", code)
```
```elixir
PyCell.run("sub", [1, 3])
```
## Error Handling
<!-- livebook:{"attrs":"eyJmdW5jdGlvbl9uYW1lIjoiZXJyb3IiLCJweXRob25fY29kZSI6ImRlZiBlcnJvcihhLCBiKTpcbiAgcmV0dXJuIGEgKyBiICsgY1xuIn0","chunks":null,"kind":"Elixir.PyCell","livebook_object":"smart_cell"} -->
```elixir
require PyCell
code = """
def error(a, b):
return a + b + c
"""
PyCell.open_port("error", code)
```
Running the following code will produce a Python error.
```elixir
PyCell.run("error", [1, 2])
```
## Is it fast?
No, not at all. In the simple benchmark below, subtracting 100K numbers through Python takes 300x longer than in Elixir. So this only makes sense when the operations would be much faster in Python.
A great place for this is when doing matrix multiplication. Numpy is sometimes faster than Nx and can handle numpy archives that contain strings.
```elixir
:timer.tc(fn ->
for _ <- 1..100_000 do
PyCell.run("sub", [1, 2])
end
end)
|> elem(0)
|> then(&(&1 / 1_000_000))
```
```elixir
:timer.tc(fn ->
for _ <- 1..100_000 do
1 - 2
end
end)
|> elem(0)
|> then(&(&1 / 1_000_000))
```