text:
---
# Title, summary, and page position.
linktitle: Chapter 5
summary: CT Chapter 5
weight: 1
icon: book
icon_pack: fas

# Page metadata.
title: Chapter 5
date: "2018-09-09T00:00:00Z"
type: book  # Do not modify.
---

## Pseudoscience: Why Study It?
**Pseudoscience** makes false claims and masquerades as real science.

Pseudoscience can have dangerous outcomes.

### Pseudoscience Is Dangerous
In 2000, Candace Newmaker was having trouble adjusting to her adoptive mother; she was having behavioral problems.

Two unlicensed social workers, Julie Ponder and Connell Watkins, treated Candace with attachment therapy.

The Outcome: Candace was forced to try to slide through a blanket wrapped around her to simulate birth. She cried, vomited, urinated, and said she couldn't breathe. After about an hour of this ordeal, she died of suffocation.

#### Attachment Therapy Assumptions
Candice's caregivers believed that having her go through a simulation of the birthing process would attach her to her new caregiver.

These are *unwarranted assumptions*, ones not supported by evidence.

#### What Are the Ethical Implications?
The APA ethical guidelines say psychologists should do no harm.

They should use practices that are effective and not use pseudoscientific and ineffective ones.

#### Attachment Therapy as Thinking Error
People who believe in attachment therapy are inappropriately using reasoning by representativeness or *"like goes with like."*

They think that a person who is not attached should go through something that looks like birthing to become attached.

#### Attachment Therapy Is Pseudoscience
**"Pseudo"** means false: It looks like science, but it is not really science.

Pseudoscientific practices do not follow the rules of good science.

Scientific research has not shown attachment therapy to be effective, but its practitioners still claim it is.

## Why Did the Romans See Libra?
[Romans saw Libra in the stars](https://www.space.com/21597-libra-constellation.html).

Their culture probably influenced what they saw from their myths.

Libras are thought to be balanced, intelligent, and diplomatic, but gullible and indecisive.

Psychologically, the identification of Libra shows **pareidolia:** the influence of knowledge and expectation on perception.

## Assumptions of Astrology
The pattern of stars corresponding to the time of your birth determines the traits you have and the course of your life.

Astrologers can use this information to make predictions about your life and offer guidance.

The astrological predictions in horoscopes are so general that they would be hard to test objectively in a specific context.

The general predictions in horoscopes could be easily explained away when they fail.

Example Horoscope:
*It is important to you that people like you and that they admire you for who you are.  While people may perceive you as confident of yourself on the outside, on the inside you are somewhat insecure. At times, you try very hard to reach your goals, but you have much unused potential. Changes and events are coming up in the near future that will present unique opportunities for you. Because of your personality characteristics, it is important that you watch for these opportunities so that you will not miss them. *

### Barnum Effect
People tend to accept general personality descriptions, but they are not predictive.

This uncritical tendency of people to accept general descriptions that do not really describe them has been termed the **"Barnum effect"** after the circus entrepreneur's expression, "We've got something for everyone" (Meehl, 1956).

### Checking Outcomes
Astrologers do not systematically check the outcomes of their predictions.

Astrologers tend to pay more attention to evidence supporting their predictions, while ignoring their failures.

### General Rules of Reasoning
Astrologers incorrectly use general rules of reasoning to evaluate claims and hypotheses.

They often use logical criteria inappropriately, such as when they say, *"Science has not been able to disprove astrology,"* to reverse the burden of proof.

They fail to reject their theory when scientific research has not supported astrological predictions.

## Implausible Claims
**Scientific plausibility** is how *reasonable* we judge a claim to be, given other things we know in science.

### Obscure Terminology
Astrologers use obscure terms, such as "sun signs," "the seventh house," "horoscopes," and "zodiac."

Astronomers, physicists, psychologists, and other scientists do not use these terms in their theories.

### Could physics or astronomy explain astrology?
Is there something special about the light from certain stars, planets, and the moon that might affect the human body at the time of one's birth?

**No**, light is light. The light from one star or planet at a particular time is not much different from other patterns of light.

**Astrology is implausible**

## Alchemy
**Alchemy** is a mystical approach to combining substances or transmuting them into gold.

Since alchemists discovered many principles that later informed chemistry, it can be considered a "proto-science."

## Mesmerism
**Mesmerism** resembles the modern technique of hypnosis.

Mesmer would tell patients that he had magnetized water, and some patients fainted.

Through an investigation on mesmerism, some scientific principles were first developed.

### Investigation of Mesmerism
**Placebo control:** Researchers told subjects they had magnetized water through mesmerism but they hadn't; even so, people said they felt the effects.

**Blind testing:** Without telling subjects, researcher magnetized some water samples but not others; subjects could not tell which was which.

## Modern Pseudoscience
Modern science is often highly technical and requires an understanding of technology.

Pseudoscience goes through the motions of scientific practices without the technology of science.

## Parapsychology
**Paranormal** refers to phenomena that seem to defy scientific explanation.

**Parapsychology** is the supposedly scientific study of the paranormal.

### Parapsychology as Pseudoscience
Psychic predictions are vague and general. Often, they are supported by low-quality evidence such as personal experience and anecdotes.

Post hoc explanations try to explain away negative findings. This strategy makes parapsychology unfalsifiable.

Some believers engage in reversing the burden of proof, and arguing from possibility.

Many studies have failed to support the existence of ESP, but many parapsychologists continue to believe in it anyway.

Parapsychology is inconsistent with physics and scientific study of perception.

It is often supported by low-quality evidence and not supported by high-quality scientific research.

## Evidence-Based Treatments
**Evidence-based treatments (EBTs)** are treatments for psychological problems whose effectiveness is validated through high-quality scientific research.
Behaviorism took a careful, systematic, often experimental approach to observing and modifying behavior, and in developing effective treatments such as systematic desensitization to treat phobias.

### Scientist-Practitioner Model
**Scientist-practitioner:** Clinicians should be good scientists.

They should be trained to think like a scientist and engage in scientific practices.

### Efficacy Research
**Efficacy research:** Clinicians should do high-quality research to discover which psychotherapies are the most effective for treating a problem. Then clinicians should use these effective therapies.

### Randomized-Trial Experiment
Experimenters randomly assign clients with a certain psychological disorder to an experimental therapy and a control condition.

Comparing the two groups, experimenters can see that the observed effect was due to the treatment.

### Placebos
**Placebo control group:** People receive something that looks like a real therapy to control for the expectancy of getting a treatment.

**Placebo effect:** People report feeling better when they receive what looks like real treatment.

### Wait List
**Wait list control group:** Participants are told they need to wait to get a treatment. At the same time as the treatment group, the wait list control group is tested before and after therapy.

This controls for spontaneous remission, or patients getting better because time has passed without treatment.

## Is Freudian Psychoanalysis Pseudoscientific?
Adler showed that Freud's ideas were not falsifiable. Also, the theory of the unconscious motives is hard to test.

Freud was very resistant to criticism of his theory and may have shown a confirmatory bias in interpreting dreams and cases.

Freudian psychoanalysis has not been revised, though it has been shown to be less effective than other approaches.

Freud used low-quality evidence such as case studies of poor quality. Very little experimentation was done on the effectiveness of psychoanalysis.

## Scientology
Though it pretends to be scientific, Scientology does not systematically test the outcomes of its predictions.

It lacks connection to other sciences.

It is implausible; Scientology is based on science fiction myths.

Scientology is supported by low-quality evidence such as poorly documented cases and statements of celebrities, such as Tom Cruise, who know little about science.

Scientology uses unconventional terms, such as referring to counselors as "auditors."

## Power Therapies
**Thought Field Therapy** claims that tapping at specific points on the head can release blocked energy that causes psychological problems.

It boasts a very high success rate for many different kinds of disorders.

It claims it can be effective in just one or two treatment sessions.

These claims make it implausible.

## Self-Help Books
A market survey showed that the people who were most likely to buy a self-help book were the people who had bought such a book in the last 18 months.

There is not much research about self-help, and the research results that do exist are mixed.

For these reasons, it is impossible to tell if self-help books are actually helpful.

### Positive Thinking
Many self-help techniques were created around positive thinking.

One such approach, *The Secret*, claimed that life is governed by the **law of attraction**, meaning that people who think positive thoughts will attract positive outcomes.

#### The Secret
James Arthur Ray, a proponent of The Secret, had followers go through a sweat lodge ceremony to help them avoid fear of death.

One such ceremony resulted in 18 people being hospitalized and 3 people dying from being denied water. Ray was convicted of three counts of negligent homicide.

## Alternative Medicine
**Alternative medicine** uses natural remedies that have been unchanged for centuries.

It is mostly untested in a rigorous fashion and unregulated in the United States.

These medicines often claim to be clinically proven, but have been only minimally tested.

## Magnet Therapy
One alternative medicine, known as **magnet therapy**, claims that magnets placed near the body can reduce pain, promote well-being, and even cure cancer.

Research has shown that magnets on the body have no effect.

Experiments comparing magnet treatments to placebos have not shown that the magnets have clear benefits.


text:
# MNIST Beaker Example

This is an example of how to train a Pytorch MNIST model in Beaker.

The mnist data is current already available on Beaker under `marc/mnist`.

## Vanilla usage:

1. install pytorch and torchvision
2. set the python path:

```bash
export PYTHONPATH=.
```

3. download the four MNIST files from [Yann Lecun's website](http://yann.lecun.com/exdb/mnist/) and put them somewhere
4. run the main file

```bash
python beaker_pytorch/main.py \
    --data-dir /path/to/data \
    --output-dir /tmp/output \
    --epochs 10
```

## Docker usage:

1. build the docker image

```bash
docker build -t beaker_pytorch .
```

2. Download the MNIST data, as above
3. run the docker image mounting the data and output directories

```bash
docker run -t \
    -v /local/path/to/data:/data:ro \
    -v /local/path/to/output:/output:rw \
    beaker_pytorch \
    python beaker_pytorch/main.py \
        --data-dir /data \
        --output-dir /output \
        --epochs 10
```

## Beaker usage

1. [Install Beaker](https://github.com/allenai/beaker/wiki/Getting-Started)
2. You can choose to download the MNIST data above and create a new dataset or use the existing MNIST dataset named
`mnist.1` located [here](http://beaker.allenai.org/ds/ds_siigqzxt4ctd)
3. You can either rebuild and push the docker image above or use the existing docker image already avaliable at
`896129387501.dkr.ecr.us-west-2.amazonaws.com/beaker-experiment-playground:mnist.v1`

If you chose to rebuild use
```bash
beaker blueprint create -n "beaker_pytorch" --addr="beaker.allenai.org" beaker_pytorch
```
to create a blueprint.

4.

branch_name: refs/heads/master

extension: md

gha_language: Python

license_type: permissive


text:
# SwiftHandlerKit
Super lightweight library to assign taggable, closure-based actions to UIControls.

[![CI Status](http://img.shields.io/travis/daaavid/SwiftHandlerKit.svg?style=flat)](https://travis-ci.org/daaavid/SwiftHandlerKit)
[![Version](https://img.shields.io/cocoapods/v/SwiftHandlerKit.svg?style=flat)](http://cocoapods.org/pods/SwiftHandlerKit)
[![License](https://img.shields.io/cocoapods/l/SwiftHandlerKit.svg?style=flat)](http://cocoapods.org/pods/SwiftHandlerKit)
[![Platform](https://img.shields.io/cocoapods/p/SwiftHandlerKit.svg?style=flat)](http://cocoapods.org/pods/SwiftHandlerKit)

## Usage

Just use the fuction `.on`, followed by the event on any UIControl to assign an action for that event.

```swift
textField.on(.editingChanged) { textField in
  // no need to cast as UITextField
  print("editingChanged", textField.text!)
}
```

```swift
button.on(.touchUpInside, .touchUpOutside) { button in
  //multiple events
  UIView.animate(withDuration: 0.15) {
    button.transform = .identity
  }
}
```

The `.on` function returns an `EventHandler` object that contains your action. You can add a `tag` to this EventHandler to identify it.

```swift
let touchUpEventHandler = button.on(.touchUpInside, .touchUpOutside) { button in
  print(button)
}

touchUpEventHandler.tag = "buttonTouchUp"

// if you want, you could also do something like this

button.on(.touchDown) { button in
  print(button)
}.tag = "touchDown"

```

You can find these EventHandlers later by accessing the `eventHandlers` property (it's a Set) on the ui element you assigned the EventHandler to. You can `subcript` this set with a `tag` to find specific event handlers.

```swift
if let touchUpEventHandler = button.eventHandlers["buttonTouchUp"] {
  button.eventHandlers.remove(touchUpEventHandler)
}
```

There's also some support thrown in for UIBarButtonItems. All of the stock UIBarButtonItem inits are now available as closure-based inits.

```swift
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Back") { barButtonItem in
  print("leftBarButtonItemWasPressed")
}
```

You can create UIGestureRecognizers like this as well!

```swift
UITapGestureRecognizer { tap in
  print(tap)
}.add(to: view)
```

Take a peek into `SwiftHandlerKit.swift` if you want to know more about how it works. It's very short and pretty simple! :^)

## Example

To run the example project, clone the repo, and run `pod install` from the Example directory first.

## Requirements

## Installation

SwiftHandlerKit is available through [CocoaPods](http://cocoapods.org). To install
it, simply add the following line to your Podfile:

```ruby
pod 'SwiftHandlerKit'
```

If you get some sort of spec error, try `pod repo update` or:

```ruby
pod 'SwiftHandlerKit', :git => 'https://github.com/daaavid/SwiftHandlerKit.git', :branch => 'master'
```

## Author

daaavid<EMAIL_ADDRESS>
## License

SwiftHandlerKit is available under the MIT license. See the LICENSE file for more info.

license: MIT

repository: daaavid/SwiftHandlerKit

repo_name: daaavid/SwiftHandlerKit


text:
# My Notes:

## I
Get encryption key from decompiling teh android app
    iGrill:
    encryption_key = [-19, 94, 48, -114, -117, -52, -111, 19, 48, 108, -44, 104, 84, 21, 62, -35]
    iGrill v2:
    encryption_key = [-33, 51, -32, -119, -12, 72, 78, 115, -110, -44, -49, -71, 70, -25, -123, -74]

## II
Be careful on the bluez version 5.29

## III
Use bluetoothctl trust command on iGrill device.

## IV - install components
On a fresh Raspberry Pi Install, I performed the following to get this code to work - Minus the database portion.

Install bluez using these instructions. Install version 5.29 instead of the version listed.

https://learn.adafruit.com/install-bluez-on-the-raspberry-pi/installation
a. Download - wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.29.tar.xz
b. Extract - tar xvf bluez-5.29.tar.xz
c. Browse - cd bluez-5.29
d. sudo apt-get update
e. sudo apt-get install -y libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev
f. ./configure
g. make
h. sudo make install
i. bluetoothctl -v

After bluez is installed, source installed bluepy0.9.11.

a. Download - wget https://github.com/IanHarvey/bluepy/tarball/v/0.9.11.tar.xz
b. Extract - tar xvf 0.9.11
c. Browse - cd 0.9.11
d. sudo python setup.py build
e. sudo python setup.py install

Note: If you try to install bluepy0.9.11 before installing bluez, the install will error out.

## V - install components
apt-get install python-pip libglib2.0-dev
pip install bluepy
apt-get install python-crypto
pip install influxdb
apt-get install bluez-hcidump

## VI - connects and prints characteristics of igrillv2
import bluepy.btle as btle
import random

encryption_key = [-33, 51, -32, -119, -12, 72, 78, 115, -110, -44, -49, -71, 70, -25, -123, -74]

address = "12:34:56:78:90:12"

igrill = btle.Peripheral(address)
print "Attached"

igrill.setSecurityLevel("medium")
print "raised security level"

for charas in igrill.getCharacteristics() :
 print charas

key = "".join([chr((256 + x) % 256) for x in encryption_key])
challenge = str(bytearray([(random.randint(0, 255)) for i in range(8)] + [0] * 8))

app_uuid = igrill.getCharacteristics(uuid="64ac0002-4a4b-4b58-9f37-94d3c52ffdf7")[0]
app_uuid.write(challenge, True)

## VII - specific issues a lot of information
https://github.com/kvantetore/igrill/issues/4

## VIII - different fork
https://github.com/bjoernhoefer/igrill


text:
# this is a work in progress!

# Peter Bartels Blog

*Kick off your blog with this repository, feel free to use it for your own.*

## Description

Creates a static website that can be hosted in a serverless architecture using a headless CMS (Gatsby)

***Stack***

- Gatsbyjs
  - graphql
  - image processing
  - mdx
  - font loader / icons
  - helmet
  - typescript
  - Styled components
  - Rebassjs
  - functional typescript eslint rules
- sanity.io (for content editing)

- **Page content layout is stored in MDX (JSX+markdown) files**
- **Content/blog is stored at https://sanity.io (free account for small websites)**

# 🚀 Quick start

To start developing:

`yarn start`

or

`gatsby develop`

To edit content such as your personal information, resume, projects, educaction etc.

`cd sanity`

`yarn start`

or

`sanity start`

Currently my personal sanity information is configured, this is **public** so it will work

For your own account change the following file with your own projectId:

`gatsby-config.js`

```js
{
resolve: 'gatsby-source-sanity',
  options: {
    projectId: 'xw24a3gm',
    dataset: 'production',

    // currenyly this is a public dataset
    // if you have a private dataset
    // token: process.env.MY_SANITY_TOKEN,
  }
}
```

# Deploy:

`sanity deploy` deploy content

`gatsby deploy` generate a static site for deployment

repository: peterbartels/peterbartels-blog

gha_language: TypeScript

gha_license_id: MIT

repo_name: peterbartels/peterbartels-blog


text:
---
name: Unstar a gist
example: octokit.rest.gists.unstar({ gist_id })
route: DELETE /gists/{gist_id}/star
scope: gists
type: API method
---

# Unstar a gist

```js
octokit.rest.gists.unstar({
  gist_id,
});
```

## Parameters

      name
      required
      description

gist_id	yes

The unique identifier of the gist.

See also: [GitHub Developer Guide documentation](https://docs.github.com/rest/reference/gists#unstar-a-gist).

branch_name: refs/heads/main


text:
XTi Flowable Modeler Maven Plugin
=================================

Working with Flowable BPM in a Java project?  Then you've probably found yourself downloading changed models to your codebase over and over again.
This Flowable Maven plugin that allows for easy integration of Flowable Modelering in your development cycle.
It takes a Java + Spring Boot setup as default configuration, as this is the most common habitat of an embedded Flowable BPM implementation

### Plugin Features

Automate the **download of all your models** to your maven project (Spring Boot layout as default).
This allows you to edit your models in a Flowable Modeler instance, and get the BPMN, CMMN, DMN and FORM files in your codebase so you can commit them in your SCM.
No more need for the Download button in Flowable modeler.

**Upload existing model files** to a Flowable Modeler instance.
This makes it easy to load all relevant models of your current development branch in a (temporary) Flowable Modeler instance and do model updates as required

### Status: PRE-ALPHA

NOTE: The current plugin is a very early (and very drafty) implementation - use at own risk.  Always backup your models!

## Prerequisites

### Make sure you have Flowable Modeler running.

The default configuration of the plugin assumes that your Flowable Modeler is running at *http://localhost:8080/* (http://localhost:8080/flowable-modeler), and assumes an *admin* user with password *test* to exist.

The easiest way to hande this is to start the all-in-one docker image maintained by the Flowable project:

	docker run -p 8080:8080 flowable/all-in-one

### Add the maven repository containing the plugin to your Maven project

Add the XTi maven plugin repositories to your project's *pom.xml*:

NOTE: There currently isn't a *release*, so you'll have to work with the *snapshot* repository for now.

```xml
	<pluginRepositories>
		  <pluginRepository>
			<id>io.cloudrepo.xti.opensource</id>
			<url>https://xti.mycloudrepo.io/public/repositories/opensource</url>
			<releases>
				<enabled>true</enabled>
	         	</releases>
			<snapshots>
				<enabled>true</enabled>
				<updatePolicy>always</updatePolicy>
			</snapshots>
		</pluginRepository>
	</pluginRepositories>
```

### Enabling the plugin in your project

Configure your project to use the plugin by adding it to your *pom.xml*.

```xml
<build>
	<plugins>

		<plugin>
			<groupId>com.xti.flowable</groupId>
			<artifactId>flowable-modeler-maven-plugin</artifactId>
			<version>0.0.1-SNAPSHOT</version>
        </plugin>

    </plugins>
</build>
```

This allows you to download the plugin and then use it from the command line (see further)

### (Optional) facilitate easier commandline usage

If you're planning to use the plugin only from the commandline, you'll need complete statements like

	mvn com.xti.flowable:flowable-modeler-maven-plugin:0.0.1-SNAPSHOT:download-models

You can make this shorthand work

	mvn flowable-modeler:download-models

By adding the following to your *~/.m2/settings.xml* file:

```xml
	<pluginGroups>
		<pluginGroup>com.xti.flowable</pluginGroup>
	</pluginGroups>
```

### Integrating plugin execution in your builds

If you want your models to be downloaded automatically with each build, during the *generate-resources* phase, you can elaborate the configuration with an execution:

```xml
<build>
	<plugins>

		<plugin>
			<groupId>com.xti.flowable</groupId>
			<artifactId>flowable-modeler-maven-plugin</artifactId>
			<version>0.0.1-SNAPSHOT</version>
			<executions>
				<execution>
					<id>execution-upon-generate-resources</id>
					<phase>generate-resources</phase>
					<goals>
						<goal>download-models</goal>
					</goals>
		          </execution>
			</executions>
        </plugin>

    </plugins>
</build>
```

## Configuring the plugin

If you don't want to use the default settings, you can pass the necessary parameters to the plugin.

As a reference, a full default configuration example can be found underneath.
As all these values are the defaults, it's no use copying them in your pom.xml if you don't need to set them.

You can also use *-D<name>=<value>* on the command prompt if you wish, or externalise them to *settings.xml*.
Refer to the Maven documentation (http://maven.apache.org/examples/injecting-properties-via-settings.html) for more details.

```xml
<build>
		<pluginManagement>
			<plugins>

				<plugin>
					<groupId>com.xti.flowable</groupId>
					<artifactId>flowable-modeler-maven-plugin</artifactId>
					<version>0.0.1-SNAPSHOT</version>
						<configuration>
							<url>http://localhost:8080</url> <!-- URL on which your Flowable Modeler instance runs -->
							<username>admin</username> <!-- USERNAME to login on your Flowable Modeler instance -->
							<password>test</password> <!-- PASSWORD to login on your Flowable Modeler instance -->
							<path>src/main/resources</path><!-- PATH where model files in your project reside  -->
							<types><!-- TYPES you want the plugin to handle - BPMN, CMMN, DMN and FORM -->
								<type>BPMN</type>
								<type>CMMN</type>
								<type>DMN</type>
								<type>FORM</type>
							</types>
							<bpmnFileExtension>.bpmn20.xml</bpmnFileExtension> <!-- FILE EXTENSION to use for BPMN files (".bpmn20.xml", ".bpmn.xml", ".bpmn", ...) -->
							<cmmnFileExtension>.cmmn.xml</cmmnFileExtension> <!-- FILE EXTENSION to use for CMMN files (".cmmn.xml", ".cmmn", ...) -->
							<dmnFileExtension>.dmn</dmnFileExtension><!-- FILE EXTENSION to use for DMN files (".dmn", ".dmn.xml", ...) -->
							<formFileExtension>.form</formFileExtension><!-- FILE EXTENSION to use for FORM files -->
							<fileNameStrategyOption>NAME</fileNameStrategyOption> <!-- NAME is compliant with Flowable Modeler download names, KEY is an alternative -->
						</configuration>
		           </plugin>

			</plugins>

		</pluginManagement>

	<plugins>

		<plugin>
			<groupId>com.xti.flowable</groupId>
			<artifactId>flowable-modeler-maven-plugin</artifactId>
			<executions>
				<execution>
					<id>execution-upon-generate-resources</id>
					<phase>generate-resources</phase>
					<goals>
						<goal>download-models</goal>
					</goals>
		          </execution>
			</executions>
        </plugin>

	</plugins>
</build>
```

## Using the plugin

### Downloading models

Downloading model from Flowable Modeler to the local filesystem

	mvn flowable-modeler:download-models

With the default configuration, your downloaded model files can be found in *src/main/resources/*
The plugin logs on the consolse for each file whether it was ADDED since last download, UPDATED of UNCHANGED.

### Importing models

Importing local model files in Flowable Modeler (make sure that no duplicates exist):

	mvn flowable-modeler:import-models

With the default configuration, the following local folders are scanned and all model files are imported in Flowable Modeler:

* BPMN model files in *src/main/resources/processes*
* CMMN model files in *src/main/resources/cases*
* DMN model files in *src/main/resources/dmn*
* FORM model files in *src/main/resources/forms*

You can now edit the models in Flowable Modeler, and after that download them again in batch with the plugin

repository: XT-i/flowable-modeler-maven-plugin

gha_language: Java

repo_name: XT-i/flowable-modeler-maven-plugin


text:
[![Go Reference](https://pkg.go.dev/badge/github.com/tommzn/go-config.svg)](https://pkg.go.dev/github.com/tommzn/aws-dynamodb)
![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/tommzn/aws-dynamodb)
![GitHub release (latest by date)](https://img.shields.io/github/v/release/tommzn/aws-dynamodb)
[![Go Report Card](https://goreportcard.com/badge/github.com/tommzn/aws-dynamodb)](https://goreportcard.com/report/github.com/tommzn/aws-dynamodb)
[![Actions Status](https://github.com/tommzn/aws-dynamodb/actions/workflows/go.pkg.auto-ci.yml/badge.svg)](https://github.com/tommzn/aws-dynamodb/actions)

# DynamoDb Wrapper
This package provides a wrapper to dynamodb to run CRUD actions for items. It expects a table with a composed primary key of ObjectType (Hash) and Id (Range).
Sub package testing will support you creating a suitable table for tests.

repository: tommzn/aws-dynamodb

repo_name: tommzn/aws-dynamodb


text:
# rails_devise_with_email

fully functional app demonstarting how to use DEVISE with MAILING facility.

http://therise3107.github.io/rails_devise_with_mail

Awesome Gems which are used(checkout each gem for more cool features) :-

* rails_layout
* devise
* bootstrap
* better_error

### create a new rails project

    rails new devise_app
switch you your newly created app

    cd devise_app
open your Gemfile and add

    group :development do
      gem "better_errors"
    end
### bootstrap for some awesome features

    gem 'bootstrap-sass', '~> 3.2.0'
    gem 'autoprefixer-rails'
    gem 'devise'
### rails_layout for bootstrap or zorb foundation

    group :development do
      gem 'rails_layout'
    end
run bundle to install the new gems

    bundle
### Configuring rails_layout for handling bootstrap
run

    rails g layout:install bootstrap3
to install bootstap3 for your app

    rails g scaffold post title body:text
    rake db:migrate
this will create the post model, controller and views for you

### configure Devise

    rails g devise:install
    rails g devise user
    rake db:migrate
this will create a user model for handling the user accounts

### Configuring layout for devise and navigational links

    rails g layout:devise bootstrap3
    rails g layout:navigation

these commands will add and modify the view files for devise and will add navigation at home page
### Creating the mailer

    rails g mailer mailer
this will create a mailer for you in app/mailer/mailer.rb , open mailer.rb and add the following code

    default from<EMAIL_ADDRESS>    def confirmation_instructions(user)
      @user = user
  	  mail(to: @user.email, subject: 'Account confirmation_instructions')
    end

    def reset_password_instructions(user)
  	  @user = user
  	  mail(to: @user.email, subject: 'reset_password_instructions')
    end
    def unlock_instructions(user)
  	  @user = user
  	  mail(to: @user.email, subject: 'unlock_instructions')
    end
this are the functions which will be invoked by devise for you, to change the views created by devise for you run

    rails g devise:views

### SMTP configuration
add these lines of code in your config/env/develpoment.rb

    config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
    config.action_mailer.delivery_method = :smtp
    # SMTP settings for gmail
    config.action_mailer.smtp_settings = {
      :address              => "smtp.gmail.com",
      :port                 => 587,
      :user_name            => ENV['gmail_user_name'],
      :password             => ENV['gmail_password'],
      :authentication       => "plain",
      :enable_starttls_auto => true
      }

 and set

    config.action_mailer.raise_delivery_errors = true
this will raise errors whenever you mess up, but do not worry we have added better_errors!
### Setting ENV variables
create a new .env file in your root dir and add

    ENV["gmail_user_name"] = yourgamiladdres.com
    ENV["gmail_password"]  = youpassword
do not forget to add .env file in you .gitignore file if you are going to push your app on github

### Adding relationship between models
  add this in your app/model/user.rb

      has_many :posts

  add this in your app/post.rb

      belongs_to :user

### User Auth Mechanism
add this code in your posts_controller.rb

    before_action :authenticate_user!,only: [:new,:edit, :update, :destroy]
    before_action :own_auth, only: [:new,:edit, :update, :destroy]
    ....
    ....
    def create
      @post = Post.new(post_params)
      @user_id = current_user.id
      @post.save
      respond_with(@post)
    end
    ....
    ....
    private
     def own_auth
      if !user_signed_in? || current_user != Post.find(params[:id])
        redirect_to root_path, notice: "you cannot modify this content, please authenticate yourself"
      end
    end

now run

    rails s

and enjoy your newly created site

https://github.com/therise3107

gha_language: Ruby


text:
# Swish Activation - PyTorch CUDA Implementation

This is a PyTorch CUDA implementation of the Swish activation function (https://arxiv.org/abs/1710.05941).

## Installation
It is currently distributed as a source only PyTorch extension. So you need a properly set up toolchain and CUDA compilers to install.
1) _Toolchain_ - In conda the `gxx_linux-64` package provides an appropriate toolchain. However there can still be compatbility issues with this depending on system. You can also try with the system toolchain.
2) _CUDA Toolkit_ - The [nVidia CUDA Toolkit](https://developer.nvidia.com/cuda-toolkit) is required in addition to drivers to provide needed headers and tools. Get the appropriate version for your Linux distro from nVidia or check for distro specific instructions otherwise.

_It is important your CUDA Toolkit matches the version PyTorch is built for or errors can occur. Currently PyTorch builds for v10.0 and v9.2._

repository: thomasbrandon/swish-torch

repo_name: thomasbrandon/swish-torch


text:
---
layout: post
title: Dimensionality reduction in one slide (part 2)
tags: [backward, construction, dimensionality, ensemble-trees, features, forward, pca, reduction]
comments: true
---
Extracting knowledge from large datasets with large number of variables is
always tricky. Dimensionality reduction helps in analyzing high dimensional
data, still maintaining most of the information hidden behind complexity. Here
are some methods that you must try before further analysis (Part 2).

<img src="https://s3-eu-west-1.amazonaws.com/wopcontent/uploads/2015/09/image.jpg" />


text:
# RescueTime Menu Bar [![MIT](https://img.shields.io/badge/Hotness-Fire-orange.svg?style=flat-squared)]()
> track total productive hours in your menu bar

This adds the total hours and minutes that you've had of productivity today, according to [rescuetime](http://rescuetime.com?wish-I-had-an-affiliate-key).

## Installation
timeforthat.gif (right now you have to build it, but it's really not that hard)

## Building
0. Install [rescuetime](http://rescuetime.com?wish-I-had-an-affiliate-key) and grab an API key
1. Clone this repo somewhere locally
2. Run `npm install`
3. Copy key.json.example to key.json.
4. run `npm run build` and look in your dist directory!

## Requirements
* Mac OS 10.8 and higher

repository: khaliqgant/rescuetime-menu-bar

repo_name: khaliqgant/rescuetime-menu-bar


text:
---
layout: default
---

# 1992-11-14 - 1/3 Cryptography bibliography

## Header Data

From<EMAIL_ADDRESS>(tom jennings)

To<EMAIL_ADDRESS>Message Hash: 11beb3797803b86275a8953fedbe197501060d95b4434cd6752ad916a7a89dba

Message ID<EMAIL_ADDRESS>Reply To: _N/A_

UTC Datetime: 1992-11-14 03:23:56 UTC

Raw Date: Fri, 13 Nov 92 19:23:56 PST

## Raw message

```
{% raw  %}From<EMAIL_ADDRESS>(tom jennings)
Date: Fri, 13 Nov 92 19:23:56 PST
To<EMAIL_ADDRESS>Subject: 1/3 Cryptography bibliography
Message-ID<EMAIL_ADDRESS>MIME-Version: 1.0
Content-Type: text/plain

    * Forwarded by Rich Veraa
      To:  All                        Message #:  365
    From:  Ed Beroset                 Submitted:  10 Nov 92  20:34:38
 Subject:  1/3 cryptographic bibliog     Status:  Public
Received:  ** New Message Read! **        Group:  80XXX (17)

I'm sorry it took me a little longer than I had anticipated to put together
this list, but I think you'll find it worth while.  This is a list of books
which deal with various aspects of cryptography (including DES, RSA, and many
other schemes and topics.)  They're organized roughly in reverse chronological
order, with newer texts toward the top of the list.

TITLE : Cryptography : a new dimension in computer data security : a guide
        for the design and implementation of secure systems /
AUTHOR: Meyer, Carl H.
IMPR  : New York : Wiley, 1982.

TITLE : Traffic analysis and the Zendian problem : an exercise in
        communications intelligence operations /
AUTHOR: Callimahos, Lambros D.
IMPR  : Laguna Hills, Calif. : Aegean Park Press, c1989.

TITLE : Military communications : a test for technology /
AUTHOR: Bergen, John D., 1942-.
IMPR  : Washington, D.C. : Center of Military History, U.S. Army : For sale
        by the Supt. of Docs., U.S. G.P.O., 1986.

TITLE : Principles of secure communication systems /
AUTHOR: Torrieri, Don J.
IMPR  : Dedham, MA : Artech House, c1985.

TITLE : Contemporary cryptology : the science of information integrity /
IMPR  : Piscataway, NJ : IEEE Press, c1992.

TITLE : Public-key cryptography : state of the art and future directions :
        E.I.S.S. workshop, Oberwolfach, Germany, July 3-6 1991 : final report
       / IMPR  : Berlin ; New York : Springer-Verlag, 1992.

TITLE : Advances in cryptology--EUROCRYPT '91 : Workshop on the Theory and
        Application of Cryptographic Techniques, Brighton, UK, April 8-11,
        1991 : proceedings /
AUTHOR: EUROCRYPT '91 (1991 : Brighton, England)
IMPR  : Berlin ; New York : Springer-Verlag, c1991.

TITLE : United States cryptographic patents, 1861-1989 /
ED    : [2nd ed.]
AUTHOR: Levine, Jack, 1907-.
IMPR  : Terre Haute, Ind. : Cryptologia, 1991.

TITLE : Geometries, codes and cryptography /
IMPR  : Wien ; New York : Springer-Verlag, c1990.

TITLE : Number theory and cryptography /
IMPR  : Cambridge ; New York : Cambridge University Press, 1990.

TITLE : Cryptography : an introduction to computer security /
AUTHOR: Seberry, Jennifer, 1944-.
IMPR  : New York : Prentice-Hall, c1989.

TITLE : Codes and cryptography /
AUTHOR: Welsh, D. J. A.
IMPR  : Oxford [Oxfordshire] : Clarendon Press ; New York : Oxford University
        Press, 1988.

TITLE : Crypto users' handbook : a guide for implementors of cryptographic
        protection in computer systems /
IMPR  : Amsterdam [The Netherlands] ; New York : North-Holland ; New York,
        N.Y., U.S.A. : Sole distributors for the U.S.A. and Canada, Elsevier
        Science Pub. Co., 1988.

TITLE : An introduction to cryptology /
AUTHOR: Tilborg, Henk C. A. van, 1947-.
IMPR  : Boston : Kluwer Academic Publishers, c1987.

TITLE : Modern cryptology : a tutorial /
AUTHOR: Brassard, Gilles, 1955-.
IMPR  : New York : Springer-Verlag, c1988.

TITLE : A course in number theory and cryptography /
AUTHOR: Koblitz, Neal, 1948-.
IMPR  : New York : Springer-Verlag, c1987.

TITLE : Cryptology yesterday, today, and tomorrow /
IMPR  : Norwood, MA : Artech House, c1987.

TITLE : Mathematical cryptology for computer scientists and mathematicians /
AUTHOR: Patterson, Wayne, 1945-.
IMPR  : Totowa, N.J. : Rowman & Littlefield, 1987.

TITLE : Analysis and design of stream ciphers /
AUTHOR: Rueppel, Rainer A., 1955-.
IMPR  : Berlin ; New York : Springer-Verlag, c1986.

TITLE : Primality and cryptography /
AUTHOR: Kranakis, Evangelos.
IMPR  : Stuttgart : Teubner ; Chichester [Sussex] ; New York : Wiley, c1986.

-+--- continued next message -----

--- XAP 1.02+
 * Origin: the birds round about are against her; (1:135/907)
--
tom jennings - via FidoNet node 1:125/555
    UUCP - ...!uunet!hoptoad!kumr!fidogate!111!tom.jennings
INTERNET -<EMAIL_ADDRESS>
rom<EMAIL_ADDRESS>Fri Nov 13 19:23:59 1992
Return-Path<EMAIL_ADDRESS>Received: from kumr.lns.com by toad.com id AA23114; Fri, 13 Nov 92 19:23:59 PST
Received: by kumr.lns.com (/\==/\ Smail<IP_ADDRESS> #25.3)
	id<EMAIL_ADDRESS>Fri, 13 Nov 92 18:57 PST
Received: by fidogate.FIDONET.ORG (mailout1.26); Fri, 13 Nov 92 18:42:59 PDT
Date: Fri, 13 Nov 92 18:56:32 PDT
Message-Id<EMAIL_ADDRESS>From<EMAIL_ADDRESS>(tom jennings)
Subject: 2/3 Cryptography bibliography
To<EMAIL_ADDRESS>X-Mailer: mailout v1.26 released

    * Forwarded by Rich Veraa
      To:  All                        Message #:  366
    From:  Ed Beroset                 Submitted:  10 Nov 92  20:34:38
 Subject:  2/3 cryptographic bibliog     Status:  Public
Received:  ** New Message Read! **        Group:  80XXX (17)

RE: 2/3 cryptographic bibliography

-+--- continued from previous message -----

TITLE : Two issues in public-key cryptography : RSA bit security and a new
        knapsack type system /
AUTHOR: Chor, Ben-Zion.
IMPR  : Cambridge, Mass. : MIT Press, c1986.

TITLE : Kryptologie /
AUTHOR: Horster, Patrick.
IMPR  : Mannheim : Bibliographisches Institut, c1985.
LANG  : German

TITLE : Machine cryptography and modern cryptanalysis /
AUTHOR: Deavours, Cipher A.
IMPR  : Dedham, MA : Artech House, c1985.

TITLE : Cryptanalysis of shift-register generated stream cipher systems /
AUTHOR: Barker, Wayne G.
IMPR  : Laguna Hills, Calif. : Aegean Park Press, c1984.

TITLE : Applied cryptology, cryptographic protocols, and computer security
        models.
IMPR  : Providence, R.I. : American Mathematical Society, c1983.

TITLE : Secure digital communications /
IMPR  : Wien ; New York : Springer-Verlag, c1983.

TITLE : Cipher systems : the protection of communications /
AUTHOR: Beker, Henry.
IMPR  : New York : Wiley, c1982.

TITLE : Codes, ciphers, and computers : an introduction to information
        security /
AUTHOR: Bosworth, Bruce.
IMPR  : Rochelle Park, N.J. : Hayden Book Co., c1982.

TITLE : Cryptography and data security /
AUTHOR: Denning, Dorothy Elizabeth Robling, 1945-.
IMPR  : Reading, Mass. : Addison-Wesley, c1982.

TITLE : Secure communications and asymmetric cryptosystems /
IMPR  : Boulder, Colo. : Published by Westview Press for the American
        Association for the Advancement of Science, 1982.

TITLE : Cryptography, a primer /
AUTHOR: Konheim, Alan G., 1934-.
IMPR  : New York : Wiley, c1981.

TITLE : The origin and development of the National Security Agency /
AUTHOR: Brownell, George A.
IMPR  : Laguna Hills, Calif. : Aegean Park Press, 1981.

UNI-TI: Traite de cryptographie. English.
TITLE : Treatise on cryptography /
AUTHOR: Langie, Andre, 1871-.
IMPR  : Laguna Hills, Calif. : Aegean Park Press, c1981.

TITLE : Cryptanalysis of an enciphered code problem : where an "additive"
        method of encipherment has been used /
AUTHOR: Barker, Wayne G.
IMPR  : Laguna Hills, Calif. : Aegean Park Press, c1979.

UNI-TI: Chifferbyraernas insatser i varldskriget till lands. English.
TITLE : The contribution of the cryptographic bureaus in the World War /
AUTHOR: Gylden, Yves.
IMPR  : Laguna Hills, Calif. : Aegean Park Press, c1978.

TITLE : The protection of data by crytography /
AUTHOR: Davies, (Donald Watts)
IMPR  : Middlesex : National Physical Laboratory, 1978.

TITLE : Cryptanalysis of the Hagelin cryptograph /
AUTHOR: Barker, Wayne G.
IMPR  : Laguna Hills, Calif. : Aegean Park Press, c1977.

UNI-TI: Manuale di crittografia. Italian.
TITLE : Manual of cryptography /
AUTHOR: Sacco, Luigi.
IMPR  : Laguna Hills, Calif. : Aegean Park Press, c1977.

TITLE : Pattern-word list /
AUTHOR: Lynch, Frederick D.
IMPR  : Laguna Hills, Calif. : Aegean Park Press, c1977-.

-+--- continued next message -----

--- XAP 1.02+
 * Origin: If at first you don't succeed, try, try a bird. (1:135/907)
--
tom jennings - via FidoNet node 1:125/555
    UUCP - ...!uunet!hoptoad!kumr!fidogate!111!tom.jennings
INTERNET -<EMAIL_ADDRESS>

{% endraw %}
```

## Thread

+ Return to [November 1992](/archive/1992/11)

+ Return to<EMAIL_ADDRESS>(tom jennings)](/authors/tom_jennings_at_f111_n125_z1_fidonet_org_tom_jennings_)"

+ 1992-11-14 (Fri, 13 Nov 92 19:23:56 PST) - 1/3 Cryptography bibliography -<EMAIL_ADDRESS>(tom jennings)_


text:
# Please contribute

You can really make a difference by:

- [Making an issue](https://help.github.com/articles/creating-an-issue/). A well described issue helps a lot. (Have a look at the [known issues](https://github.com/search?q=user%3Atehtbl+is%3Aissue+state%3Aopen).)
- [Making a pull request](https://services.github.com/on-demand/github-cli/open-pull-request-github) when you see the error in code.

I'll try to help and take every contribution seriously.

It's a great opportunity for me to learn how you use the role and also an opportunity to get into the habit of contributing to open source software.

repository: tehtbl/ansible-role-bootstrap

repo_name: tehtbl/ansible-role-bootstrap


text:
# object-detection-utils
Utils scripts for object detection and tfevents exploration and visualization

### Generate tfrecords from PASCAL VOC data:
```python scripts/generate_tfrecord.py -x [path/to/data/dir/] -l [path/to/label_map.pbtxt] -o [output/path/]```
(data dir contains both XML and PNG files)

### Open tfevents in tensorboard:
```tensorboard --logdir [path/to/tfevents/]```
(path can contains subfolders, runs will be divided by its subfolders)

### Generate CSV from tfevents:
```python scripts/tfevents_to_csv.py [path/to/tfevents/] --write-csv --out-dir [output/dir/] --out-filename [output_filename_without_extension]```

repository: jamerico/object-detection-utils

repo_name: jamerico/object-detection-utils


text:
# PinCFGReconstructor

## TL;DR
An efficient Pintool to reconstruct the Control Flow Graph (CFG) of plain and UPX packed executables.

## Abstract
With the development of increasingly advanced techniques to hide the malicious
payload of a Malware, the community of reverse engineers and security researchers
has been facing more and more complex programs which brought about the need of
more advanced analysis than classic ones based on static code inspection. To truly
understand what such malicious programs do, an analyst needs to look at them
while they are executing, thus tools to carry out their analyses at runtime have
become one of the most powerful weapons to face new threats.
Among the techniques for the design and implementation of such tools there is
dynamic binary instrumentation (DBI), an advanced solution that makes it possible
to instrument a program dynamically (i.e., while it is running), allowing for a
fine-grained inspection of its execution. Although this technique is very powerful,
it carries with it some performance and accuracy trade-offs. In this project we will
build tools to record instructions and reconstruct the control flow graph of a possibly
malicious program, discussing during the journey the challenges introduced by the
usage of DBI and proposing some solutions to mitigate these problems.

## Dependencies
- [Intel PIN](https://software.intel.com/sites/landingpage/pintool/downloads/pin-3.5-97503-gac534ca30-msvc-windows.zip)
- [Capstone](https://www.capstone-engine.org/download.html)
- [Graphviz](https://www.graphviz.org/download)
- [Python 3.6.3](https://www.python.org/downloads/release/python-363)
- The solution has been compiled using Visual Studio 2010 (v100) toolset. I strongly advise to install [Visual C++ 2010 Express Edition](https://my.visualstudio.com/Downloads?q=visual%20studio%202010&wt.mc_id=o~msft~vscom~older-downloads) (to get the toolset), and then using Visual Studio 2015 or later IDE.

## Usage
Assuming Intel Pin folder is located at `C:\Pin35`, you can launch the tool with the following structure:
`C:\Pin35\pin.exe -t C:\Pin35\icount.dll <tool-switches> -- <analyzed-program> <analyzed-program-switches>`
By default the tool uses the Unbuffered version and generates a trace of 2Gb maximum
Once the tool finishes instrumenting the executable it generates: a (i)`trace.out` file; a (ii)dump of each of the sections of the program; and a (iii) `report.json` file containing information about the executed programs (e.g.: Sections' low addresses and size).
Once the analysis is finished, the CFG can be reconstructed by launching `python CFG_reconstructor.py`. A PDF of the CFG will be shown and a file called CFG.gv.pdf will be created

#### Pintool otions
Apart from the standard switches of Intel Pin, the Pintool can be configured with these additional switches:
- -**buffered**  [default false]:
        whether or not the trace is buffered
- -**thread_flushed**  [default false]:
        whether or not the trace has a thread for flushing
- -**favor_main_thread**  [default false]:
        allocate only a quarter of thread buffer for threads that are not the main one
- -**tag**  [default ""]:
        tag for the performance report. If missing no report will be generated
- -**thread_buffer_size**  [default 30Mb]:
        size of the per-thread buffer
- -**trace_limit**  [default 2Gb]:
        size of the trace limit

### Notes
The tool has been tested on Win32 only with UPX packer.

## Thanks
This work has also been possible thanks to: [Capstone](https://github.com/aquynh/capstone) and [Graphviz](https://gitlab.com/graphviz/graphviz)

repository: sljiaa/PinCFGReconstructor

repo_name: sljiaa/PinCFGReconstructor


text:
# Examples

## Offline cold-wallet usage :

The wallet can handle a lack of connectivity. This could allow the use of the wallet library in an offline way.
Such uses case would be to generate a bunch of addresses that you could manually import into a database (for rolling incoming addresses)

You also have ways to import a known address, transaction, account or any type of data that you could wish to have via the network,
thus allowing you to use the wallet-library without connectivity.

See here [sample code](https://github.com/dashevo/wallet-lib/blob/master/examples/offline-wallet.js)

## Offline message signing :

See here [sample code](https://github.com/dashevo/wallet-lib/blob/master/examples/offline-wallet-signing-message.js)

## Client usage

- From Mnemonic: [sample code](https://github.com/dashevo/wallet-lib/blob/master/examples/client-usage.js)
- From PrivateKey: [sample code](https://github.com/dashevo/wallet-lib/blob/master/examples/client-usage-single-privateKey.js)

repository: dashevo/wallet-lib

gha_language: JavaScript

repo_name: dashevo/wallet-lib


text:
---
title: Part 8 - B-Tree Leaf Node Format
date: 2017-09-25
---

We're changing the format of our table from an unsorted array of rows to a B-Tree. This is a pretty big change that is going to take multiple articles to implement. By the end of this article, we'll define the layout of a leaf node and support inserting key/value pairs into a single-node tree. But first, let's recap the reasons for switching to a tree structure.

## Alternative Table Formats

With the current format, each page stores only rows (no metadata) so it is pretty space efficient. Insertion is also fast because we just append to the end. However, finding a particular row can only be done by scanning the entire table. And if we want to delete a row, we have to fill in the hole by moving every row that comes after it.

If we stored the table as an array, but kept rows sorted by id, we could use binary search to find a particular id. However, insertion would be slow because we would have to move a lot of rows to make space.

Instead, we're going with a tree structure. Each node in the tree can contain a variable number of rows, so we have to store some information in each node to keep track of how many rows it contains. Plus there is the storage overhead of all the internal nodes which don't store any rows. In exchange for a larger database file, we get fast insertion, deletion and lookup.

|               | Unsorted Array of rows | Sorted Array of rows | Tree of nodes |
|---------------|------------------------|----------------------|---------------|
| Pages contain | only data              | only data            | metadata, primary keys, and data              |
| Rows per page | more                   | more                 | fewer         |
| Insertion     | O(1)                   | O(n)                 | O(log(n))     |
| Deletion      | O(n)                   | O(n)                 | O(log(n))     |
| Lookup by id  | O(n)                   | O(log(n))            | O(log(n))     |

## Node Header Format

Leaf nodes and internal nodes have different layouts. Let's make an enum to keep track of node type:

```diff
+typedef enum { NODE_INTERNAL, NODE_LEAF } NodeType;
```

Each node will correspond to one page. Internal nodes will point to their children by storing the page number that stores the child. The btree asks the pager for a particular page number and gets back a pointer into the page cache. Pages are stored in the database file one after the other in order of page number.

Nodes need to store some metadata in a header at the beginning of the page. Every node will store what type of node it is, whether or not it is the root node, and a pointer to its parent (to allow finding a node's siblings). I define constants for the size and offset of every header field:

```diff
+/*
+ * Common Node Header Layout
+ */
+const uint32_t NODE_TYPE_SIZE = sizeof(uint8_t);
+const uint32_t NODE_TYPE_OFFSET = 0;
+const uint32_t IS_ROOT_SIZE = sizeof(uint8_t);
+const uint32_t IS_ROOT_OFFSET = NODE_TYPE_SIZE;
+const uint32_t PARENT_POINTER_SIZE = sizeof(uint32_t);
+const uint32_t PARENT_POINTER_OFFSET = IS_ROOT_OFFSET + IS_ROOT_SIZE;
+const uint8_t COMMON_NODE_HEADER_SIZE =
+    NODE_TYPE_SIZE + IS_ROOT_SIZE + PARENT_POINTER_SIZE;
```

## Leaf Node Format

In addition to these common header fields, leaf nodes need to store how many "cells" they contain. A cell is a key/value pair.

```diff
+/*
+ * Leaf Node Header Layout
+ */
+const uint32_t LEAF_NODE_NUM_CELLS_SIZE = sizeof(uint32_t);
+const uint32_t LEAF_NODE_NUM_CELLS_OFFSET = COMMON_NODE_HEADER_SIZE;
+const uint32_t LEAF_NODE_HEADER_SIZE =
+    COMMON_NODE_HEADER_SIZE + LEAF_NODE_NUM_CELLS_SIZE;
```

The body of a leaf node is an array of cells. Each cell is a key followed by a value (a serialized row).

```diff
+/*
+ * Leaf Node Body Layout
+ */
+const uint32_t LEAF_NODE_KEY_SIZE = sizeof(uint32_t);
+const uint32_t LEAF_NODE_KEY_OFFSET = 0;
+const uint32_t LEAF_NODE_VALUE_SIZE = ROW_SIZE;
+const uint32_t LEAF_NODE_VALUE_OFFSET =
+    LEAF_NODE_KEY_OFFSET + LEAF_NODE_KEY_SIZE;
+const uint32_t LEAF_NODE_CELL_SIZE = LEAF_NODE_KEY_SIZE + LEAF_NODE_VALUE_SIZE;
+const uint32_t LEAF_NODE_SPACE_FOR_CELLS = PAGE_SIZE - LEAF_NODE_HEADER_SIZE;
+const uint32_t LEAF_NODE_MAX_CELLS =
+    LEAF_NODE_SPACE_FOR_CELLS / LEAF_NODE_CELL_SIZE;
```

Based on these constants, here's what the layout of a leaf node looks like currently:

{% include image.html url="assets/images/leaf-node-format.png" description="Our leaf node format" %}

It's a little space inefficient to use an entire byte per boolean value in the header, but this makes it easier to write code to access those values.

Also notice that there's some wasted space at the end. We store as many cells as we can after the header, but the leftover space can't hold an entire cell. We leave it empty to avoid splitting cells between nodes.

## Accessing Leaf Node Fields

The code to access keys, values and metadata all involve pointer arithmetic using the constants we just defined.

```diff
+uint32_t* leaf_node_num_cells(void* node) {
+  return node + LEAF_NODE_NUM_CELLS_OFFSET;
+}
+
+void* leaf_node_cell(void* node, uint32_t cell_num) {
+  return node + LEAF_NODE_HEADER_SIZE + cell_num * LEAF_NODE_CELL_SIZE;
+}
+
+uint32_t* leaf_node_key(void* node, uint32_t cell_num) {
+  return leaf_node_cell(node, cell_num);
+}
+
+void* leaf_node_value(void* node, uint32_t cell_num) {
+  return leaf_node_cell(node, cell_num) + LEAF_NODE_KEY_SIZE;
+}
+
+void initialize_leaf_node(void* node) { *leaf_node_num_cells(node) = 0; }
+
```

These methods return a pointer to the value in question, so they can be used both as a getter and a setter.

## Changes to Pager and Table Objects

Every node is going to take up exactly one page, even if it's not full. That means our pager no longer needs to support reading/writing partial pages.
```diff
-void pager_flush(Pager* pager, uint32_t page_num, uint32_t size) {
+void pager_flush(Pager* pager, uint32_t page_num) {
   if (pager->pages[page_num] == NULL) {
     printf("Tried to flush null page\n");
     exit(EXIT_FAILURE);
@@ -242,7 +337,7 @@ void pager_flush(Pager* pager, uint32_t page_num, uint32_t size) {
   }

   ssize_t bytes_written =
-      write(pager->file_descriptor, pager->pages[page_num], size);
+      write(pager->file_descriptor, pager->pages[page_num], PAGE_SIZE);

   if (bytes_written == -1) {
     printf("Error writing: %d\n", errno);
```

```diff
 void db_close(Table* table) {
   Pager* pager = table->pager;
-  uint32_t num_full_pages = table->num_rows / ROWS_PER_PAGE;

-  for (uint32_t i = 0; i < num_full_pages; i++) {
+  for (uint32_t i = 0; i < pager->num_pages; i++) {
     if (pager->pages[i] == NULL) {
       continue;
     }
-    pager_flush(pager, i, PAGE_SIZE);
+    pager_flush(pager, i);
     free(pager->pages[i]);
     pager->pages[i] = NULL;
   }

-  // There may be a partial page to write to the end of the file
-  // This should not be needed after we switch to a B-tree
-  uint32_t num_additional_rows = table->num_rows % ROWS_PER_PAGE;
-  if (num_additional_rows > 0) {
-    uint32_t page_num = num_full_pages;
-    if (pager->pages[page_num] != NULL) {
-      pager_flush(pager, page_num, num_additional_rows * ROW_SIZE);
-      free(pager->pages[page_num]);
-      pager->pages[page_num] = NULL;
-    }
-  }
-
   int result = close(pager->file_descriptor);
   if (result == -1) {
     printf("Error closing db file.\n");
```

Now it makes more sense to store the number of pages in our database rather than the number of rows. The number of pages should be associated with the pager object, not the table, since it's the number of pages used by the database, not a particular table. A btree is identified by its root node page number, so the table object needs to keep track of that.

```diff
 const uint32_t PAGE_SIZE = 4096;
 const uint32_t TABLE_MAX_PAGES = 100;
-const uint32_t ROWS_PER_PAGE = PAGE_SIZE / ROW_SIZE;
-const uint32_t TABLE_MAX_ROWS = ROWS_PER_PAGE * TABLE_MAX_PAGES;

 typedef struct {
   int file_descriptor;
   uint32_t file_length;
+  uint32_t num_pages;
   void* pages[TABLE_MAX_PAGES];
 } Pager;

 typedef struct {
   Pager* pager;
-  uint32_t num_rows;
+  uint32_t root_page_num;
 } Table;
```

```diff
@@ -127,6 +200,10 @@ void* get_page(Pager* pager, uint32_t page_num) {
     }

     pager->pages[page_num] = page;
+
+    if (page_num >= pager->num_pages) {
+      pager->num_pages = page_num + 1;
+    }
   }

   return pager->pages[page_num];
```

```diff
@@ -184,6 +269,12 @@ Pager* pager_open(const char* filename) {
   Pager* pager = malloc(sizeof(Pager));
   pager->file_descriptor = fd;
   pager->file_length = file_length;
+  pager->num_pages = (file_length / PAGE_SIZE);
+
+  if (file_length % PAGE_SIZE != 0) {
+    printf("Db file is not a whole number of pages. Corrupt file.\n");
+    exit(EXIT_FAILURE);
+  }

   for (uint32_t i = 0; i < TABLE_MAX_PAGES; i++) {
     pager->pages[i] = NULL;
```

## Changes to the Cursor Object

A cursor represents a position in the table. When our table was a simple array of rows, we could access a row given just the row number. Now that it's a tree, we identify a position by the page number of the node, and the cell number within that node.

```diff
 typedef struct {
   Table* table;
-  uint32_t row_num;
+  uint32_t page_num;
+  uint32_t cell_num;
   bool end_of_table;  // Indicates a position one past the last element
 } Cursor;
```

```diff
 Cursor* table_start(Table* table) {
   Cursor* cursor = malloc(sizeof(Cursor));
   cursor->table = table;
-  cursor->row_num = 0;
-  cursor->end_of_table = (table->num_rows == 0);
+  cursor->page_num = table->root_page_num;
+  cursor->cell_num = 0;
+
+  void* root_node = get_page(table->pager, table->root_page_num);
+  uint32_t num_cells = *leaf_node_num_cells(root_node);
+  cursor->end_of_table = (num_cells == 0);

   return cursor;
 }
```

```diff
 Cursor* table_end(Table* table) {
   Cursor* cursor = malloc(sizeof(Cursor));
   cursor->table = table;
-  cursor->row_num = table->num_rows;
+  cursor->page_num = table->root_page_num;
+
+  void* root_node = get_page(table->pager, table->root_page_num);
+  uint32_t num_cells = *leaf_node_num_cells(root_node);
+  cursor->cell_num = num_cells;
   cursor->end_of_table = true;

   return cursor;
 }
```

```diff
 void* cursor_value(Cursor* cursor) {
-  uint32_t row_num = cursor->row_num;
-  uint32_t page_num = row_num / ROWS_PER_PAGE;
+  uint32_t page_num = cursor->page_num;
   void* page = get_page(cursor->table->pager, page_num);
-  uint32_t row_offset = row_num % ROWS_PER_PAGE;
-  uint32_t byte_offset = row_offset * ROW_SIZE;
-  return page + byte_offset;
+  return leaf_node_value(page, cursor->cell_num);
 }
```

```diff
 void cursor_advance(Cursor* cursor) {
-  cursor->row_num += 1;
-  if (cursor->row_num >= cursor->table->num_rows) {
+  uint32_t page_num = cursor->page_num;
+  void* node = get_page(cursor->table->pager, page_num);
+
+  cursor->cell_num += 1;
+  if (cursor->cell_num >= (*leaf_node_num_cells(node))) {
     cursor->end_of_table = true;
   }
 }
```

## Insertion Into a Leaf Node

In this article we're only going to implement enough to get a single-node tree. Recall from last article that a tree starts out as an empty leaf node:

{% include image.html url="assets/images/btree1.png" description="empty btree" %}

Key/value pairs can be added until the leaf node is full:

{% include image.html url="assets/images/btree2.png" description="one-node btree" %}

When we open the database for the first time, the database file will be empty, so we initialize page 0 to be an empty leaf node (the root node):

```diff
 Table* db_open(const char* filename) {
   Pager* pager = pager_open(filename);
-  uint32_t num_rows = pager->file_length / ROW_SIZE;

   Table* table = malloc(sizeof(Table));
   table->pager = pager;
-  table->num_rows = num_rows;
+  table->root_page_num = 0;
+
+  if (pager->num_pages == 0) {
+    // New database file. Initialize page 0 as leaf node.
+    void* root_node = get_page(pager, 0);
+    initialize_leaf_node(root_node);
+  }

   return table;
 }
```

Next we'll make a function for inserting a key/value pair into a leaf node. It will take a cursor as input to represent the position where the pair should be inserted.

```diff
+void leaf_node_insert(Cursor* cursor, uint32_t key, Row* value) {
+  void* node = get_page(cursor->table->pager, cursor->page_num);
+
+  uint32_t num_cells = *leaf_node_num_cells(node);
+  if (num_cells >= LEAF_NODE_MAX_CELLS) {
+    // Node full
+    printf("Need to implement splitting a leaf node.\n");
+    exit(EXIT_FAILURE);
+  }
+
+  if (cursor->cell_num < num_cells) {
+    // Make room for new cell
+    for (uint32_t i = num_cells; i > cursor->cell_num; i--) {
+      memcpy(leaf_node_cell(node, i), leaf_node_cell(node, i - 1),
+             LEAF_NODE_CELL_SIZE);
+    }
+  }
+
+  *(leaf_node_num_cells(node)) += 1;
+  *(leaf_node_key(node, cursor->cell_num)) = key;
+  serialize_row(value, leaf_node_value(node, cursor->cell_num));
+}
+
```

We haven't implemented splitting yet, so we error if the node is full. Next we shift cells one space to the right to make room for the new cell. Then we write the new key/value into the empty space.

Since we assume the tree only has one node, our `execute_insert()` function simply needs to call this helper method:

```diff
 ExecuteResult execute_insert(Statement* statement, Table* table) {
-  if (table->num_rows >= TABLE_MAX_ROWS) {
+  void* node = get_page(table->pager, table->root_page_num);
+  if ((*leaf_node_num_cells(node) >= LEAF_NODE_MAX_CELLS)) {
     return EXECUTE_TABLE_FULL;
   }

   Row* row_to_insert = &(statement->row_to_insert);
   Cursor* cursor = table_end(table);

-  serialize_row(row_to_insert, cursor_value(cursor));
-  table->num_rows += 1;
+  leaf_node_insert(cursor, row_to_insert->id, row_to_insert);

   free(cursor);
```

With those changes, our database should work as before! Except now it returns a "Table Full" error much sooner, since we can't split the root node yet.

How many rows can the leaf node hold?

## Command to Print Constants

I'm adding a new meta command to print out a few constants of interest.

```diff
+void print_constants() {
+  printf("ROW_SIZE: %d\n", ROW_SIZE);
+  printf("COMMON_NODE_HEADER_SIZE: %d\n", COMMON_NODE_HEADER_SIZE);
+  printf("LEAF_NODE_HEADER_SIZE: %d\n", LEAF_NODE_HEADER_SIZE);
+  printf("LEAF_NODE_CELL_SIZE: %d\n", LEAF_NODE_CELL_SIZE);
+  printf("LEAF_NODE_SPACE_FOR_CELLS: %d\n", LEAF_NODE_SPACE_FOR_CELLS);
+  printf("LEAF_NODE_MAX_CELLS: %d\n", LEAF_NODE_MAX_CELLS);
+}
+
@@ -294,6 +376,14 @@ MetaCommandResult do_meta_command(InputBuffer* input_buffer, Table* table) {
   if (strcmp(input_buffer->buffer, ".exit") == 0) {
     db_close(table);
     exit(EXIT_SUCCESS);
+  } else if (strcmp(input_buffer->buffer, ".constants") == 0) {
+    printf("Constants:\n");
+    print_constants();
+    return META_COMMAND_SUCCESS;
   } else {
     return META_COMMAND_UNRECOGNIZED_COMMAND;
   }
```

I'm also adding a test so we get alerted when those constants change:
```diff
+  it 'prints constants' do
+    script = [
+      ".constants",
+      ".exit",
+    ]
+    result = run_script(script)
+
+    expect(result).to match_array([
+      "db > Constants:",
+      "ROW_SIZE: 293",
+      "COMMON_NODE_HEADER_SIZE: 6",
+      "LEAF_NODE_HEADER_SIZE: 10",
+      "LEAF_NODE_CELL_SIZE: 297",
+      "LEAF_NODE_SPACE_FOR_CELLS: 4086",
+      "LEAF_NODE_MAX_CELLS: 13",
+      "db > ",
+    ])
+  end
```

So our table can hold 13 rows right now!

## Tree Visualization

To help with debugging and visualization, I'm also adding a meta command to print out a representation of the btree.

```diff
+void print_leaf_node(void* node) {
+  uint32_t num_cells = *leaf_node_num_cells(node);
+  printf("leaf (size %d)\n", num_cells);
+  for (uint32_t i = 0; i < num_cells; i++) {
+    uint32_t key = *leaf_node_key(node, i);
+    printf("  - %d : %d\n", i, key);
+  }
+}
+
```

```diff
@@ -294,6 +376,14 @@ MetaCommandResult do_meta_command(InputBuffer* input_buffer, Table* table) {
   if (strcmp(input_buffer->buffer, ".exit") == 0) {
     db_close(table);
     exit(EXIT_SUCCESS);
+  } else if (strcmp(input_buffer->buffer, ".btree") == 0) {
+    printf("Tree:\n");
+    print_leaf_node(get_page(table->pager, 0));
+    return META_COMMAND_SUCCESS;
   } else if (strcmp(input_buffer->buffer, ".constants") == 0) {
     printf("Constants:\n");
     print_constants();
     return META_COMMAND_SUCCESS;
   } else {
     return META_COMMAND_UNRECOGNIZED_COMMAND;
   }
```

And a test

```diff
+  it 'allows printing out the structure of a one-node btree' do
+    script = [3, 1, 2].map do |i|
+      "insert #{i} user#{i}<EMAIL_ADDRESS>+    end
+    script << ".btree"
+    script << ".exit"
+    result = run_script(script)
+
+    expect(result).to match_array([
+      "db > Executed.",
+      "db > Executed.",
+      "db > Executed.",
+      "db > Tree:",
+      "leaf (size 3)",
+      "  - 0 : 3",
+      "  - 1 : 1",
+      "  - 2 : 2",
+      "db > "
+    ])
+  end
```

Uh oh, we're still not storing rows in sorted order. You'll notice that `execute_insert()` inserts into the leaf node at the position returned by `table_end()`. So rows are stored in the order they were inserted, just like before.

## Next Time

This all might seem like a step backwards. Our database now stores fewer rows than it did before, and we're still storing rows in unsorted order. But like I said at the beginning, this is a big change and it's important to break it up into manageable steps.

Next time, we'll implement finding a record by primary key, and start storing rows in sorted order.

## Complete Diff

```diff
@@ -62,29 +62,101 @@ const uint32_t ROW_SIZE = ID_SIZE + USERNAME_SIZE + EMAIL_SIZE;

 const uint32_t PAGE_SIZE = 4096;
 #define TABLE_MAX_PAGES 100
-const uint32_t ROWS_PER_PAGE = PAGE_SIZE / ROW_SIZE;
-const uint32_t TABLE_MAX_ROWS = ROWS_PER_PAGE * TABLE_MAX_PAGES;

 typedef struct {
   int file_descriptor;
   uint32_t file_length;
+  uint32_t num_pages;
   void* pages[TABLE_MAX_PAGES];
 } Pager;

 typedef struct {
   Pager* pager;
-  uint32_t num_rows;
+  uint32_t root_page_num;
 } Table;

 typedef struct {
   Table* table;
-  uint32_t row_num;
+  uint32_t page_num;
+  uint32_t cell_num;
   bool end_of_table;  // Indicates a position one past the last element
 } Cursor;

+typedef enum { NODE_INTERNAL, NODE_LEAF } NodeType;
+
+/*
+ * Common Node Header Layout
+ */
+const uint32_t NODE_TYPE_SIZE = sizeof(uint8_t);
+const uint32_t NODE_TYPE_OFFSET = 0;
+const uint32_t IS_ROOT_SIZE = sizeof(uint8_t);
+const uint32_t IS_ROOT_OFFSET = NODE_TYPE_SIZE;
+const uint32_t PARENT_POINTER_SIZE = sizeof(uint32_t);
+const uint32_t PARENT_POINTER_OFFSET = IS_ROOT_OFFSET + IS_ROOT_SIZE;
+const uint8_t COMMON_NODE_HEADER_SIZE =
+    NODE_TYPE_SIZE + IS_ROOT_SIZE + PARENT_POINTER_SIZE;
+
+/*
+ * Leaf Node Header Layout
+ */
+const uint32_t LEAF_NODE_NUM_CELLS_SIZE = sizeof(uint32_t);
+const uint32_t LEAF_NODE_NUM_CELLS_OFFSET = COMMON_NODE_HEADER_SIZE;
+const uint32_t LEAF_NODE_HEADER_SIZE =
+    COMMON_NODE_HEADER_SIZE + LEAF_NODE_NUM_CELLS_SIZE;
+
+/*
+ * Leaf Node Body Layout
+ */
+const uint32_t LEAF_NODE_KEY_SIZE = sizeof(uint32_t);
+const uint32_t LEAF_NODE_KEY_OFFSET = 0;
+const uint32_t LEAF_NODE_VALUE_SIZE = ROW_SIZE;
+const uint32_t LEAF_NODE_VALUE_OFFSET =
+    LEAF_NODE_KEY_OFFSET + LEAF_NODE_KEY_SIZE;
+const uint32_t LEAF_NODE_CELL_SIZE = LEAF_NODE_KEY_SIZE + LEAF_NODE_VALUE_SIZE;
+const uint32_t LEAF_NODE_SPACE_FOR_CELLS = PAGE_SIZE - LEAF_NODE_HEADER_SIZE;
+const uint32_t LEAF_NODE_MAX_CELLS =
+    LEAF_NODE_SPACE_FOR_CELLS / LEAF_NODE_CELL_SIZE;
+
+uint32_t* leaf_node_num_cells(void* node) {
+  return node + LEAF_NODE_NUM_CELLS_OFFSET;
+}
+
+void* leaf_node_cell(void* node, uint32_t cell_num) {
+  return node + LEAF_NODE_HEADER_SIZE + cell_num * LEAF_NODE_CELL_SIZE;
+}
+
+uint32_t* leaf_node_key(void* node, uint32_t cell_num) {
+  return leaf_node_cell(node, cell_num);
+}
+
+void* leaf_node_value(void* node, uint32_t cell_num) {
+  return leaf_node_cell(node, cell_num) + LEAF_NODE_KEY_SIZE;
+}
+
+void print_constants() {
+  printf("ROW_SIZE: %d\n", ROW_SIZE);
+  printf("COMMON_NODE_HEADER_SIZE: %d\n", COMMON_NODE_HEADER_SIZE);
+  printf("LEAF_NODE_HEADER_SIZE: %d\n", LEAF_NODE_HEADER_SIZE);
+  printf("LEAF_NODE_CELL_SIZE: %d\n", LEAF_NODE_CELL_SIZE);
+  printf("LEAF_NODE_SPACE_FOR_CELLS: %d\n", LEAF_NODE_SPACE_FOR_CELLS);
+  printf("LEAF_NODE_MAX_CELLS: %d\n", LEAF_NODE_MAX_CELLS);
+}
+
+void print_leaf_node(void* node) {
+  uint32_t num_cells = *leaf_node_num_cells(node);
+  printf("leaf (size %d)\n", num_cells);
+  for (uint32_t i = 0; i < num_cells; i++) {
+    uint32_t key = *leaf_node_key(node, i);
+    printf("  - %d : %d\n", i, key);
+  }
+}
+
 void print_row(Row* row) {
     printf("(%d, %s, %s)\n", row->id, row->username, row->email);
 }
@@ -101,6 +173,8 @@ void deserialize_row(void *source, Row* destination) {
     memcpy(&(destination->email), source + EMAIL_OFFSET, EMAIL_SIZE);
 }

+void initialize_leaf_node(void* node) { *leaf_node_num_cells(node) = 0; }
+
 void* get_page(Pager* pager, uint32_t page_num) {
   if (page_num > TABLE_MAX_PAGES) {
     printf("Tried to fetch page number out of bounds. %d > %d\n", page_num,
@@ -128,6 +202,10 @@ void* get_page(Pager* pager, uint32_t page_num) {
     }

     pager->pages[page_num] = page;
+
+    if (page_num >= pager->num_pages) {
+      pager->num_pages = page_num + 1;
+    }
   }

   return pager->pages[page_num];
@@ -136,8 +214,12 @@ void* get_page(Pager* pager, uint32_t page_num) {
 Cursor* table_start(Table* table) {
   Cursor* cursor = malloc(sizeof(Cursor));
   cursor->table = table;
-  cursor->row_num = 0;
-  cursor->end_of_table = (table->num_rows == 0);
+  cursor->page_num = table->root_page_num;
+  cursor->cell_num = 0;
+
+  void* root_node = get_page(table->pager, table->root_page_num);
+  uint32_t num_cells = *leaf_node_num_cells(root_node);
+  cursor->end_of_table = (num_cells == 0);

   return cursor;
 }
@@ -145,24 +227,28 @@ Cursor* table_start(Table* table) {
 Cursor* table_end(Table* table) {
   Cursor* cursor = malloc(sizeof(Cursor));
   cursor->table = table;
-  cursor->row_num = table->num_rows;
+  cursor->page_num = table->root_page_num;
+
+  void* root_node = get_page(table->pager, table->root_page_num);
+  uint32_t num_cells = *leaf_node_num_cells(root_node);
+  cursor->cell_num = num_cells;
   cursor->end_of_table = true;

   return cursor;
 }

 void* cursor_value(Cursor* cursor) {
-  uint32_t row_num = cursor->row_num;
-  uint32_t page_num = row_num / ROWS_PER_PAGE;
+  uint32_t page_num = cursor->page_num;
   void* page = get_page(cursor->table->pager, page_num);
-  uint32_t row_offset = row_num % ROWS_PER_PAGE;
-  uint32_t byte_offset = row_offset * ROW_SIZE;
-  return page + byte_offset;
+  return leaf_node_value(page, cursor->cell_num);
 }

 void cursor_advance(Cursor* cursor) {
-  cursor->row_num += 1;
-  if (cursor->row_num >= cursor->table->num_rows) {
+  uint32_t page_num = cursor->page_num;
+  void* node = get_page(cursor->table->pager, page_num);
+
+  cursor->cell_num += 1;
+  if (cursor->cell_num >= (*leaf_node_num_cells(node))) {
     cursor->end_of_table = true;
   }
 }
@@ -185,6 +271,12 @@ Pager* pager_open(const char* filename) {
   Pager* pager = malloc(sizeof(Pager));
   pager->file_descriptor = fd;
   pager->file_length = file_length;
+  pager->num_pages = (file_length / PAGE_SIZE);
+
+  if (file_length % PAGE_SIZE != 0) {
+    printf("Db file is not a whole number of pages. Corrupt file.\n");
+    exit(EXIT_FAILURE);
+  }

   for (uint32_t i = 0; i < TABLE_MAX_PAGES; i++) {
     pager->pages[i] = NULL;
@@ -194,11 +285,15 @@ Pager* pager_open(const char* filename) {
@@ -195,11 +287,16 @@ Pager* pager_open(const char* filename) {

 Table* db_open(const char* filename) {
   Pager* pager = pager_open(filename);
-  uint32_t num_rows = pager->file_length / ROW_SIZE;

   Table* table = malloc(sizeof(Table));
   table->pager = pager;
-  table->num_rows = num_rows;
+  table->root_page_num = 0;
+
+  if (pager->num_pages == 0) {
+    // New database file. Initialize page 0 as leaf node.
+    void* root_node = get_page(pager, 0);
+    initialize_leaf_node(root_node);
+  }

   return table;
 }
@@ -234,7 +331,7 @@ void close_input_buffer(InputBuffer* input_buffer) {
     free(input_buffer);
 }

-void pager_flush(Pager* pager, uint32_t page_num, uint32_t size) {
+void pager_flush(Pager* pager, uint32_t page_num) {
   if (pager->pages[page_num] == NULL) {
     printf("Tried to flush null page\n");
     exit(EXIT_FAILURE);
@@ -242,7 +337,7 @@ void pager_flush(Pager* pager, uint32_t page_num, uint32_t size) {
@@ -249,7 +346,7 @@ void pager_flush(Pager* pager, uint32_t page_num, uint32_t size) {
   }

   ssize_t bytes_written =
-      write(pager->file_descriptor, pager->pages[page_num], size);
+      write(pager->file_descriptor, pager->pages[page_num], PAGE_SIZE);

   if (bytes_written == -1) {
     printf("Error writing: %d\n", errno);
@@ -252,29 +347,16 @@ void pager_flush(Pager* pager, uint32_t page_num, uint32_t size) {
@@ -260,29 +357,16 @@ void pager_flush(Pager* pager, uint32_t page_num, uint32_t size) {

 void db_close(Table* table) {
   Pager* pager = table->pager;
-  uint32_t num_full_pages = table->num_rows / ROWS_PER_PAGE;

-  for (uint32_t i = 0; i < num_full_pages; i++) {
+  for (uint32_t i = 0; i < pager->num_pages; i++) {
     if (pager->pages[i] == NULL) {
       continue;
     }
-    pager_flush(pager, i, PAGE_SIZE);
+    pager_flush(pager, i);
     free(pager->pages[i]);
     pager->pages[i] = NULL;
   }

-  // There may be a partial page to write to the end of the file
-  // This should not be needed after we switch to a B-tree
-  uint32_t num_additional_rows = table->num_rows % ROWS_PER_PAGE;
-  if (num_additional_rows > 0) {
-    uint32_t page_num = num_full_pages;
-    if (pager->pages[page_num] != NULL) {
-      pager_flush(pager, page_num, num_additional_rows * ROW_SIZE);
-      free(pager->pages[page_num]);
-      pager->pages[page_num] = NULL;
-    }
-  }
-
   int result = close(pager->file_descriptor);
   if (result == -1) {
     printf("Error closing db file.\n");
@@ -305,6 +389,14 @@ MetaCommandResult do_meta_command(InputBuffer* input_buffer, Table *table) {
   if (strcmp(input_buffer->buffer, ".exit") == 0) {
     db_close(table);
     exit(EXIT_SUCCESS);
+  } else if (strcmp(input_buffer->buffer, ".btree") == 0) {
+    printf("Tree:\n");
+    print_leaf_node(get_page(table->pager, 0));
+    return META_COMMAND_SUCCESS;
+  } else if (strcmp(input_buffer->buffer, ".constants") == 0) {
+    printf("Constants:\n");
+    print_constants();
+    return META_COMMAND_SUCCESS;
   } else {
     return META_COMMAND_UNRECOGNIZED_COMMAND;
   }
@@ -354,16 +446,39 @@ PrepareResult prepare_statement(InputBuffer* input_buffer,
   return PREPARE_UNRECOGNIZED_STATEMENT;
 }

+void leaf_node_insert(Cursor* cursor, uint32_t key, Row* value) {
+  void* node = get_page(cursor->table->pager, cursor->page_num);
+
+  uint32_t num_cells = *leaf_node_num_cells(node);
+  if (num_cells >= LEAF_NODE_MAX_CELLS) {
+    // Node full
+    printf("Need to implement splitting a leaf node.\n");
+    exit(EXIT_FAILURE);
+  }
+
+  if (cursor->cell_num < num_cells) {
+    // Make room for new cell
+    for (uint32_t i = num_cells; i > cursor->cell_num; i--) {
+      memcpy(leaf_node_cell(node, i), leaf_node_cell(node, i - 1),
+             LEAF_NODE_CELL_SIZE);
+    }
+  }
+
+  *(leaf_node_num_cells(node)) += 1;
+  *(leaf_node_key(node, cursor->cell_num)) = key;
+  serialize_row(value, leaf_node_value(node, cursor->cell_num));
+}
+
 ExecuteResult execute_insert(Statement* statement, Table* table) {
-  if (table->num_rows >= TABLE_MAX_ROWS) {
+  void* node = get_page(table->pager, table->root_page_num);
+  if ((*leaf_node_num_cells(node) >= LEAF_NODE_MAX_CELLS)) {
     return EXECUTE_TABLE_FULL;
   }

   Row* row_to_insert = &(statement->row_to_insert);
   Cursor* cursor = table_end(table);

-  serialize_row(row_to_insert, cursor_value(cursor));
-  table->num_rows += 1;
+  leaf_node_insert(cursor, row_to_insert->id, row_to_insert);

   free(cursor);
```

And the specs:
```diff
+  it 'allows printing out the structure of a one-node btree' do
+    script = [3, 1, 2].map do |i|
+      "insert #{i} user#{i}<EMAIL_ADDRESS>+    end
+    script << ".btree"
+    script << ".exit"
+    result = run_script(script)
+
+    expect(result).to match_array([
+      "db > Executed.",
+      "db > Executed.",
+      "db > Executed.",
+      "db > Tree:",
+      "leaf (size 3)",
+      "  - 0 : 3",
+      "  - 1 : 1",
+      "  - 2 : 2",
+      "db > "
+    ])
+  end
+
+  it 'prints constants' do
+    script = [
+      ".constants",
+      ".exit",
+    ]
+    result = run_script(script)
+
+    expect(result).to match_array([
+      "db > Constants:",
+      "ROW_SIZE: 293",
+      "COMMON_NODE_HEADER_SIZE: 6",
+      "LEAF_NODE_HEADER_SIZE: 10",
+      "LEAF_NODE_CELL_SIZE: 297",
+      "LEAF_NODE_SPACE_FOR_CELLS: 4086",
+      "LEAF_NODE_MAX_CELLS: 13",
+      "db > ",
+    ])
+  end
 end
```

gha_language: C


text:
# Docker Client in Docker for Jenkins Container

## Synopsis
The primary purpose of running Docker clients in a Docker Jenkins container is to allow the Jenkins system to handle multiple container instances during the CI/CD testing with the development of Docker itself to make the tests to be more efficient, less risky.

You probably have read these articles, [blog post](http://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/) and [git dind](https://github.com/jpetazzo/dind/), and understand about the risks of running multiple Dockers in Docker. By this example, the docker in the Jenkins server acted as a client to the host to prevent from the potential issues as mentioned in the articles.

## Systems / Applications
* OS: Linux RHEL 7.5
* Ansible: 2.7.5
* Docker: 1.13.1
* Jenkins container: 2.121.1 (openshift/jenkins-2-centos7)
* Python: 2.7.5
* Platform: Google Cloud Platform

## Installation
1. git clone https://github.com/joehmchiu/docker-client-in-docker.git
2. cd docker-client-in-docker/
3. run ansible playbook by command:

    $ ansible-playbook -vvv build-my-jenkins.yml
4. Ignore or troubleshoot the errors generated while cleaning the docker containers.
5. When infrastructure completed, prompt the following command to see if the docker process is up:

    $ docker ps -l

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                                NAMES
5f66686982f2        myjenkins           "/usr/bin/dumb-ini..."   About an hour ago   Up About an hour    53/tcp, 8443/tcp, <IP_ADDRESS>:50000->50000/tcp, <IP_ADDRESS>:9191->8080/tcp   romantic_kare

6. Update firewall to allow access going through port 9191.
7. Browse http://<host ip>:9191/ to see if the Jenkins server is online.
8. Please note this version of Jenkins container won't go to the installation process, it goes to an authentication page instead. Type 'foobar' as password to login. BTW, you can change the password in jenkins-container.yml before running ansible playbook.
9. You may run your dockerfile as docker client by Jenkins pipeline to see the docker status by using the following command.

    $ docker stats

CONTAINER           CPU %               MEM USAGE / LIMIT       MEM %               NET I/O             BLOCK I/O           PIDS
2b3e3603e067        0.54%               369.3 MiB / 2.288 GiB   15.76%              6.26 MB / 3.15 MB   97.2 MB / 86.5 MB   130
d9c471e9ff8e        3.13%               516 KiB / 2.288 GiB     0.02%               2.82 kB / 648 B     0 B / 0 B           6
8958a3b1d0dc        0.00%               524 KiB / 2.288 GiB     0.02%               2.56 kB / 578 B     0 B / 0 B           6
a64079f26469        0.20%               532 KiB / 2.288 GiB     0.02%               2.05 kB / 578 B     0 B / 0 B           6
61a520059e50        3.17%               528 KiB / 2.288 GiB     0.02%               1.46 kB / 508 B     0 B / 0 B           6
cf27a7c31488        0.00%               532 KiB / 2.288 GiB     0.02%               1.04 kB / 508 B     0 B / 0 B           6

## Troubleshooting
As you seen the dockerfile is going to add user jenkins to be a sudoer. It's available to become root to troubleshoot if meet any jenkins setup issues in the container. For some reason the jenkins user id in the container was set as 999 instead of 1000 therefore you need to run as user 999 on the running container. eg. running bash session:

* docker exec -u 999 -it <container ID> bash

## License
A short snippet describing the license (MIT, Apache, etc.)

repository: joechiu/docker-client-in-docker

repo_name: joechiu/docker-client-in-docker


text:
## Description

This code replicates the model discussed in the following research
> A. Chadha, R. Dara and Z. Poljak, "Convolutional Classification of Pathogenicity in H5 Avian Influenza Strains," 2019 18th IEEE International Conference On Machine Learning And Applications (ICMLA), Boca Raton, FL, USA, 2019, pp. 1570-1577.

- Within research 1202 HP sequences, 1167 LP sequences were used which were gathered from various sources such as https://www.fludb.org
- This code has yet to collect relevant number of data and works with only 133 HP sequences and 750 LP sequences
- These sequences were collected from https://www.fludb.org only
- They are all HA segments of H5 avian influenza virus of various kinds
- These HA segments are aligned using MUSCLE (Multiple Sequence Comparison by Log-Expectation) algorithm, available [here](https://www.fludb.org/brc/msa.spg?method=ShowCleanInputPage&decorator=influenza)

gha_language: Jupyter Notebook


text:
# Example

This is an example using the AWS SDK for Go to delete an ECR Repository.

# Usage

The example deletes the repository name provided in the first parameter from default `us-east-1` aws region.

```sh
go run -tags example deleteRepository.go <repo_name>
```

To delete a repository from a different region, set `AWS_REGION` env var.

```sh
AWS_REGION=us-west-2 go run -tags example deleteRepository.go <repo_name>
```

Output:
```
ECR Repository "repo2" deleted successfully!

AWS Output:
{
  Repository: {
    CreatedAt: 2020-03-26 00:20:36 +0000 UTC,
    RegistryId: "999999999999",
    RepositoryArn: "arn:aws:ecr:us-east-1:999999999999:repository/repo_name",
    RepositoryName: "repo_name",
    RepositoryUri: "999999999999.dkr.ecr.us-east-1.amazonaws.com/repo_name"
  }
}
```

repository: aws/aws-sdk-go

gha_language: Go

repo_name: aws/aws-sdk-go


text:
# MinDiff Requirements

## When should I use MinDiff?
We recommend applying MinDiff in instances where your model performs well
generally, but produces harmful errors more frequently on examples belonging to
a sensitive group, and you wish to close the performance gap. The sensitive
groups of interest may vary depending on your use case, but often include
protected classes, such as race, religion, gender, sexual orientation, and more.
Throughout this document, we will use “sensitive group” to refer to any set of
examples belonging to a protected class.

There are two primary conditions for using MinDiff to address underperforming
slices of data:

-   You have already tuned and evaluated your model, identifying metrics that
show underperforming slices of data. This must be done *before* applying model
remediation.
-   You have, or can obtain, a sufficient number of relevant labeled examples
belonging to the underperforming group (more details below).

Note: If you’re new to evaluating for fairness, we recommend reviewing this
module in Google’s Machine Learning Crash Course, which provides an introduction
to this topic, and this guide for a broader discussion on the topic.

MinDiff is one of many techniques for remediating unequal behavior. In
particular, it may be a good choice when you’re trying to directly equalize
performance between groups. MinDiff can be used in conjunction with other
approaches, such as data augmentation and others, which may lead to better
results. However, if you need to prioritize which technique to invest in, you
should do so according to your product needs.

When applying MinDiff, you may see performance degrade or shift slightly for
your best performing groups, as your underperforming groups improve. This
tradeoff is expected, and should be evaluated in the context of your product
requirements. In practice, we have often seen that MinDiff does not cause top
performing slices to drop below acceptable levels, but this is application-
specific and a decision that needs to be made by the product owner.

### On what model types can I apply MinDiff?
MinDiff has been shown to be consistently effective when applied to *binary
classifiers.* Adapting the method for other applications is possible, but has
not been fully tested. Some work has been done to show success in multi-
classification and ranking tasks1 but any use of MinDiff on these or
other types of models should be considered experimental.

### On what metrics can I apply MinDiff?
MinDiff may be a good solution when the metric you’re trying to equalize across
groups is *false positive rate (FPR)*, or *false negative rate (FNR)*, but it may
work for other metrics. As a general rule, MinDiff may work when the metric
you’re targeting is a result of differences in the score distributions between
examples belonging to a sensitive group and examples not belonging to a
sensitive group.

## Building your MinDiff dataset
When preparing to train with MinDiff, you’ll need to prepare three separate
datasets. As with regular training, your MinDiff datasets should be
representative of the users your model serves. MinDiff may work without this but
you should use extra caution in such cases.

Assuming you’re trying to improve your model’s FPR for examples belonging to a
sensitive class, you’ll need:
1. The original training set - The original dataset that was used for training
your baseline model
2. The MinDiff sensitive set - A dataset of examples belonging to the sensitive
class with *only* negative ground truth labels. These examples will be used only
for calculating the MinDiff loss.
3. The MinDiff non-sensitive set - A dataset of examples *not* belonging to the
sensitive class with *only* negative ground truth labels. These examples will be
used only for calculating the MinDiff loss.

Note: The examples in your MinDiff datasets may overlap partially, or completely
with your original training dataset.

When using the library, you will combine all three of these datasets into a
single dataset, which will serve as your new training set.

### Picking examples for MinDiff
It may have seemed counterintuitive in the example above to carve out sets of
*negatively* labeled examples if you are primarily concerned with disparities in
*false positive rate*. However, remember that a false positive prediction comes
from a negatively labeled example incorrectly classified as positive.

When collecting your data for MinDiff, you should pick examples where the
disparity in performance is evident. In our example above, this meant choosing
negatively labeled examples to address FPR. Had we been interested in targeting
FNR, we would have needed to choose positively labeled examples.

### How much data do I need?
Good question--it depends on your use case! Based on your model architecture,
data distribution, and MinDiff configuration, the amount of data needed can vary
significantly. In past applications, we have seen MinDiff work well with 5,000
examples in each MinDiff training set (sets 2 and 3 in the previous section).
With less data, there is increased risk of lowered performance, but this may be
minimal or acceptable within the bounds of your production constraints. After
applying MinDiff, you will need to evaluate your results thoroughly to ensure
acceptable performance. If they are unreliable, or do not meet performance
expectations, you may still want to consider gathering more data.

## When is MinDiff *not* right for me?
MinDiff is a powerful technique that can provide impressive results, but this
does not mean that it is the right method for all situations. Applying it
haphazardly does not guarantee that you will achieve an adequate solution.

Beyond the requirements discussed above, there are cases where MinDiff may be
technically feasible, but not suitable. You should always design your ML
workflow according to known recommended practices. For instance, if your model
task is ill-defined, the product needs unclear, or your example labels overly
skewed, you should prioritize addressing these issues. Similarly, if you do not
have a clear definition of the sensitive group, or are unable to reliably
determine whether examples belong to the sensitive group, you will not be able
to apply MinDiff effectively.

At a higher level, you should always consider whether your product is an
appropriate use for ML at all. If it is, consider the potential vectors for user
harm it creates. The pursuit of responsible ML is a multi-faceted effort which
aims to anticipate a broad range of potential harms; MinDiff can help mitigate
some of these, but all outcomes deserve careful consideration.

1Beutel A., Chen, J., Doshi, T., Qian, H., Wei, L., Wu, Y., Heldt,
L., Zhao, Z., Hong, L., Chi, E., Goodrow, C. (2019). [Fairness in Recommendation
Ranking through Pairwise
Comparisons.](https://dl.acm.org/doi/abs/10.1145/3292500.3330745)


text:
# Note
We have discontinued Jaggery based [Unified UI Framework](https://github.com/wso2/carbon-uuf/tree/js-master) and as a result this repository has been deprecated.
***

# UUF Template App
This sample app demonstrate the features and functionality of the
[Unified UI Framework](https://github.com/wso2/carbon-uuf/tree/js-master).

## How to deploy

1. Clone this repository. `git clone https://github.com/wso2-incubator/uuf-template-app.git`

2. Build the project with `mvn clean install`

   Make sure you have built the carbon-uuf  as a maven project before building this project.
   Refer [Carbon-UUF](https://github.com/ChamNDeSilva/carbon-uuf/blob/master/README.md).

3. Extract`uuf-template-app.zip` generated in project target.

4. Copy the extracted `uuf-template-app` to the `<CARBON_PRODUCT_HOME>/repository/deployment/server/jaggeryapps/`
   directory.

5. Navigate to https://localhost:9443/uuf-template-app/.


text:
# Conekta.net.Model.TransferMethodResponse
Method used to make the transfer.

## Properties

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**AccountHolder** | **string** | Name of the account holder. | [optional]
**AccountNumber** | **string** | Account number of the bank account. | [optional]
**Bank** | **string** | Name of the bank. | [optional]
**CreatedAt** | **long** | Date and time of creation of the transfer. | [optional]
**Id** | **string** | Unique identifier of the transfer. | [optional]
**Object** | **string** | Object name, which is bank_transfer_payout_method. | [optional]
**PayeeId** | **string** | Unique identifier of the payee. | [optional]
**Type** | **string** | Type of the payee. | [optional]

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

gha_language: C#


text:
# Peniophora versiformis f. carbonicola (Pat.) Boidin, 1958 FORM

#### Status
SYNONYM

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Bull. trimest. Soc. mycol. Fr. 74(4): 465 (1958)

#### Original name
null

### Remarks
null

repository: mdoering/backbone

path: /life/Fungi/Basidiomycota/Agaricomycetes/Russulales/Peniophoraceae/Peniophora/Peniophora versiformis/ Syn. Peniophora versiformis carbonicola/README.md

repo_name: mdoering/backbone