text:
# Deploying the whole cluster

This document is intended to give you a step by step guide to deploy the initial cluster with all infrastructures within the single data center. It contains Kubernetes Master hosts, Kubernetes Node hosts, Glusterfs servers, and HAProxy servers.

## Prerequirements

1. 3 Ubuntu 14.04 server version instances with at least 2 CPU and 8 GB memory for Kubernetes Master/Node hosts.
2. 2 Ubuntu 14.04 server version instances with at least 1 CPU and 2 GB memory for Glusterfs servers and HAproxy servers.
3. The Ubuntu instances could be run on AWS, GCE, Virtual Machine environment, bare metal environment and ...etc.

## Topology

### Functional view

![Stateful data](/images/install_guide/deploying_cluster_functional_view.png)

### Host View

![Stateful data](/images/install_guide/deploying_cluster_host_view.png)

## Install

### Step 1. Download

1. Login one of the Ubuntu 14.04 instances.
2. Install git with "sudo apt-get install git".
3. Clone from github with "git clone https://github.com/cloudawan/cloudawan_install.git".
4. Move to the directory "./cloudawan_install/kubernetes1.2/".

### Step 2. Configure

1. Open the file **hosts_cluster** to modify.
2. Configure the ip for 3 Kubernetes Master/Node hosts in the section [master_node_host]. Change the ip to the physical ip of the Ubuntu 14.04 instance with at least 2 CPU and 8 GB memory and username(ansible_user) and password(both ansible_ssh_pass and ansible_become_pass) to the root user and root password.
3. Configure the ip for 2 Glusterfs servers in the section [glusterfs_host]. Change the ip to the physical ip of the Ubuntu 14.04 instance with at least 1 CPU and 2 GB memory and username(ansible_user) and password(both ansible_ssh_pass and ansible_become_pass) to the root user and root password.
4. Configure the master host slb vip in the section [glusterfs:vars] to the floating ip of HAProxy(haproxy_floating_ip in section [haproxy:vars]). Hosts will use this floating ip supported by HA to communicate with master host cluster.
5. Configure the ip for 2 HAproxy servers in the section [haproxy_host]. Change the ip to the physical ip of the Ubuntu 14.04 instance with at least 1 CPU and 2 GB memory and username(ansible_user) and password(both ansible_ssh_pass and ansible_become_pass) to the root user and root password.
6. Configure the floating IP (haproxy_floating_ip in section [haproxy:vars]) to an IP reserved in the same physical subnet. The floating ip is in the hot-standby mode. If the active HAproxy server is down, the other will take over this floating ip immediately. This ip should not be used by any other machine in the subnet.
7. Configure the domain name suffix (domain_name_suffix in section [haproxy:vars]) to the suffix of all services exported to Internet. This is used to provide domain name service access to the Kubernetes services of the deployed applications. The access entry will be application_name.service_name.domain_name_suffix:container_port. Also, users should configure the *.domain_name_suffix to send to the floating IP (haproxy_floating_ip in section [haproxy:vars]) in the public domain service providers.
8. (Optional) Change the flannel virtual network (flannel_subnet and flannel_subnet_mask_bit) used only internal on the Kubernetes hosts in the section [master_node:vars]. The docker containers will use this network to communicate.
9. (Optional) Change the Kubernetes service network (service_cluster_ip_range) used only insides the docker containers to access Kubernetes service and kubernetes internal dns (service_cluster_dns_ip) used only insides the docker containers for domain name in the section [master_node:vars]. The service_cluster_dns_ip must reside in the service_cluster_ip_range.
10. (Optional) Change the data center label (node_label) in the section [master_node:vars]. The label could be used to do geographical topology awareness when deploying new instances. One region contains many zones and one zones contains many hosts. The network delay between two zones in the same region should be small enough (1~2 ms) to ignore.

### Step 3. Run script

1. Run ./cluster_install.sh and input the password for root privilege. It will first install ansible and then run the ansible template to install.
2. The whole process may takes half an hour depending on the network speed since most of big  files are retrieved from the docker hub.

## The Ansible configuration file

The following is the configuration file /cloudawan_install/kubernetes1.2/hosts_cluster in the ansible configuration file format.

```
# Kubernetes Master role or Node role hosts
[master_node:children]
master_node_host

[master_node:vars]
# The virtual network used for containers to communicate
flannel_subnet=<IP_ADDRESS>
flannel_subnet_mask_bit=16
# The virtual network used for the Kubernetes services. This should be the subset of flannel_subnet.
service_cluster_ip_range=<IP_ADDRESS>/24
service_cluster_dns_ip=<IP_ADDRESS>
# This is used to provide location awareness. The difference between region and zone is that the network delay between zones is small enough to ignore while it is not between regions.
node_label="region=region1,zone=zone1"
# Restrict the location to deploy
private_registry_region="region1"
private_registry_zone="zone1"
cloudone_all_region="region1"
cloudone_all_zone="zone1"
# Generate certificates for Kubernetes components to use bi-directional SSL to secure the communication.
# User could use their own CA certificates to sign the generated certificates.
# The file path could be relative or absolute. If not indicated, one CA pair will be generated.
# The generated CA pair should keep safely and will be used when adding new Kubernetes Node hosts.
certificate_ca_certificate_file_path=""
certificate_ca_key_file_path=""
certificate_ca_key_passphrase="password"
certificate_ca_valid_days=36500
certificate_server_valid_days=36500

# Install infrastructure
[master_node_host]
<IP_ADDRESS> ansible_user=username ansible_ssh_pass=password ansible_become_pass=password
<IP_ADDRESS> ansible_user=username ansible_ssh_pass=password ansible_become_pass=password
<IP_ADDRESS> ansible_user=username ansible_ssh_pass=password ansible_become_pass=password

# Glusterfs
[glusterfs:children]
glusterfs_host

[glusterfs:vars]
# This is the ip used to connect to Kubernetes master hosts.
master_host_slb_vip=<IP_ADDRESS>

[glusterfs_host]
# At least two hosts are required due to the HA configuration.
# The first host {{ groups['glusterfs_host'][0] }} will be used as the seed host.
# The first host {{ groups['glusterfs_host'][0] }} and the second host {{ groups['glusterfs_host'][1] }} will hold the volumes for system programs
<IP_ADDRESS> ansible_user=username ansible_ssh_pass=password ansible_become_pass=password
<IP_ADDRESS> ansible_user=username ansible_ssh_pass=password ansible_become_pass=password

# HAproxy
[haproxy:children]
haproxy_host

[haproxy:vars]
# This floating ip is in the hot-standby mode. If the active HAProxy server is down, the other will take over.
# This is also the ip used to connect to Kubernetes master hosts. That is the role of master_host_slb_vip.
haproxy_floating_ip=<IP_ADDRESS>
# Domain name suffix. This is used to provide domain name service access to the Kubernetes services of the deployed applications. The access entry will be application_name.service_name.domain_name_suffix:container_port
domain_name_suffix=cloudawan.com

[haproxy_host]
<IP_ADDRESS> ansible_user=username ansible_ssh_pass=password ansible_become_pass=password
<IP_ADDRESS> ansible_user=username ansible_ssh_pass=password ansible_become_pass=password
```

### Kubernetes

#### Shared Variable [master_node:vars]

These parameters are shared by all Kubernetes Master hosts and Kubernetes Node hosts.

        Variable Name
        Example
        Description

        flannel_subnet
        <IP_ADDRESS>
        The virtual network used within Kubernetes hosts for Docker containers to communicate. It is a flat network provided by Flannel.

        flannel_subnet_mask_bit
        16
        The range of the Flannel virtual network

        service_cluster_ip_range
        <IP_ADDRESS>/24
        The virtual network used by Kubernetes kube-proxy to provide access for  Kubernetes services. It should not overlap with the Flannel virtual network.

        service_cluster_dns_ip
        <IP_ADDRESS>
        The virtual ip of the Kubernetes dns service. All containers could ask the service ip with the Kubernetes service domain name in the Kubernetes format (service_name).(namespace_name).svc.(cluster).(local)

        node_label
        "region=region1,zone=zone1"
        The Kubernetes node host label for all Node hosts in the initial cluster. It is usd to identify different data center in different regions and different zones.

        private_registry_zone
        "zone1"
        The zone the private-registry is limited to hold.

        private_registry_region
        "region1"
        The region the private-registry is limited to hold.

        cloudone_all_region
        "region1"
        The region the cloudone, that is the management platform, is limited to hold.

        cloudone_all_zone
        "zone1"
        The zone the cloudone, that is the management platform, is limited to hold.

        certificate_ca_certificate_file_path

        The file path of the ca certificate used to verify the generated certificates for hosts. The file path could be relative or absolute. If not indicated, one CA pair will be generated.

        certificate_ca_key_file_path

        The file path of the ca key used to sign the generated certificates for hosts. The file path could be relative or absolute. If not indicated, one CA pair will be generated.

        certificate_ca_key_passphrase
        "password"
        If the file path for ca is empty. This will be used as the password for the generated self-signed CA.

        certificate_ca_valid_days
        36500
        The valid duration for the generated CA.

        certificate_server_valid_days
        36500
        The valid duration for the generated certificates.

#### Host Variable [master_node_host]

Each host has its own independent variables following the host ip. The hosts here have both Kubernetes Master programs and Node programs so they play two roles.

        Variable Name
        Example
        Description

        ansible_user
        username
        The username to login this host. The user must have the root privilege

        ansible_ssh_pass
        password
        The password for the ansible_user.

        ansible_become_pass
        password
        The password for the ansible_user to use sudo. Generally, it is the same as ansible_ssh_pass.

### Glusterfs

#### Shared Variable [glusterfs:vars]

These parameters are shared by all Glusterfs hosts.

        Variable Name
        Example
        Description

        master_host_slb_vip
        <IP_ADDRESS>
        The virtual IP provided by the SLB to route to the master host. The health check dameon will send the data to the port 4001 of the master_host_slb_vip. If there is no SLB, the master host could be used here but there won't be HA.

#### Host Variable [glusterfs_host]

Each host has its own independent variables following the host ip. The hosts here have Glusterfs server side programs.

        Variable Name
        Example
        Description

        ansible_user
        username
        The username to login this host. The user must have the root privilege

        ansible_ssh_pass
        password
        The password for the ansible_user.

        ansible_become_pass
        password
        The password for the ansible_user to use sudo. Generally, it is the same as ansible_ssh_pass.

### HAProxy

#### Shared Variable [haproxy:vars]

These parameters are shared by all Glusterfs hosts.

        Variable Name
        Example
        Description

        haproxy_floating_ip
        <IP_ADDRESS>
        This floating IP is in the hot-standby mode. If the active HAProxy server is down, the other will take over. This is also the ip used to connect to Kubernetes master hosts. The health check dameon will send the data to the port 4001 of the haproxy_floating_ip

        domain_name_suffix
        cloudawan.com
        The domain name suffix. This is used to provide domain name service access to the Kubernetes services of the deployed applications. The access entry will be application_name.service_name.domain_name_suffix:container_port

#### Host Variable [haproxy_host]

Each host has its own independent variables following the host ip. The hosts here have HAProxy programs.

        Variable Name
        Example
        Description

        ansible_user
        username
        The username to login this host. The user must have the root privilege

        ansible_ssh_pass
        password
        The password for the ansible_user.

        ansible_become_pass
        password
        The password for the ansible_user to use sudo. Generally, it is the same as ansible_ssh_pass.

## Uninstall cluster

Run ./cluster_uninstall.sh with the same configuration file hosts_cluster and input the password for root privilege. It will first install ansible and then run the ansible template to uninstall.


text:
# [RiskAdjustedLinearizations.jl](@id Home)

This package provides a user-friendly API for efficiently calculating risk-adjusted linearizations
of dynamic economic models. These linearizations are equivalent
to first-order perturbations around the stochastic steady state and are solved
by computing affine approximations.

## License

This content is released under the [MIT](https://opensource.org/licenses/MIT) License.

## Contents

```@contents
Pages = ["risk_adjusted_linearization.md", "sparse_arrays_jacs.md", "numerical_algorithms.md", "example.md", "caching.md", "diagnostics.md", "tips.md"]
```

license: MIT

branch_name: refs/heads/main

extension: md

license_type: permissive


text:
# How to create Apps on Slack and Bot users

* Navigate to `https://api.slack.com/apps/`.
* Create a new app in your desired workspace.
* Configure app settings and add desired collaborators.
* Under the `Add features and functionality` section, click on `Bots`, and add a bot user.
* From the left sidebar, click on `install app` and install the application in your workspace.
* Now navigate to slack workspace.
* Open the channel in which you want to add the bot-user.
* Click on the settings icon, and then on `Invite new members to join`. Type in the bot-user's name and invite it to the channel.

repository: stakater/til

branch_name: refs/heads/master

repo_name: stakater/til


text:
# Tic Tac Toe

## Requirements

* Yarn
* Nodejs

To get started, clone the project from [GitHub](https://github.com/xNocken/tic-tac-toe) and follow the steps below:

* Open any shell in root and type ```yarn```
* Run webpack with ```yarn dev```
* Open /globalconfig.js and change ip to your ip
* Start the server with ```yarn start```

## Development

* Run webpack with ```yarn dev```

repository: xNocken/tic-tac-toe

gha_language: JavaScript

gha_license_id: MIT

repo_name: xNocken/tic-tac-toe


text:
# Changelog

Notable changes to this project are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

Breaking changes:

New features:

Bugfixes:

Other improvements:

## [v3.0.0](https://github.com/purescript/purescript-gen/releases/tag/v3.0.0) - 2021-02-26

Breaking changes:
- Added support for PureScript 0.14 and dropped support for all previous versions (#26)

New features:

Bugfixes:
- Make `elements` test no longer hang at cost of possible false negative (#29)
- Fixed `fromIndex` internal helper in tests (#23)

Other improvements:
- Refer people to the `quickcheck` package's `Gen` type as a default implementation for `MonadGen` (#25)
- Restored frequency tests (#28)
- Migrated CI to GitHub Actions and updated installation instructions to use Spago (#30)
- Added a changelog and pull request template (#31, #32)

## [v2.1.1](https://github.com/purescript/purescript-gen/releases/tag/v2.1.1) - 2019-04-29

- Fixed `unfoldable` looping forever when `size` is `< 0`
- Fixed `genNonEmpty` reducing the size below `0`

## [v2.1.0](https://github.com/purescript/purescript-gen/releases/tag/v2.1.0) - 2018-06-22

- Added `genEither'` and `genMaybe'` that take a bias parameter to alter `Left/Right` and `Just/Nothing` frequency

## [v2.0.0](https://github.com/purescript/purescript-gen/releases/tag/v2.0.0) - 2018-05-23

- Updated for PureScript 0.12

## [v1.3.1](https://github.com/purescript/purescript-gen/releases/tag/v1.3.1) - 2018-02-26

- Export `filtered` function (@safareli)

## [v1.3.0](https://github.com/purescript/purescript-gen/releases/tag/v1.3.0) - 2018-02-25

- Generalized generators to take `Foldable1` inputs where `NonEmpty` was required previously (@matthewleon)

## [v1.2.1](https://github.com/purescript/purescript-gen/releases/tag/v1.2.1) - 2018-02-25

- Fix warnings (@matthewleon)

## [v1.2.0](https://github.com/purescript/purescript-gen/releases/tag/v1.2.0) - 2018-02-23

- Added `filtered` (like `suchThat` but filters based on `Maybe` rather than a predicate) (@safareli)

## [v1.1.1](https://github.com/purescript/purescript-gen/releases/tag/v1.1.1) - 2017-11-09

- Fixed behaviour of `frequency` (@safareli)

## [v1.1.0](https://github.com/purescript/purescript-gen/releases/tag/v1.1.0) - 2017-04-08

- Added `genNonEmpty`

## [v1.0.0](https://github.com/purescript/purescript-gen/releases/tag/v1.0.0) - 2017-04-04

- Initial release

repository: dhinojosa/language-matrix

gha_language: Java

repo_name: dhinojosa/language-matrix


text:
---
title: 'Shattered Pixel Dungeon v0.5.0: The Visual Overhaul!'
excerpt: "I’ve mentioned a few times that I have big plans for 2017, and this update is the first of them. Shattered Pixel Dungeon has adopted an entirely new visual style! The new graphics give an impression of depth: walls are raised, characters actually stand up on the floor, and characters & items cast shadows! The new style will also serve as a basis for future visual improvements. For now I’ve kept the style very close to the original game, but there is plenty of opportunity for lots of new, cool things with the extra visual dimension."
---
It’s been almost 3 months since the last shattered update, time to fix that!

I’ve mentioned a few times that I have big plans for 2017, and this update is the first of them. Shattered Pixel Dungeon has adopted an entirely new visual style! The new graphics give an impression of depth: walls are raised, characters actually stand up on the floor, and characters & items cast shadows! The new style will also serve as a basis for future visual improvements. For now I’ve kept the style very close to the original game, but there is plenty of opportunity for lots of new, cool things with the extra visual dimension.

The update is available now through Google Play, and will be available to users on other platforms soon.

Here’s a full list of changes:

```
New Visuals!:
- Walls and some terrain now have depth
- Characters & items are raised & cast shadows
- Added a visible tile grid in the settings menu
- Various Bugfixes
- Translation Updates

Balance Changes:
- Quarterstaff armor bonus increased from 2 to 3
- Wand of Frost damage against chilled enemies
  reduced from -7.5% per turn of chill to -10%
- Wand of Transfusion self-damage reduced
  from 15% max hp per zap to 10% max hp per zap
- Dried Rose charges 20% faster and the ghost
  hero is stronger, especially at low levels
- Glyph of Entanglement activates less often
  but grants significantly more herbal armor
- Glyph of Stone armor bonus reduced
  from 2+level to 0+level
- Glyph of Antimagic magical damage resist
  reduced from 50% of armor to 33% of armor
- Glyph of Viscosity damage rate increased
  from 10% of deferred damage to 15%
- Exhausting Curse activates more often
```

## New Visuals!:

Not many specifics to discuss here, best to get into the game and try them out! One thing to note regarding the visible tile grid though, it defaults to on at a very low setting, where it subtly darkens every other tile. While testing I found this subtle change was impossible to detect unless I focused on it, but it still helped with clearly seeing the tile grid. If you’re having trouble seeing where tiles are, try turning this up, it gets in the way of the visuals a bit but makes it really clear where you need to tap. You can of course turn it off completely too if you find it annoying even on very low.

Obviously the new visuals are a huge sudden change, and I expect more than a few people will get some whiplash. I have no plans to offer a toggle to the old style, but I do intend to continue improving the visuals to be the best they can be. If you have any feedback, please let me hear it.

## Balance changes:

These are mostly minor adjustments meant to nudge items into line. They were all made after looking into data from player analytics, which I receive from players who have enabled google play services. Essentially, all of these items got nerfed or buffed because they were showing up in won runs a bit too often, or not quite often enough.

gha_language: Ruby


text:
# Getting Started

Caesar.jl is one of the packages within the [JuliaRobotics](http://www.juliarobotics.org) community, and adheres to the [code-of-conduct](https://github.com/JuliaRobotics/administration/blob/master/code_of_conduct.md).

## Local copy of Julia

Although [Julia](https://julialang.org/) (or [JuliaPro](https://juliacomputing.com/)) can be installed on a Linux computer using the `apt` package manager, we are striving for a fully local installation environment which is highly reproducible on a variety of platforms.

The easiest method is---via the terminal---to [download the desired](https://julialang.org/downloads/) version of Julia as a binary, extract, setup a symbolic link, and run:

```bash
cd ~
mkdir -p julia-software
cd julia-software
wget https://julialang-s3.julialang.org/bin/linux/x64/0.6/julia-0.6.4-linux-x86_64.tar.gz
tar -xvf julia-0.6.4-linux-x86_64
cd /usr/bin
sudo ln -s ~/julia-software/julia-9d11f62bcb/bin/julia julia064
sudo ln -s julia064 julia
```
**NOTE** Feel free to modify this setup as you see fit.

This should allow any terminal or process on the computer to run the Julia REPL:

```
<EMAIL_ADDRESS>julia

   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: https://docs.julialang.org
   _ _   _| |_  __ _   |  Type "?help" for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.6.3 (2018-05-28 20:20 UTC)
 _/ |\__'_|_|_|\__'_|  |  Official http://julialang.org/ release
|__/                   |  x86_64-pc-linux-gnu

julia> println("hello world")
hello world
```

Maybe a script, or command:

```
<EMAIL_ADDRESS>echo "println(\"hello again\")" > myscript.jl
<EMAIL_ADDRESS>julia myscript.jl
hello again
<EMAIL_ADDRESS>rm myscript.jl

<EMAIL_ADDRESS>julia -e "println(\"one more time.\")"
one more time.
```

**NOTE** When searching for Julia related help online, use the phrase 'julialang' instead of just 'julia'.
For example, search for 'julialang workflow tips' or 'julialang performance tips'.

## Just-In-Time Compiling (i.e. why are first runs slow?)

Julia uses just-in-time compilation ([unless pre-compiled](https://stackoverflow.com/questions/40116045/why-is-julia-taking-a-long-time-on-the-first-call-into-my-module))
 which is slow the first time a function is called but fast from the second call onwards, since the static function is now cached and ready for use.

## Setup Juno IDE Environment

[Juno IDE](http://junolab.org/) allows for interactive development of Julia code by extending the [Atom text editor](https://atom.io/) with a few packages.
Download and install Atom as instructed on the website, or via command line:

```
cd ~/Downloads
wget https://atom.io/download/deb
dpkg -i atom-amd64.deb
```

After installing and running Atom, you can choose to either install `uber-juno` package [in one go](https://github.com/JunoLab/uber-juno/blob/master/setup.md) or install the three associated packages individually.
In Atom, open the command pallette by pressing `Ctrl + Shft + p` and typing `settings`.
Go to the `install` tab, search for and install these packages:
```
ink
julia-client
julia-language
latex-completions
```

**NOTE** Some situations have required separately installing the `Atom.jl` Julia package via command line and Julia REPL; this is done with Julia's package manager and `Pkg.add("Atom")`:

```
$ julia
...
julia> Pkg.add("Atom")
```

There are a variety of useful packages in Atom, such as `minimap` and `minimap-git`.

To install the Julia packages related to [Caesar.jl]()---which are independent of the Atom packages installed above---please follow instructions below.

## Julia Packages

The philosophy around Julia packages are discussed at length in the [Julia core documentation](https://docs.julialang.org/en/stable/manual/packages/), where each Julia package relates to a git repository likely found on [Github.com](http://www.github.com).
To install a Julia package, simply open a `julia` REPL (equally the julia REPL in Atom/Juno) and type:

```julia
Pkg.add("Caesar")
```

These are [registered packages](https://pkg.julialang.org/) maintained by [JuliaLang/METADATA.jl](http://www.github.com/JuliaLang/METADATA.jl).
Unregistered packages can also be installed with using only the `Pkg.clone` function:

```julia
# Just using Caesar URL as an example --  Caesar is already registered with METADATA
Pkg.clone("https://github.com/JuliaRobotics/Caesar.jl.git")
```

Unless you change the default environment variable `JULIA_PKG_DIR`, all packages (git repos) are cloned/installed to `~/.julia`.
You can work with the packages as regular git repositories there.

## Install Visualization Utils (e.g. Arena.jl)

Visualizations were removed from Caesar by popular demand and moved to a new package [Arena.jl](https://github.com/JuliaRobotics/Arena.jl) instead.
Please follow instructions on the [Visualizations page](http://www.juliarobotics.org/Caesar.jl/latest/arena_visualizations.html) for a variety of 2D / 3D utilities.

## Contributing, Issues, or Comments

Please feel free to open [issues with Caesar.jl](https://github.com/JuliaRobotics/Caesar.jl/issues) or even Fork and Pull Request as required.
General conversations or comments can be made in the [Caesar Gist](https://gist.github.com/dehann/537f8a2eb9cc24d8bbd35ae92cb4d2d2).


text:
---
layout: post
title: Competition, A Necessary Evil
date: '2014-01-19 02:38:49'
---

When I see an online contest, my first reaction is to run as fast as possible in the opposite direction. This is due partly to bad experiences, but mostly because my reasons for entering contests were misguided. I have learned a lot from both winning and losing competitions.

Things to remember when entering a contest :

- Be humble, arrogance in competition is ugly
- Don't focus on the prize, there is only one
- Have a passion for the contest
- Don't rush, get it right, half-done never wins

## Calculator App Contest

[Team Treehouse](https://teamtreehouse.com/) just put on a contest, [Calculator App for iOS](https://teamtreehouse.com/forum/forum-contest-calculator-app-for-ios), which sounded like a great way for me to [start giving back to others](http://blog.jo2.co/the-balance-of-creation-consumption/#creationconsumption). I have been impressed with what the Treehouse's team has been doing with their online training service.

[![Team Treehouse]({{ site.baseurl }}public/content/images/treehouse_logo.jpg)](https://teamtreehouse.com/forum/forum-contest-calculator-app-for-ios)

The details for the app contest :

- Build an app that is based on Apple's calculator
- Make the addition button work
- Due by January 19th *(tomorrow as I am writing this)*
- Post it on [Github](https://github.com/) or [Dropbox](https://www.dropbox.com/)

Let the competition ensue. :)

### Research

Find apps like what you are wanting to build.

![Calculator App Icon]({{ site.baseurl }}public/content/images/calc.png)

I spent a while testing what happens when using the Apple calculator in different ways. Below are a few tests :

*[button] display*

- [3] 3 [+] 3 [5] 5 [=] 8 [=] 13 [=] 18
- [4] 4 [%] 0.04
- [3] 3 [-] 3 [1] 1 [+] 2 [4] 4 [x] 4 [3] 3 [=] 14
- [4] 4 [.] 4. [5] 4.5 [+] 4.5 [3] 3 [=] 7.5

### Functionality

I spent a good chunk of time trying to get it as close to working like the original app. Here is what I was able to get working :

- math operations [+], [-], [x], [/]
- percent ... [4] 4 [%] 0.04
- signing ... [4] 4 [+/-] -4
- clear / all clear ... [4] 4 [c] 0 and [ac] clears last operation
- decimal ... [4] 4 [.] 4. [6] 4.6
- equals after operation ... [4] 4 [+] 4 [4] 4 [=] 8 [=] 12
- operation after operation ... [4] 4 [+] 4 [3] 3 [-] 7 [2] 2 [=] 5

I always get annoyed when I accidentally hit the wrong number while in the middle of a multi-step formula. So I chose to add a "delete" button that removes numbers if they have just been input. It does not delete if the display is a result.

- delete ... [4] 4 [5] 45 [del] 4 [del] 0

### Design & Experience

Specifications I wanted to follow :

- works for both 3.5 & 4 inch displays
- simple iOS 7 look with better touch and selected animations
- resizable font size for display (like the original app)
- design that will be dynamic for future ability to customize
- discover and use original font

My biggest design challenge was the font**(s)**. Yes, that is plural. Apple uses the Helvetica Neue family for most of there thin [fonts in iOS 7](http://iosfonts.com/). But the funny thing is the decimal point in [Helvetica Neue](http://www.myfonts.com/fonts/linotype/neue-helvetica/) is a line, not a circle. So I went about finding a good decimal and I ended up using [Avenir](http://www.myfonts.com/fonts/linotype/avenir/). The button was easy, the display was a little trickier. I setup a simple [NSMutableAttributedString](https://developer.apple.com/library/mac/documentation/cocoa/reference/foundation/classes/NSMutableAttributedString_Class/Reference/Reference.html) to solve the display issue.

I wanted to have a nerdy throwback. So I based the icon on [calculator speak](http://en.wikipedia.org/wiki/Calculator_spelling). When you put 1337 in a calculator and turn it upside down it spells LEEt (as in an elite nerd).

![1337 App Icon]({{ site.baseurl }}public/content/images/leet_icon.png)

Here are the screenshots of the calculator app that I built.

![Launch Image]({{ site.baseurl }}public/content/images/leet_launch.jpg)
![Screen Shot]({{ site.baseurl }}public/content/images/leet_ss.jpg)
![Screen Shot]({{ site.baseurl }}public/content/images/leet_ss2.jpg)

### Project Links

- [Github - 1337 Calc](https://github.com/joalbright/1337-Calc)
- [Treehouse Contest Entry](https://teamtreehouse.com/forum/forum-contest-calculator-app-for-ios#featurette-241)
- [The Iron Yard](http://theironyard.com/)

Wish me luck!


text:
## TCP Window Full

Send Function                           | Socket Options           | TCP Window full
----------------------------------------|--------------------------|-------------------------------------------
gen_tcp:send(Socket, Data)              | {send_timeout, infinity} | Block forever.
port_command(Socket, Data)              | {send_timeout, infinity} | Block forever.
port_command(Socket, Data, [force])     | {send_timeout, infinity} | Return true always. Write to TCP Stack.
port_command(Socket, Data, [nosuspend]) | {send_timeout, infinity} | Return false always. Drop the packets silently.
gen_tcp:send(Socket, Data)              | {send_timeout, 5000}     | Return {error, timeout}.
port_command(Socket, Data)              | {send_timeout, 5000}     | Return true always. Pause 5 seconds and Drop packets silently.
port_command(Socket, Data, [force])     | {send_timeout, 5000}     | Return true always. Write to TCP Stack.
port_command(Socket, Data, [nosuspend]) | {send_timeout, 5000}     | Return false first, and true after timeout. Drop the packets silently.

## Conclusions

1. Should set the `send_timeout` option if using `gen_tcp:send`
2. Should not set the `nosuspend` option if using `port_command`, for the busy sock will be killed at once.

repository: xio/esockd

repo_name: xio/esockd


text:
# Eloquent datatables

[![Latest Version on Packagist](https://img.shields.io/packagist/v/singlequote/laravel-datatables.svg?style=flat-square)](https://packagist.org/packages/singlequote/laravel-datatables)
[![Total Downloads](https://img.shields.io/packagist/dt/singlequote/laravel-datatables.svg?style=flat-square)](https://packagist.org/packages/singlequote/laravel-datatables)

This repo contains a Datatable that can render a filterable and sortable table. It aims to be very lightweight and easy to use. It has support for retrieving data asynchronously, pagination and recursive searching in relations.

## Note
Users who want to use the older version of this package, go to the [early version repo](https://github.com/ACFBentveld/Laravel-datatables). The ACFBentveld group is transferd to a new group called SingleQuote.

## Installation

> The package is tested on laravel 5.8.*

You can install the package via composer:
```bash
composer require singlequote/laravel-datatables
```

## Whats new
Yes, we live in a time where everything is automated. So in this version we introduce some very cool features.
In this version the html and the script is created for you. Also this version is based on how laravel nova works.

## Let's start
We wanted our code as clean as possible and use the same code more than once.

[See the Quick start docs here](https://singlequote.github.io/Laravel-datatables/)

### Changelog

Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.

## Contributing

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

## Postcardware

You're free to use this package, but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.

Our address is: ACF Bentveld, Ecu 2 8305 BA, Emmeloord, Netherlands.

## Credits

- [Wim Pruiksma](https://github.com/wimurk)
- [All Contributors](../../contributors)

## License

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

repository: kastoras/Laravel-datatables

repo_name: kastoras/Laravel-datatables


text:
---
title: Getting Started
icon: home
ordinal: 0
---

### Badger Wallet

Install the extension for your browser from https://badger.bitcoin.com

### Local Development

Web pages must be served from an http server for Badger Wallet to inject its API for use in your app or site.

One easy to use server for local testing and development is [http-server](https://www.npmjs.com/package/http-server).

#### Install NodeJS and http-server

Use the official installer from [nodejs.org](https://nodejs.org/). Install the one which says “Recommended for Most Users”

To install http-server:

    npm install http-server -g

#### Running the API samples

Clone the badger-samples repository:

    git clone https://github.com/bitcoin-com/badger-samples.git

Start the http-server in the samples directory:

    http-server ./badger-samples

Navigate to http://localhost:8080/ to browse the samples


text:
# route\_append #

This rails gem/plugin allows you to append routes dynamically to your pre-existing routes

Works well for testing abstract controllers that normally have no routes associated with them

## Example ##

	ActionController::Routing::Routes.append do |map|
	  map.connect 'login_required', :controller => 'application', :action => 'login_required'
	end

extension: markdown


text:
# Laravel-Elasticsearch

An easy way to use the official Elastic Search client in your Laravel 5.

* [Installation and Configuration](#installation-and-configuration)
* [Usage](#usage)
* [Bugs, Suggestions and Contributions](#bugs-suggestions-and-contributions)
* [Copyright and License](#copyright-and-license)

## Installation and Configuration

Install the `addons/elasticsearch` package via composer:

```shell
composer require addons/elasticsearch
```

### Laravel

Add the service provider and facade to `config/app.php`:

```php
'providers' => [
    ...
    Addons\Elasticsearch\ServiceProvider::class,
]

'aliases' => [
    ...
    'Elasticsearch' => Addons\Elasticsearch\Facade::class,
]
```

Publish the configuration file:

```shell
php artisan vendor:publish --provider="Addons\Elasticsearch\ServiceProvider"
```

## Usage

The `Elasticsearch` facade is just an entry point into the ES client, so previously
you might have used:

```php
$data = [
    'body' => [
        'testField' => 'abc'
    ],
    'index' => 'my_index',
    'type' => 'my_type',
    'id' => 'my_id',
];

$client = ClientBuilder::create()->build();
$return = $client->index($data);
```

You can now replace those last two lines with simply:

```php
$return = Elasticsearch::index($data);
```

That will run the command on the default connection.  You can run a command on
any connection (see the `defaultConnection` setting and `connections` array in
the configuration file).

```php
$return = Elasticsearch::connection('connectionName')->index($data);
```

Please be noticed that you should not use Facade in Lumen.
So, in Lumen - you should use IoC or get the ElasticSearch service object from the application.
```php
$elasticSearch = $this->app('elasticsearch');
```

## Copyright and License

[elasticsearch](https://git.load-page.com/addons/elasticsearch)
was written by [Colin Viebrock](http://viebrock.ca),[Fly Mirage](https://www.load-page.com/base/manual) and is released under the
[MIT License](LICENSE.md).

Copyright (c) 2016


text:
# Frontend
App = m({}, {sinkNames:..., routeSource:...}, UI)

UI = \[[SidePanel](.SidePanel.md), [MainPanel](.MainPanel.md)\]

### Nav
only sets enclosing <nav> tags
### Section, SubSection
- settings :
  - title
    - a priori used by the parent component, should be displayed proeminently, ahead of subsections and other children
  - link
    - clicking on the div should route to the location in `link`

# Advantages
- you can go top down
  - take a ui
  - break it down into components
  - write the structure first
  - then fill in the blank in the order that you want
    - first dummy html
    - then real html constructed from inputs
    - then add events
    - then add actions and services
  - this allows for progressive testing

Resistance to changes or maintanability :
- if the ui changes, it is easy to find where to apply changes, as the component tree follows the UI.
- if the model changes, it is a bit more annoying, but disciplined use of Inject can help finding out the component affected by the model change (the famous slicing problem)
- if the action changes, that is a bit more easy, it is about getting maybe different inputs (Inject!) and changing the reactive funcion (action = f(event))

There can still be significant changes in implementation from changes in UI/model/functionality, however hopefully the impact on the implementation is easier to identify, and only a specific slice has to change.

# Organization
Find a way to organize all the information. When the tree gets deep, one loose navigation ability, which is the key really to readability, which is a problem with angular (going back and forth between component and diretives, and js, and html, etc.)

repository: cyclejs-community/component-combinators

repo_name: cyclejs-community/component-combinators


text:
# static-site-generator

---

A simple template language for generating static websites using HTML, JS, and CSS.

`static-site-generator`'s goal is to make development of static websites using raw HTML, CSS, and JS as frictionless as possible by reducing repetition.

## Setup

Currently, this project doesn't have a standalone command-line utility or associated `npm` package, so to use it you just need to clone this git repository and use the included scripts to run the template engine.

To set up a local clone of this project, run:
```
git clone https://github.com/nicholascc/static-site-generator.git
cd static-site-generator
npm install
```

## Usage

---

### Basic directory structure

```
.
├── desc/
│   ├── out.txt
│   ├── global.json
│   └── other files...
└── gen/
    └── resulting website is placed here...
```

The `static-site-generator` engine takes a description folder (`desc/`) containing templates and other specialized files, and uses that data to generate a static website (in the `gen/` folder) which can be hosted using any static file hosting service you like (e.g. Github Pages, Netlify, Surge, Amazon S3).

### Commands

- `npm run serve` - starts a basic web server (using [http-server](https://www.npmjs.com/package/http-server)) which hosts the contents of `gen/` at http://localhost:8080/.

- `npm run build` - generates a website based on the description (in `desc/`)

- `npm run watch` - starts a process watching for changes in `desc/`; upon any updates to `desc/` it regenerates the website based on the updated description. Note that this command currently doesn't watch subdirectories of `desc/` and doesn't delete files in `gen/` once their corresponding description files are removed (these are both bugs and should be fixed).

Recommended usage is to run both `serve` and `watch` simultaneously so that you can view new changes in your web browser just by refreshing the page.

### Special description files

The `desc/` folder contains 2 special files: `out.txt` and `global.json`.

`global.json` is a JSON file parsed as a flat dictionary defining global variables that can be used in any template.

`out.txt` directs the template engine on how to translate the description to a generated site. Each line represents a copy operation where one file or directory in the `desc/` folder is moved to the `gen/` folder, with files optionally passing through the template engine first.

For example:

```
# Comments are prefixed by a '#' character
index.css >> index.css

# The '$' character in the below instruction means that this file should be evaluated with the template engine before copying
home_page.html >$> index.html

# Directories can be copied as well as files.
img/ >> img/
```

The above `out.txt` file will cause the generator, when run, to
1. copy `desc/index.css` to `gen/index.css`
2. execute `desc/home_page.html` with the template engine and copy it to `gen/index.html`
3. copy `desc/img/` and its contents to `gen/img/`

### The template engine file format

The template engine is designed for HTML, but it also works with any other plain-text file format. Template commands are delimited with `$<` and `>$` and have space-separated arguments; for example, a command to define the variable `contents` would be written like `$<def contents>$`.

#### Commands:

* A variable literal starts with `-`. For example, `$<-content>$` will be replaced by the value stored in variable `content`.

* The `def` command takes all the lines that follow it until the end of the file or another `def` command, and places those lines in the variable named by its second argument. Note that all variables are constant and cannot be redefined.

* The `inherit` command can only occur once in a file and should be placed in the file's first line. If an `inherit` command is encountered in a file, then that file will only be used to define variables, and once those variables are defined, the template engine will move to generating using the file referenced by the inherit command (that file can also inherit from another file; the command is recursive).

For example, if a file `home.html` has the following data:

```
$<inherit website.html>$

$<def body>$
<h1>
  This is the website's home page.
</h1>
```

and `website.html` has the following data:

```
<!DOCTYPE html>
<html>
<head>
  <title>Example Website</title>
</head>
<body>
  <!-- A website header might be included here -->
  <div class="body">
    $<-body>$
  </div>
</body>
```

then the template engine, when evaluated on `home.html`, will output the file:

```
<!DOCTYPE html>
<html>
<head>
  <title>Example Website</title>
</head>
<body>
  <!-- TODO: Add a website header here. -->
  <div class="body">
    <h1>
      This is the website's home page.
    </h1>
  </div>
</body>
```

Nothing about this process is specific to HTML; `static-site-generator` will work just as well for any other plain-text file format.

repository: nicholascc/static-site-generator

repo_name: nicholascc/static-site-generator


text:
# go-conllu
CoNLL-U parser written in Go. Convert CoNLL-U files to in-memory structs

[![](https://godoc.org/github.com/nuvi/go-conllu?status.svg)](https://godoc.org/github.com/nuvi/go-conllu)

The Computational Natural Language Learning - U format (CoNLL-U) is used by the [Universal Dependencies](https://universaldependencies.org/format.html) project to represent natural language annotations.
`go-conllu` parses CoNNL-U file formats and exposes the data via in-memory Go structs.

## ⚙ Installation

```bash
go get github.com/nuvi/go-conllu
```

## 🚀 Quick Start

```go
package main

import (
	"fmt"
	"log"

	conllu "github.com/nuvi/go-conllu"
)

func main() {
	sentences, err := conllu.ParseFile("../../test_data/en_ewt-ud-train.small.conllu")
	if err != nil {
		log.Fatal(err)
	}

	for _, sentence := range sentences {
		for _, token := range sentence.Tokens {
			fmt.Println(token)
		}
		fmt.Println()
	}
}
```
## Issues

All issues should be submitted via the issues tab on Github. Please provide the code and data used in order for us to reproduce the issue.

## 💬 Contact

Feel free to reach out with questions/comments to maintainers:

[![Twitter Follow](https://img.shields.io/twitter/follow/wagslane.svg?label=Follow%20Wagslane&style=social)](https://twitter.com/intent/follow?screen_name=wagslane)

## Transient Dependencies

None, and we plan to keep it that way.

## 👏 Contributing

We love help! Contribute by forking the repo and opening pull requests. Please ensure that your code passes the existing tests and linting processes, and write new tests to test your changes if applicable.

All pull requests should be submitted to the "master" branch.

```bash
go test
```

```bash
go fmt
```

repository: nuvi/go-conllu

gha_language: Go

repo_name: nuvi/go-conllu


text:
# Detail-oriented Capsule Network
Official PyTorch implementation of the Detail-oriented Capsule Network (DECAPS) proposed in
the paper [Radiologist-Level COVID-19 Detection Using CT Scans with Detail-Oriented Capsule Networks](https://arxiv.org/pdf/2004.07407.pdf).

![FastCapsNet](imgs/decaps.png)
*Fig1. Detail-oriented Capsule Network architecture for COVID-19 Detection from CT scans*

## Dependencies
- Python (3.5 preferably; should also works fine with python 2.7)
- NumPy
- [PyTorch](https://pytorch.org/)>=1.1
- [torchvision](https://pytorch.org/)>=0.3
- [Tensorflow](https://github.com/tensorflow/tensorflow)>=1.10 (for visualizations with Tensorboard)
- Matplotlib (for saving images)

## How to run the code

### 1. Prepare your data
The COVID-19 CT dataset is currently available [Here](https://github.com/UCSD-AI4H/COVID-CT).
By April 17th of 2020,  it
contains a total of 746 chest CT images, which are divided
into two classes, namely COVID-19 and non-COVID-19. Instructions on
preparing the data for the model will be prepared and uploaded soon.

### 2. Train
Most of the network hyper-parameters can be found in ```config.py``` file. You may modify them or run with
the default values which runs the DECAPS proposed in the paper.

Training the model displays the training results and saves the trained model if an improvement observed in the accuracy value.
- For training with the default setting: ```python train.py ```
- For training with a different batch size: ```python train.py --bs=16```

### 3. Test:
- For running the test: ```python inference.py --load_model_path=/path/to/saved/model```
where ```load_model_path``` is the path to the desired .ckpt file.


text:
# Dendrite EKS example

Example project that shows how to set up an Elastic Kubernetes Service (EKS) cluster on AWS and run a project based on [archetype-rust-axon](https://github.com/dendrite2go/archetype-rust-axon) on it.

The steps are documented in [doc/aws.md](doc/aws.md). I'm currently stuck at getting the aws-load-balancer-controller to work.


text:
# py4cl2

[Last update: v2.9.0]

## Introduction

[py4cl][bendudson/py4cl] is a package by Ben Dudson, aimed at making python libraries availble in Common Lisp using streams to communicate with a separate python process - this is the approach taken by [cl4py](https://github.com/marcoheisig/cl4py) and is
different to the CFFI approach used by [burgled-batteries](https://github.com/pinterface/burgled-batteries),
but has the same goal.

[py4cl2](https://github.com/digikar99/py4cl2) is intended to be an improvement over the original py4cl - importing of arguments posed a critical problem with backwards-compatibility. (See [Highlights and Limitations](#highlights-and-limitations-of-py4cl).)

Please report the issues on github: [py4cl2](https://github.com/digikar99/py4cl2/issues) or [py4cl](https://github.com/bendudson/py4cl/issues)).

## Highlights and Limitations of `py4cl`

- Speed: About 6500 `(pycall "int" "5")` instructions per second @ 1GHz intel 8750H.
This shouldn't be a bottleneck if you're planning to run "long" processes in python. (For example, deep learning :). )
- Virtual environments: [`pycmd`](#pycmd) (`*python-command*` in `py4cl`): Choose which python binary to use. Works with miniconda.
- Multiple python processes (not documented here) - parallel execution?
- CI for SBCL, CCL, and ECL
- v2.6.0 worked with ABCL 1.7.1 (Java 1.8) despite several limitations (see the documentation included in [that release](https://github.com/digikar99/py4cl2/releases/tag/v2.6.0)).
- While CI has not been set up for windows (a PR is welcome!), from v2.7.0, things will be tested locally before releasing.
- No support for inheriting python classes - should require MOP
- Mac users should update to a later version of bash. See [this stackoverflow question](https://stackoverflow.com/questions/32481734/shell-error-with-bash-bad-substitution-no-closing). Thanks to [byulparen](https://github.com/byulparan) for pointing out!
- Embeddable into lisp-image - the code from py4cl.py is copied into `*python-code*` and heredocs are used. This is made to happen for unix and not for windows; until someone gets into Windows heredocs. (Maintainer note: This entails not using single-quote character `'` in py4cl.py.) Also note that this still requires the developer (= py4cl2 user) to supply the python libraries and binaries along with the lisp image to the (very-)end-user.
- Improvements in large array transfer speed numpy-file-format (see [initialize](#initialize)); while this does not beat `remote-objects` in existence since `py4cl`, it does provide a faster way to send array data from lisp to python and can be beneficial while offloading the work to python process, eg. deep learning.
- Ability to interrupt the python process using [(pyinterrupt)](#pyinterrupt)

## Upcoming Sources of Possible Code Breakage

- `*lispifiers*` and `with-lispifiers` symbols are currently unstable introduced in this very version. Avoid using in production code until stability.

### Changes over py4cl

**Backwards Incompatible Changes**

**Unavoidable**

- Arguments are imported; submodules can be imported with an option to [defpymodule](#defpymodule). However, this is only possible for python3. In fact, with python2's end-of-life, no support for python2 is provided even.
- Asynchronous Printing: use `(with-python-output &body body)` to capture python output; in py4cl, `(with-output-to-stream (*standard-output*) &body body)` works. The separate macro [with-python-output](#with-python-output) was necessitated due to the asyncronous printing in py4cl2.
- Semantics of `nil`: see [Type Mapping and Pythonize](#type-mapping-and-pythonize)

**Avoidable**

- Several (but not all) names have been shorted from `python-` to `py`; `remote-objects` have been changed to `with-remote-object(s)`. Personal preference for these names stems from:
    - `defpyfun/module` reminds of the equivalent in `burgled-batteries` and `cffi`
    - `py`names are shorter
    - `with-remote` seems more appropriate
    - `chain` and `chain*` with more "uniformity"

**IMO Backwards Portable Changes**

- `defpymodule` (previously `import-module`) works "as-expected" with asdf / `defpackage`
- Embedding py4cl.py into lisp image
- importing submodules
- process startup errors

**Other Notes**

- Argument ordering can be wrong with ABCL, CCL or  ECL. I've not used it extensively at anywhere other than SBCL. Basic tests concerning argument orders do work on ABCL, CCL and ECL; since, in most cases, you are good with keyword args. Early adopters are welcome :D!

Feature / Implementation (default: linux)
SBCL
SBCL (Windows)
CCL
ECL
ABCL

Basic Functionality
✓
✓
?
?
?

Interrupt
✓
✗
✓
✗
✗

with-python-output
✓
✓
✗
✗
✓

array-element-type preservation
✓
✓
✓
✓
✗

Fast Large Array Transfer
✓
✓
✓
✗
✗

- See [Future Work](#future-work).

## Installation

### Dependencies

This fork is possible due to the following (and therefore, depends on):

On the CL side:

- alexandria
- bordeaux-threads
- cl-json
- trivial-garbage
- iterate
- numpy-file-format
- parse-number
- uiop (some implementations have an older version of uiop; support for `launch-program` is needed for asynchronous processes)

On python side:

- numpy (recommended for arrays)

(other packages should be available in a standard python distribution - tested with CPython.)

### Installation

Besides installing directly from [quicklisp](https://www.quicklisp.org/beta/), download the (latest) release from the [Releases](https://github.com/digikar99/py4cl2/releases) and untar/unzip into `~/quicklisp/local-projects/` or any other
location where it can be discovered by `quicklisp`:

```sh
wget -qO- https://github.com/digikar99/py4cl2/archive/v2.6.0.tar.gz | tar xvz - -C ~/quicklisp/local-projects
```

Load into REPL with
```lisp
(ql:quickload :py4cl2)
```

### Tests

See [py4cl2-tests](https://github.com/digikar99/py4cl2-tests)

### Setting up

#### initialize

On loading this library for the first time, run `initialize` and provide the necessary details.

```lisp
(py4cl2:initialize)
```

(You may want to note the printed information, about the location of config-file. Of course, you can call this function again, but be sure to refill the values.)

The library uses (temporary) pickled .npy files for transferring large numpy arrays efficiently
between lisp and python. This process is IO intensive, writing as much as 100MB or even a GB each time, and therefore, using a ram-disk is recommended for this purpose would be recommended. ([How to create a ram disk on Linux?](https://unix.stackexchange.com/questions/66329/creating-a-ram-disk-on-linux))

#### \*config\* / config-var

These values can also be accessed using `*config*` and `config-var`:

```lisp
CL-USER> py4cl2:*config*
((PY4CL2:PRINT-PYTHON-TRACEBACK . T)
 (PY4CL2:PYCMD . "/home/user/miniconda3/bin/python")
 (PY4CL2:NUMPY-PICKLE-LOCATION . "/home/user/ram-disk/_numpy_pickle.npy")
 (PY4CL2:NUMPY-PICKLE-LOWER-BOUND . 100000))
CL-USER> (py4cl2:config-var 'py4cl2:numpy-pickle-location)
"/home/user/ram-disk/_numpy_pickle.npy"
CL-USER> (setf (config-var 'py4cl2:pycmd) "python")
"python"
```

Complementary to `config-var` are `save-config` and `load-config`. The latter is called on startup, the config-file exists. `(setf config-var)` calls the former unless it is `pycmd`, as well as asks the python process to load the config, from the config file. (The exception for `pycmd` exists so as to let the users set up project-local environments.)

#### \*internal-features\* / \*warn-on-unavailable-feature-usage\*

This lists the features available on your system/implementation. Values in the list may include:

- `:ARRAYS`: requires numpy, and can be seen only after a call to `(pystart)`
- `:TYPED-ARRAYS`: requires support for specialized-arrays on lisp side; ABCL 1.7.1 does not provide this
- `:FAST-LARGE-ARRAY-TRANSFER`: requires support for [numpy-file-format](https://github.com/marcoheisig/numpy-file-format)
- `:INTERRUPT`: requires system support for SIGINT (and some more things not working on ECL)
- `:WITH-PYTHON-OUTPUT`

See also: the [feature comparison table](#feature-comparison).

Attempt to use a feature that is not available will signal a warning and has undefined consequences. To avoid the warning, set the value of `*warn-on-unavailable-feature-usage*` to `nil`.

## Examples and Documentation

```lisp
CL-USER> (use-package :py4cl2)
```

### Python Processes

It all starts with a python process (actually, more than one as well - however, this use hasn't been documented here.).

#### pycmd

```lisp
CL-USER> (config-var 'pycmd)
"python"
```

Also see [config-var](#config--config-var).

#### pyversion-info
```lisp
CL-USER> (pyversion-info)
(3 7 3 "final" 0)
```

#### pyinterrupt
`(pyinterrupt &optional process)`

A simple `C-c C-c` only interrupts the lisp process from slime - the python process keeps running. `(pyinterrupt)` can be used in these cases to send a SIGINT (2) to the python process.

Also note that if `pyinterrupt` is not called before sending the next form to `eval` or `exec`, the input-output would go out of sync. A known way to get out is to `(pystop)` the python-process.

Therefore, you may want to have `(pyinterrupt)` called on the reception of SIGINT in SLIME:

```lisp
(when (find-package :swank)
  (defvar swank-simple-break)
  (setf (fdefinition 'swank-simple-break)
        (fdefinition (find-symbol "SIMPLE-BREAK" :swank)))
  (defun swank:simple-break
      (&optional (datum "Interrupt from Emacs") &rest args)
    (py4cl2:pyinterrupt)
    (apply (fdefinition 'swank-simple-break) datum args)))
```

However, I have been unable to get the code to work (by adding to `do-after-load` with as well as without SLIME. Further, people may not like a library to fiddle with their environments - so it might be better to leave it up to the user to set it.

#### py-cd
`(py-cd path)`

Equivalent of `slime-cd`, since python is a separate process.

#### Other useful functions and variables

##### pystart
##### pystop
##### python-alive-p
##### python-start-if-not-alive
##### \*defpymodule-silent-p\*
##### \*print-python-object\*

### Doing arbitrary things in python

Unlike lisp, python (and most other languages) make a distinction between *statements* and *expressions*: see [Quora](https://www.quora.com/Whats-the-difference-between-a-statement-and-an-expression-in-Python-Why-is-print-%E2%80%98hi%E2%80%99-a-statement-while-other-functions-are-expressions) or [stackoverflow](https://stackoverflow.com/questions/4728073/what-is-the-difference-between-an-expression-and-a-statement-in-python).

A general rule of thumb from there is: if you can print it, or assign it to a variable, then it's an expression, otherwise it's a statement.

Both `pyeval` and `pyexec` take any type of arguments. The `arg` is `pythonize`d if the `arg` is not a `string`, or it is a `string` that can be read into a `real`.

#### raw-pyeval
`(raw-pyeval &rest strings)`

Concatenates the strings and sends them to the python process for `eval`uation. The concatenation should be a valid python expression. Returns the result of evaluating the expression.

#### raw-pyexec
`(raw-pyexec &rest strings)`

Concatenates the strings and sends them to the python process for `exec`uation. The concatenation should be a valid python statement. Returns nil.

Note that [one limitation of `pyexec` is that modules imported on the top-level (of python) are not available inside some things](https://stackoverflow.com/questions/12505047/in-python-why-doesnt-an-import-in-an-exec-in-a-function-work). These "some things" include functions.

The following should illustrate this point:
```lisp
CL-USER> (pyexec "import time")
NIL
CL-USER> (pyeval "time.time()")
1.5623434e9
CL-USER> (pyexec "
def foo():
  return time.time()")
NIL
CL-USER> (pyeval "foo()")
; Evaluation aborted on #<PYERROR {100C24DF03}> ;; says 'time' is not defined
CL-USER> (pyeval "time.time()")
1.5623434e9
```
THe workaround in this case is to `import` inside the `def`.

Often times, the two commands above would be tedious - since you'd need to convert objects into their string representations every time. To avoid this hassle, there are the following useful functions.

#### pyeval
`(pyeval &rest args)`

For python expressions
```lisp
CL-USER> (pyeval 4 "+" 3)
7
```

There's also `(setf pyeval)`, which unlike `(pyexec)`, can return non-`nil` values.

```lisp
CL-USER> (setf (pyeval "a") "5")
"5"
CL-USER> (pyeval "a")
"5"
```

`pyeval` (and `pyexec`) treats the string as a python string, if it can be parsed into a number.
In fact, in accordance with an internal function `pythonizep`.

```lisp
CL-USER> (pyeval "1.0")
"1.0"
CL-USER> (pyeval "hello")
; Evaluation aborted on #<PYERROR {1003AC0183}>.
```

See also [Doing arbitrary things in python](#doing-arbitrary-things-in-python).

#### pyexec
`(pyexec &rest args)`

For python statements
```lisp
CL-USER> (pyexec "
if True:
  print(5)
else:
  print(10)")
; 5
NIL
```
`pyexec` (and `pyeval`) treats the string as a python string, if it can be parsed into a number).
In fact, in accordance with an internal function `pythonizep`. (See [pyeval](#pyeval).)

See also [Doing arbitrary things in python](#doing-arbitrary-things-in-python) to learn about `pyeval` and `pyexec`.

### Defining python functions and modules

Rather, we define functions that call python functions.

Names are lispified by converting underscores hyphens, and converting CamelCase to camel-case. Also see [Name Mapping](#name-mapping).

#### defpyfun
```lisp
(defpyfun fun-name &optional pymodule-name &key
  (as fun-name) (lisp-fun-name (lispify-name as))
  (lisp-package *package*)
  (safety t))
```
`lisp-fun-name` is the name of the symbol that would be `fboundp`ed to the function [that calls the python function].

Example Usage:
```lisp
CL-USER> (defpyfun "Input" "keras.layers" :lisp-fun-name "INP")
INP

CL-USER> (inp :shape '(1 2))
##S(PY4CL2::PYTHON-OBJECT
   :TYPE "<class 'tensorflow.python.framework.ops.Tensor'>"
   :HANDLE 1849)
```

`safety` takes care to import the required function from the required module after python process restarts for some reason. However, this affects speed.

Refer `(describe 'defpyfun)`.

#### defpymodule
```lisp
(defpymodule (pymodule-name
              &optional (import-submodules nil)
              &key (cache t)
                (continue-ignoring-errors t)
                (lisp-package (lispify-name pymodule-name) lisp-package-supplied-p)
                (reload t)
                (recompile-on-change nil)
                (safety t)
                (silent *defpymodule-silent-p*)))
```

`lisp-package` is the name of the symbol that the package would be bound to.

Example Usage:
```lisp
CL-USER> (defpymodule "keras.layers" t :lisp-package "KL")
Defining KL for accessing python package kl...
Defining KL.ADVANCED-ACTIVATIONS for accessing python package kl.advanced_activations...
Defining KL.CONVOLUTIONAL for accessing python package kl.convolutional...
Defining KL.CONVOLUTIONAL-RECURRENT for accessing python package kl.convolutional_recurrent...
Defining KL.CORE for accessing python package kl.core...
Defining KL.CUDNN-RECURRENT for accessing python package kl.cudnn_recurrent...
Defining KL.EMBEDDINGS for accessing python package kl.embeddings...
Defining KL.LOCAL for accessing python package kl.local...
Defining KL.MERGE for accessing python package kl.merge...
Defining KL.NOISE for accessing python package kl.noise...
Defining KL.NORMALIZATION for accessing python package kl.normalization...
Defining KL.POOLING for accessing python package kl.pooling...
Defining KL.RECURRENT for accessing python package kl.recurrent...
Defining KL.WRAPPERS for accessing python package kl.wrappers...
T

CL-USER> (kl:input/1 :shape '(1 2))
#S(PY4CL2::PYTHON-OBJECT
   :TYPE "<class 'tensorflow.python.framework.ops.Tensor'>"
   :HANDLE 816)

CL-USER> (pycall (kl.advanced-activations:softmax/class :input-shape '(1 2))
                 (kl:input/1 :shape '(1 2)))
#S(PY4CL2::PYTHON-OBJECT
   :TYPE "<class 'tensorflow.python.framework.ops.Tensor'>"
   :HANDLE 144)
```

Note that unlike Common Lisp, python has a single namespace. Therefore, currently,
to call a callable (in Python) object, but not defined as a function in Common Lisp,
you'd need to use something like [pycall].

#### defpyfuns

(Undocumented here.)

### Customizing Type Mapping

#### \*lispifiers\*

> NOTE: This is a new feature and hence unstable; recommended to avoid in production code.

Each entry in the alist `*lispifiers*` maps from a lisp-type to a single-argument lisp function. This function takes as input the "default" lisp objects and is expected to appropriately parse it to the corresponding lisp object.

#### with-lispifiers
```lisp
(with-lispifiers ((&rest overriding-lispifiers) &body body))
```

> NOTE: This is a new feature and hence unstable; recommended to avoid in production code.

Each entry of `overriding-lispifiers` is a two-element list of the form

```
  (type lispifier)
```

Here, `type` is unevaluated, while `lispifier` will be evaluated; the `lispifier` is expected
to take a default-lispified object (see lisp-python types translation table in docs)
and return the appropriate object user expects.

For example,

```lisp
  (pyeval "[1, 2, 3]") ;=> #(1 2 3) ; the default lispified object
  (with-lispifiers ((vector (lambda (x) (coerce (print x) 'list))))
    (print (pyeval "[1,2,3]"))
    (print (pyeval 5)))
  ; #(1 2 3) ; default lispified object
  ; (1 2 3)  ; coerced to LIST by the lispifier
  ; 5        ; lispifier uncalled for non-VECTOR
  5
```

#### \*pythonizers\*

> NOTE: This is a new feature and hence unstable; recommended to avoid in production code.

Each entry in the alist `*pythonizers*` maps from a lisp-type to
a single-argument PYTHON-FUNCTION-DESIGNATOR. This python function takes as input the
"default" python objects and is expected to appropriately convert it to the corresponding
python object.

#### with-pythonizers

```lisp
(with-pythonizers (&rest overriding-pythonizers) &body body)
```

> NOTE: This is a new feature and hence unstable; recommended to avoid in production code.

Each entry of `overriding-pythonizers` is a two-element list of the form

```
  (type pythonizer)
```

Here, `type` is unevaluated, while `pythonizer` will be evaluated; the `pythonizer` is expected
to take a default-pythonized object (see lisp-python types translation table in docs)
and return the appropriate object user expects.

For example,

```lisp
  (pyeval "[1, 2, 3]") ;=> #(1 2 3) ; the default object
  (with-pythonizers ((vector "tuple"))
    (print (pyeval "[1,2,3]"))
    (print (pyeval 5)))
  ; #(1 2 3) ; default object
  ; (1 2 3)  ; coerced to tuple by the pythonizer, which then translates to list
  ; 5        ; pythonizer uncalled for non-VECTOR
  5
```

### Errors

#### pyerror

Signalled if there an error in a running python process

#### python-process-startup-error

Signalled if [pystart](#pystart) fails to start a python process

#### python-eof-and-dead

Signalled (from `dispatch-messages`) if the lisp process is unable to read/write from/to a python process and the process has died. This should provide a cleaner error than `CL:END-OF-FILE`.

#### python-eof-but-alive

Signalled (from `dispatch-messages`) if the lisp process is unable to read/write from/to a python process but the process is alive. This should provide a cleaner error than `CL:END-OF-FILE`.

### Using functions and methods

#### pycall
`(pycall fun-name &rest args)`

Equivalent to the lisp `(funcall function &rest arguments)`. Call a python (or lisp! See [generators and lambdas](#generators-and-lambdas)) function.

```lisp
CL-USER> (py4cl2:pycall "print" "hello")
;; hello
"None"
CL-USER> (py4cl2:pycall #'+ 2 3 1)
6
```

Note that `fun-name` can be a name (see [Name Mapping]), a function, or a [callable] python-object. See the example in [defpymodule](#defpymodule).

#### pymethod
`(pymethod obj method-name &rest args)`

`pymethod` always pythonizes; `method-name` is [name mapped to Python names][Name Mapping].

```lisp
SEQ2SEQ> (pymethod model 'summary) ;; for some "ready" model
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to
==================================================================================================
input_1 (InputLayer)            (None, None, 43)     0
__________________________________________________________________________________________________
input_2 (InputLayer)            (None, None, 64)     0
__________________________________________________________________________________________________
lstm_1 (LSTM)                   [(None, 256), (None, 307200      input_1[0][0]
__________________________________________________________________________________________________
lstm_2 (LSTM)                   [(None, None, 256),  328704      input_2[0][0]
                                                                 lstm_1[0][1]
                                                                 lstm_1[0][2]
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, None, 64)     16448       lstm_2[0][0]
==================================================================================================
Total params: 652,352
Trainable params: 652,352
Non-trainable params: 0
__________________________________________________________________________________________________
"None"
```

See [pymethod-list](#pymethod-list).

#### pyslot-value
`(pyslot-value object slot-name)`

```lisp
CL-USER> (pyslot-value model 'input-shape)
#((NIL NIL 43) (NIL NIL 64))
```

See [pyslot-list](#pyslot-list)

Also see [Name Mapping].

#### export-function
`(export-funtion function python-name)`

Lisp functions can be made available to python code using `export-function`:
```lisp
(py4cl:python-exec "from scipy.integrate import romberg")

(py4cl:export-function (lambda (x) (/ (exp (- (* x x)))
                                      (sqrt pi))) "gaussian")

(py4cl:python-eval "romberg(gaussian, 0.0, 1.0)") ; => 0.4213504
```

#### pyhelp
`(pyhelp python-object)`

Calls python's `help` function on `python-object`. (NOTE: some descriptions, especially
for modules, are too big to be transferred in a reasonable time.)

### Generators and Lambdas

#### pygenerator
`(pygenerator function stop-value)`

```lisp
CL-USER> (let ((a 0)) (defun foo () (incf a)))
FOO

CL-USER> (pyeval "[x for x in " (pygenerator #'foo 3) "]")
#(1 2)
```

#### lambdas

Lisp functions are `pythonize`d to `LispCallbackObject`s. As the name suggests, python can call LispCallbackObjects (and therefore, lisp functions), just like it is any other python callable (which it is!).

```lisp
CL-USER> (py4cl::pythonize #'car)
"_py4cl_LispCallbackObject(4)"

CL-USER> (pycall (lambda (string) (concatenate 'string string " - from Lisp"))
                 "hello")
"hello - from Lisp"
```

### Slot and Method Lists

Currently, all the python objects are grouped under the class `python-object`. The list of methods
and slots associated with these objects can be obtained using the following two functions.

#### pyslot-list
`(pyslot-list python-object &key as-vector)`

```lisp
CL-USER> (defpyfun "Model" "keras")
NIL

CL-USER> (pyslot-list (model))
("__class__" "__delattr__" "__dict__" "__doc__" "__eq__" "__ge__"
 "__getattribute__" "__gt__" "__hash__" "__le__" "__lt__" "__module__" "__ne__"
 "__repr__" "__str__" "__weakref__" "_built" "_expects_training_arg"
 "_inbound_nodes" "_initial_weights" "_is_compiled" "_is_graph_network"
 "_layers" "_losses" "_outbound_nodes" "_per_input_losses" "_per_input_updates"
 "_updates" "_uses_inputs_arg" "built" "input_spec" "inputs" "layers" "losses"
 "name" "non_trainable_weights" "optimizer" "outputs" "state_updates"
 "stateful" "supports_masking" "trainable" "trainable_weights" "updates"
 "uses_learning_phase" "weights")

CL-USER> (pyeval (model) ".inputs")
"None"
```

Optionally, see [pyslot-value](#pyslot-value)

#### pymethod-list
`(pymethod-list python-object &key as-vector)`

```lisp
CL-USER> (pymethod-list (model))
("__call__" "__class__" "__delattr__" "__dir__" "__eq__" "__format__" "__ge__"
 "__getattribute__" "__getstate__" "__gt__" "__hash__" "__init__"
 "__init_subclass__" "__le__" "__lt__" "__ne__" "__new__" "__reduce__"
 "__reduce_ex__" "__repr__" "__setattr__" "__setstate__" "__sizeof__" "__str__"
 "__subclasshook__" "_add_inbound_node" "_base_init"
 "_check_trainable_weights_consistency" "_get_node_attribute_at_index"
 "_init_graph_network" "_init_subclassed_network" "_make_predict_function"
 "_make_test_function" "_make_train_function" "_node_key" "_set_inputs"
 "_standardize_user_data" "_updated_config" "_uses_dynamic_learning_phase"
 "add_loss" "add_update" "add_weight" "assert_input_compatibility" "build"
 "call" "compile" "compute_mask" "compute_output_shape" "count_params"
 "evaluate" "evaluate_generator" "fit" "fit_generator" "from_config"
 "get_config" "get_input_at" "get_input_mask_at" "get_input_shape_at"
 "get_layer" "get_losses_for" "get_output_at" "get_output_mask_at"
 "get_output_shape_at" "get_updates_for" "get_weights" "load_weights" "predict"
 "predict_generator" "predict_on_batch" "reset_states" "run_internal_graph"
 "save" "save_weights" "set_weights" "summary" "test_on_batch" "to_json"
 "to_yaml" "train_on_batch")
```
Optionally, see [pymethod](#pymethod).

### chain(*)
`(chain &rest chain)`

This is inspired by the `chain` in parenscript, discussed in [this issue](https://github.com/bendudson/py4cl/issues/4).

In python it is quite common to apply a chain of method calls, data
member access, and indexing operations to an object. To make this work
smoothly in Lisp, there is the `chain` macro (Thanks to @kat-co and
[parenscript](https://common-lisp.net/project/parenscript/reference.html)
for the inspiration). This consists of a target object,
followed by a chain of operations to apply.  For example
```lisp
(chain "hello {0}" (format "world") (capitalize)) ; => "Hello world"
```
which is converted to python `return "hello {0}".format("world").capitalize()`.

`chain` has two variants: `chain` is a macro, and `chain*` is a function.

A few examples are as follows:

```lisp
(chain (slice 3) stop) ; => 3
(let ((format-str "hello {0}")
      (argument "world"))
 (py4cl2:chain* format-str `(format ,argument))) ; => "hello world"
```

Arguments to methods are lisp, since only the top level forms in `chain` are treated specially:
```lisp
CL-USER> (chain (slice 3) stop)
3
CL-USER> (let ((format-str "hello {0}")
               (argument "world"))
           (chain* format-str `(format ,argument)))
"hello world"
CL-USER> (chain* "result: {0}" `(format ,(+ 1 2)))
"result: 3"
CL-USER> (chain (aref "hello" 4))
"o"
CL-USER> (chain (aref "hello" (slice 2 4)))
"ll"
CL-USER> (chain (aref #2A((1 2 3) (4 5 6)) (slice 0 2)))
#2A((1 2 3) (4 5 6))
CL-USER> (chain (aref #2A((1 2 3) (4 5 6))  1 (slice 0 2)))
#(4 5)
CL-USER> (pyexec "class TestClass:
      def doThing(self, value = 42):
        return value")
CL-USER> (chain ("TestClass") ("doThing" :value 31))
31
```

There is also `(setf chain)`:

```lisp
CL-USER> (pyeval
          (with-remote-object (array (np:zeros '(2 2)))
            (setf (chain* `(aref ,array 0 1)) 1.0
                  (chain* `(aref ,array 1 0)) -1.0)
            array))
#2A((0.0 1.0) (-1.0 0.0))
```

Note that this modifies the value in python, so the above example only
works because =array= is a handle to a python object, rather than an
array which is stored in lisp. The following therefore does not work:

```lisp
CL-USER> (let ((array (np:zeros '(2 2))))
           (setf (chain* `(aref ,array 0 1)) 1.0
                 (chain* `(aref ,array 1 0)) -1.0)
           array)
#2A((0.0 0.0) (0.0 0.0))
```

### with-remote-objects(*)
`(with-remote-objects &body body)

If a sequence of python functions and methods are being used to manipulate data,
then data may be passed between python and lisp. This is fine for small amounts
of data, but inefficient for large datasets.

The `with-remote-objects` and `with-remote-objects*` macros provide `unwind-protect` environments
in which all python functions return handles rather than values to lisp. This enables
python functions to be combined without transferring much data.

```lisp
(with-remote-objects (py4cl:python-eval "1+2"))
; => #S(PY4CL::PYTHON-OBJECT :TYPE "<class 'int'>" :HANDLE 0)
```

`with-remote-objects*` evaluates the last result, instead of merely returning a handle

```lisp
(with-remote-objects* (py4cl:python-eval "1+2")) ; => 3
```

The advantage comes when dealing with large arrays or other datasets:
```lisp
CL-USER> (time (let ((arr (make-array 1000000
                                      :element-type 'single-float
                                      :initial-element 2.0)))
                 (np:sum (np:add arr arr))))
;  0.258 seconds of real time
;  8,065,504 bytes consed
4000000.0
CL-USER> (time (with-remote-objects
                 (let ((arr (make-array 1000000
                                        :element-type 'single-float
                                        :initial-element 2.0)))
                   (np:sum (np:add arr arr)))))
;  0.100 seconds of real time
;  4,065,456 bytes consed
4000000.0
```
Note that this requires you to solely use python functions and methods. So, do not expect something like this to work:

```lisp
(with-remote-objects (print (aref (np:ones :shape '(10000000)) 0)))
; Error
```

to work.

Besides this, see [Setting up](#setting-up) for using ram-disk and `numpy-file-format` to
combine lisp and python functions.
.

### python-getattr
`(python-getattr object slot-name)`

Lisp structs and class objects can be passed to python, put into data structures and
returned:

```lisp
(defpyfun "dict") ; Makes python dictionaries

(defstruct test-struct
    x y)

(let ((map (dict :key (make-test-struct :x 1 :y 2))))  ; Make a dictionary, return as hash-map
  ;; Get the struct from the hash-map, and get the Y slot
  (test-struct-y
    (chain* `(aref ,map "key"))))  ; => 2
```

In python this is handled using an object of class `UnknownLispObject`, which
contains a handle. The lisp object is stored in a hash map
`*lisp-objects*`. When the python object is deleted, a message is sent to remove
the object from the hash map.

To enable python to access slots, or call methods on a struct or class, a
handler function needs to be registered. This is done by providing a method
for generic function `python-getattr`. This function will be called when a
python function attempts to access attributes of an object (`__getattr__`
method).

```lisp
;; Define a class with some slots
(defclass test-class ()
  ((value :initarg :value)))

;; Define a method to handle calls from python
(defmethod python-getattr ((object test-class) slot-name)
  (cond
    ((string= slot-name "value") ; data member
      (slot-value object 'value))
    ((string= slot-name "func")  ; method, return a function
      (lambda (arg) (* 2 arg)))
    (t (call-next-method)))) ; Otherwise go to next method

(let ((instance (make-instance 'test-class :value 21)))
  ;; Get the value from the slot, call the method
  ;; python: instance.func(instance.value)
  (chain* `((@ ,instance func) (@ ,instance value))))  ; => 42
```
Inheritance then works as usual with CLOS methods:
```lisp
;; Class inheriting from test-class
(defclass child-class (test-class)
  ((other :initarg :other)))

;; Define method which passes to the next method if slot not recognised
(defmethod py4cl:python-getattr ((object child-class) slot-name)
  (cond
    ((string= slot-name "other")
     (slot-value object 'other))
    (t (call-next-method))))

(let ((object (make-instance 'child-class :value 42 :other 3)))
  (list
    (chain* object 'value) ; Call TEST-CLASS getattr method via CALL-NEXT-METHOD
    (chain* object 'other))) ;=> (42 3)
```

### python-setattr

## Type Mapping and Pythonize

Data is passed between python and lisp as text. The python function
`lispify` converts values to a form which can be read by the lisp
reader; the lisp function `pythonize` outputs strings which can be
`eval`'d in python. The following type conversions are done:

```
| Lisp type               | Python type           |
|-------------------------+-----------------------|
| NIL                     | False                 |
| integer                 | int                   |
| ratio                   | fraction.Fractions    |
| real                    | float                 |
| complex                 | complex float         |
| string                  | str                   |
| hash map                | dict                  |
| list                    | tuple                 |
| unspecialized vector    | list                  |
| (un)specialized array   | NumPy array*          |
| single-float            | numpy.float32         |
| double-float            | float                 |
| symbol                  | Symbol class          |
| function                | function              |
```

\*The currently supported numpy types include: `((un)signed-byte XX)` where XX can be from `(08 16 32 64)`, and arrays of `bit`s. Raise an [issue](https://github.com/digikar99/py4cl2/issues) if you want more types supported or this functionality exposed to the user.

Special conversion rules include:

```
nil     False
t       True
"None"  None
"()"    ()        # empty tuple
```

Because `pyeval` and `pyexec` evaluate strings as python
expressions, strings passed to them are not escaped or converted as
other types are. To pass a string to python as an argument, call `py4cl:pythonize`

```lisp
CL-USER> (py4cl:pythonize "string")
"\"string\""
CL-USER> (py4cl:pythonize #'identity)
"_py4cl_LispCallbackObject(1)"
CL-USER> (py4cl:pythonize 3.0)
"3.0"
CL-USER> (py4cl:pythonize (model)) ;; keras.Model
"_py4cl_objects[1918]"
```

If python objects cannot be converted into a lisp value, then they are
stored and a handle is returned to lisp.

### Customizing Type-Mapping

> Unstable feature

Since version 2.8.0, values returned from the python process are wrapped inside a call to `py4cl2::customize`. This function essentially does the following:

```lisp
(defun customize (object)
  (loop :for (type . lispifier) :in *lispifiers*
        :if (typep object type)
          :do (return-from customize (funcall lispifier object)))
  object)
```

`with-lispifiers` provides a convenient wrapper to bind the dynamic variable `*lispifiers*` for executing its `body`.

## Name Mapping

The arguments passed to `pycall` are parsed as follows: the lisp keywords are converted to their python equivalents. This only entails downcasing the symbol-name of the keywords and replacing hyphens with underscores. If the symbol-name contained capital letters, then, if all the letters are capitals, the symbol-name is downcased; else it stays as it is

```lisp
CL-USER> (pyexec "
def foo(A, b):
  return True")
CL-USER> (pycall 'foo :*A* 4 :b 3)
T
CL-USER> (pycall 'foo :a 4 :b 3)
; Evaluation aborted on #<PYERROR {100E2AF473}>.
;; unexpected keyword argument 'a'
CL-USER> (pycall 'foo 4 3)
T
```
Lispfication of python names is done by `defpyfun`, in import-export.lisp. Both `CamelCase` and `joint_words` are converted to `camel-case` and `joint-words`; the actual names of the arguments are substituted:

```lisp
CL-USER> (macroexpand-1 '(defpyfun "foo"))
(DEFUN FOO (&KEY (A 'NIL) (B 'NIL))
  "None"
  NIL
  (PYTHON-START-IF-NOT-ALIVE)
  (RAW-PYEVAL "foo" "(" "A" "=" (PY4CL2::PYTHONIZE A) "," "b" "="
              (PY4CL2::PYTHONIZE B) "," ")"))
T
```

The format of the calling expression does depend on the signature of the function.

## What remains?

Feel free to create an [Issue on Github](https://github.com/digikar99/py4cl2/issues).

### Future Work

In no order of priority:

- adding/documenting proper multithreaded support
- [ABANDON since python2 has reached end-of-life] finding equivalent of inspect._empty in python2 (unable to google)
- importing python classes, and methods, may be, as subclasses
  of 'python-object; to be able to use make-instance and slot-value
  might require knowledge of MOP, to make python-object at the same level
  as standard-object
- should return value of defpyfun matter - so as to indicate success or failure?
  failure is anyways indicated by errors
- ability to define customized arg-lists, documentation, and calling methods
  for functions: this can serve as a community project to cover up some
  naming and arg-list idiosyncrasies
- cleaning up documentation while defining functions - many python functions
  have documentation intended for use directly in md/rst files

## Also check out

### [The Common Lisp Cookbook](http://lispcookbook.github.io/cl-cookbook/)

[tCLC]: https://github.com/LispCookbook/cl-cookbook
[pyeval]: #expressions-pyeval-rest-args
[limitations]: #limitations-of-this-documentation
[pycall]: #pycall
[Name Mapping]: #name-mapping
[bendudson/py4cl]: https://github.com/bendudson/py4cl

gha_language: Common Lisp

gha_license_id: NOASSERTION


text:
# Connectwise::ProjectsApi

All URIs are relative to *https://api-na.myconnectwise.net/v4_6_release/apis/3.0*

Method | HTTP request | Description
------------- | ------------- | -------------
[**project_projects_count_get**](ProjectsApi.md#project_projects_count_get) | **GET** /project/projects/count |
[**project_projects_get**](ProjectsApi.md#project_projects_get) | **GET** /project/projects |
[**project_projects_id_delete**](ProjectsApi.md#project_projects_id_delete) | **DELETE** /project/projects/{id} |
[**project_projects_id_get**](ProjectsApi.md#project_projects_id_get) | **GET** /project/projects/{id} |
[**project_projects_id_patch**](ProjectsApi.md#project_projects_id_patch) | **PATCH** /project/projects/{id} |
[**project_projects_id_put**](ProjectsApi.md#project_projects_id_put) | **PUT** /project/projects/{id} |
[**project_projects_post**](ProjectsApi.md#project_projects_post) | **POST** /project/projects |

# **project_projects_count_get**
> Count project_projects_count_get(opts)

Get Projects Count

### Example
```ruby
# load the gem
require 'connectwise-ruby-sdk'
# setup authorization
Connectwise.configure do |config|
  # Configure HTTP basic authorization: BasicAuth
  config.username = 'YOUR USERNAME'
  config.password = 'YOUR PASSWORD'
end

api_instance = Connectwise::ProjectsApi.new

opts = {
  conditions: "conditions_example" # String |
}

begin
  result = api_instance.project_projects_count_get(opts)
  p result
rescue Connectwise::ApiError => e
  puts "Exception when calling ProjectsApi->project_projects_count_get: #{e}"
end
```

### Parameters

Name | Type | Description  | Notes
------------- | ------------- | ------------- | -------------
 **conditions** | **String**|  | [optional]

### Return type

[**Count**](Count.md)

### Authorization

[BasicAuth](../README.md#BasicAuth)

### HTTP request headers

 - **Content-Type**: Not defined
 - **Accept**: application/json

# **project_projects_get**
> Array<Project> project_projects_get(opts)

Get Projects

### Example
```ruby
# load the gem
require 'connectwise-ruby-sdk'
# setup authorization
Connectwise.configure do |config|
  # Configure HTTP basic authorization: BasicAuth
  config.username = 'YOUR USERNAME'
  config.password = 'YOUR PASSWORD'
end

api_instance = Connectwise::ProjectsApi.new

opts = {
  conditions: "conditions_example" # String |
  order_by: "order_by_example", # String |
  page: 56, # Integer |
  page_size: 56 # Integer |
}

begin
  result = api_instance.project_projects_get(opts)
  p result
rescue Connectwise::ApiError => e
  puts "Exception when calling ProjectsApi->project_projects_get: #{e}"
end
```

### Parameters

Name | Type | Description  | Notes
------------- | ------------- | ------------- | -------------
 **conditions** | **String**|  | [optional]
 **order_by** | **String**|  | [optional]
 **page** | **Integer**|  | [optional]
 **page_size** | **Integer**|  | [optional]

### Return type

[**Array<Project>**](Project.md)

### Authorization

[BasicAuth](../README.md#BasicAuth)

### HTTP request headers

 - **Content-Type**: Not defined
 - **Accept**: application/json

# **project_projects_id_delete**
> project_projects_id_delete(id)

Delete Project By Id

### Example
```ruby
# load the gem
require 'connectwise-ruby-sdk'
# setup authorization
Connectwise.configure do |config|
  # Configure HTTP basic authorization: BasicAuth
  config.username = 'YOUR USERNAME'
  config.password = 'YOUR PASSWORD'
end

api_instance = Connectwise::ProjectsApi.new

id = 56 # Integer |

begin
  api_instance.project_projects_id_delete(id)
rescue Connectwise::ApiError => e
  puts "Exception when calling ProjectsApi->project_projects_id_delete: #{e}"
end
```

### Parameters

Name | Type | Description  | Notes
------------- | ------------- | ------------- | -------------
 **id** | **Integer**|  |

### Return type

nil (empty response body)

### Authorization

[BasicAuth](../README.md#BasicAuth)

### HTTP request headers

 - **Content-Type**: Not defined
 - **Accept**: Not defined

# **project_projects_id_get**
> Project project_projects_id_get(id)

Get Project By Id

### Example
```ruby
# load the gem
require 'connectwise-ruby-sdk'
# setup authorization
Connectwise.configure do |config|
  # Configure HTTP basic authorization: BasicAuth
  config.username = 'YOUR USERNAME'
  config.password = 'YOUR PASSWORD'
end

api_instance = Connectwise::ProjectsApi.new

id = 56 # Integer |

begin
  result = api_instance.project_projects_id_get(id)
  p result
rescue Connectwise::ApiError => e
  puts "Exception when calling ProjectsApi->project_projects_id_get: #{e}"
end
```

### Parameters

Name | Type | Description  | Notes
------------- | ------------- | ------------- | -------------
 **id** | **Integer**|  |

### Return type

[**Project**](Project.md)

### Authorization

[BasicAuth](../README.md#BasicAuth)

### HTTP request headers

 - **Content-Type**: Not defined
 - **Accept**: application/json

# **project_projects_id_patch**
> Project project_projects_id_patch(id, operations)

Update Project

### Example
```ruby
# load the gem
require 'connectwise-ruby-sdk'
# setup authorization
Connectwise.configure do |config|
  # Configure HTTP basic authorization: BasicAuth
  config.username = 'YOUR USERNAME'
  config.password = 'YOUR PASSWORD'
end

api_instance = Connectwise::ProjectsApi.new

id = 56 # Integer |

operations = [Connectwise::PatchOperation.new] # Array<PatchOperation> |

begin
  result = api_instance.project_projects_id_patch(id, operations)
  p result
rescue Connectwise::ApiError => e
  puts "Exception when calling ProjectsApi->project_projects_id_patch: #{e}"
end
```

### Parameters

Name | Type | Description  | Notes
------------- | ------------- | ------------- | -------------
 **id** | **Integer**|  |
 **operations** | [**Array<PatchOperation>**](PatchOperation.md)|  |

### Return type

[**Project**](Project.md)

### Authorization

[BasicAuth](../README.md#BasicAuth)

### HTTP request headers

 - **Content-Type**: application/json
 - **Accept**: application/json

# **project_projects_id_put**
> Project project_projects_id_put(id, project)

Replace Project

### Example
```ruby
# load the gem
require 'connectwise-ruby-sdk'
# setup authorization
Connectwise.configure do |config|
  # Configure HTTP basic authorization: BasicAuth
  config.username = 'YOUR USERNAME'
  config.password = 'YOUR PASSWORD'
end

api_instance = Connectwise::ProjectsApi.new

id = 56 # Integer |

project = Connectwise::Project.new # Project |

begin
  result = api_instance.project_projects_id_put(id, project)
  p result
rescue Connectwise::ApiError => e
  puts "Exception when calling ProjectsApi->project_projects_id_put: #{e}"
end
```

### Parameters

Name | Type | Description  | Notes
------------- | ------------- | ------------- | -------------
 **id** | **Integer**|  |
 **project** | [**Project**](Project.md)|  |

### Return type

[**Project**](Project.md)

### Authorization

[BasicAuth](../README.md#BasicAuth)

### HTTP request headers

 - **Content-Type**: application/json
 - **Accept**: application/json

# **project_projects_post**
> Project project_projects_post(project)

Create Project

### Example
```ruby
# load the gem
require 'connectwise-ruby-sdk'
# setup authorization
Connectwise.configure do |config|
  # Configure HTTP basic authorization: BasicAuth
  config.username = 'YOUR USERNAME'
  config.password = 'YOUR PASSWORD'
end

api_instance = Connectwise::ProjectsApi.new

project = Connectwise::Project.new # Project |

begin
  result = api_instance.project_projects_post(project)
  p result
rescue Connectwise::ApiError => e
  puts "Exception when calling ProjectsApi->project_projects_post: #{e}"
end
```

### Parameters

Name | Type | Description  | Notes
------------- | ------------- | ------------- | -------------
 **project** | [**Project**](Project.md)|  |

### Return type

[**Project**](Project.md)

### Authorization

[BasicAuth](../README.md#BasicAuth)

### HTTP request headers

 - **Content-Type**: application/json
 - **Accept**: application/json

repository: jordanbyron/connectwise-ruby-sdk

repo_name: jordanbyron/connectwise-ruby-sdk


text:
---
templateKey: move-page
title: It was spring when I last wrote to you
date: "2020-03-31T07:00:00.000Z"
mainImage: /assets/L1210863_JPG.jpg
---
Inspired by the clotheslines in East Vancouver, *It was Spring When I Last Wrote to You* investigates notions of displacement and memory. The written component of this work takes form as a diasporic poem, one in which thoughts were given to subjects of interest in spontaneous manners. Language acts as the distorting mirror: words lose and regain parts of their meaning in the process of translation. In exploring the relationship between rememberance and lost, this work can be seen as an effort of preservation and an act of protection of thoughts in their formation.

Credits:

Artist: Xinyue Liu

Videographer: Xinyue Liu

Photographer: Jennifer Tham

Editor: Xinyue Liu

![](/assets/L1210863_JPG.jpg)

![](/assets/L1210857_JPG.jpg)

![](/assets/L1210850_JPG.jpg)

![](/assets/L12108.jpg)

`oembed: https://vimeo.com/626828096/2d04e7c288`

repository: casperleerink/liuxinyue

repo_name: casperleerink/liuxinyue


text:
[![Build Status](https://travis-ci.com/DataDog/jmxfetch.png?branch=master)](https://travis-ci.com/DataDog/jmxfetch)

# [Change log](https://github.com/DataDog/jmxfetch/blob/master/CHANGELOG.md)

# JMXFetch

JMXFetch is the new tool to collect metrics from JMX Servers in order to be sent to Datadog (http://www.datadoghq.com)
It is called by the Datadog Agent (https://github.com/Datadog/datadog-agent) and sends metrics back to the Agent using the [Java `dogstatsd` library](https://github.com/datadog/java-dogstatsd-client).

# How to contribute code?

First of all and most importantly, **thank you** for sharing.

If you want to submit code, please fork this repository and submit pull requests against the `master` branch.

Please note that the Agent is licensed for simplicity's sake
under a simplified BSD license, as indicated in the `LICENSE` file.
Exceptions are marked with LICENSE-xxx where xxx is the component name.
If you do **not** agree with the licensing terms and wish to contribute code nonetheless,
please email us at<EMAIL_ADDRESS>before submitting your
pull request.

# Building from source

JMXFetch uses [Maven](http://maven.apache.org) for its build system.

In order to generate the jar artifact, simply run the ```mvn clean compile assembly:single``` command in the cloned directory.

The distribution will be created under ```target/```.

Once the jar is created, you can update the one in the Datadog Agent repo.

# Coding standards

JMXFetch uses [Checkstyle](http://checkstyle.sourceforge.net/) with [Google Java Style](http://google.github.io/styleguide/javaguide.html) to enforce coding standards.

To perform a `Checkstyle` analysis and outputs violations, run:
```
mvn checkstyle::check
```

`Checkstyle` analysis is automatically executed prior to compiling the code, testing.

# Generated code

JMXFetch uses [Lombok](https://projectlombok.org/) to modify classes and generate additional code at runtime.
You may need to [enable annotation processors](https://projectlombok.org/setup/overview) to compile in your IDE.

# Testing

To run unit test, issue the following command:
```
mvn test
```

# To run:
```
Get help on usage:
java -jar jmxfetch-0.33.0-jar-with-dependencies.jar --help
```


text:
[![License](https://img.shields.io/badge/license-Apache--2.0-brightgreen.svg)](LICENSE)

# http4s-gradle-template

`http4s-gradle-template` is a starter template for [http4s] with [Gradle] build system.

## Prerequisites

The only prerequisites is a Java 8+ SDK in path. Gradle build tool will be downloaded and setup on first run.

### sdkman

On macOS or Linux, it is recommended to use [sdkman] to manage the underlying Java SDK version used.

  1. Run `sdk env` on the project root to configure the Java SDK version

_Note: This repo uses Eclipse OpenJ9 Java distribution by default (as defined in `.sdkmanrc`)_

## Setup Steps

### Development mode via Gradle

  1. Run `./gradlew run` to start the application in development mode

Now you can visit it on [`localhost:8080`](http://localhost:8080) from your browser.

## Code Formatting

We follow [Google Java styleguide] for Java code formatting and style, and custom Scalafmt rule for Scala as found in
`.scalafmt.conf`.

  - Import the relevant configuration to your favourite IDE to auto-apply formatting during development time, or
  - Run `spotlessCheck` and `spotlessApply` prior to committing your code to apply auto-formatting

Scalafmt does not enforce import formatting order, so these rules should be manually-applied in the IDE.

## License

```
    Copyright (c) 2020 Herdy Handoko

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
```

`http4s-gradle-template` is released under the Apache Version 2.0 License. See the [LICENSE] file for further details.

[Google Java styleguide]: https://google.github.io/styleguide/javaguide.html
[Gradle]: https://gradle.org/
[http4s]: https://http4s.org/
[LICENSE]: https://github.com/hhandoko/http4s-gradle-template/blob/master/LICENSE.txt
[sdkman]: https://sdkman.io/