text:
---
layout: post
title: Approximate Nearest Neighbor Search in Vespa - Part 1
date: '2020-06-30'
toc: true
author: geirst
image: assets/2020-06-30-approximate-nearest-neighbor-search-in-vespa-part-1/search-throughput-sift.png
tags: []
excerpt: In this blog post we explore how the Vespa team selected HNSW (Hierarchical Navigable Small World Graphs)
         as the baseline approximate nearest neighbor algorithm for extension and integration in Vespa.
---

Searching for the nearest neighbors of a data point in a high dimensional vector space is an important problem for many real-time applications.
For example, in Computer Vision it can be used to find similar images in large image datasets.
In Information Retrieval, pre-trained text embeddings can be used to match documents based on the distance between query and document embeddings.
In many of these applications,
the document corpus is constantly evolving and the search is constrained by query filters applied on the metadata of the data points.
For example, in E-commerce,
a nearest neighbor search for products in a vector space would typically be constrained by product metadata like inventory status and price.

[Vespa](https://vespa.ai/) (the open source big data serving engine) already supports exact
[nearest neighbor search](https://docs.vespa.ai/en/nearest-neighbor-search.html)
that is integrated with the Vespa query tree and its filter support.
This enables you to get the exact nearest neighbors meeting the filter criterias of the query.
This works well when the number of documents to calculate nearest neighbors for is small,
e.g when the query filter is strong, or the document corpus is small.
However, as the number of documents to consider increases, we want to trade exactness for performance and we need an approximate solution.

This blog post is part 1 in a series of blog posts where we share how the Vespa team implemented an approximate nearest neighbor (ANN) search algorithm.
In this first post, we'll explain why we selected HNSW (Hierarchical Navigable Small World Graphs)
as the baseline algorithm and how we extended it to meet the requirements for integration in Vespa.
Requirements included supporting real-time updates, integration with the Vespa query tree, and being flexible enough to fit a wide range of use cases.

## Requirements & Challenges
[Vespa](https://vespa.ai/) is an open source real-time big data serving engine.
In a typical application, the document corpus is constantly evolving.
New documents are added and removed, and metadata is being updated.
A typical use case is news article search and recommendation, keeping a week, month or year's worth of articles,
continually adding or updating new articles while selectively removing the oldest ones.
In this case, nearest neighbor search over pre-trained text embeddings could be used in combination with query filters over metadata.

Based on the existing functionality and flexibility of Vespa,
we defined a set of requirements an ANN search algorithm had to support to be a good fit for integration:
* Indexes used in the algorithm must be real-time updateable with low latency and high throughput.
  Data points can be added, updated and removed, and the entire corpus should not be needed when creating the index.
* Concurrent querying with low latency and high throughput without huge performance impact due to ongoing update operations.
* Seamless integration with the Vespa query tree and its filter support.
  This enables correct results, compared to just increasing top K for the nearest neighbor search algorithm to compensate when query filters are used.

## Algorithms Background
There exists a lot of algorithms for ANN search.
Many of these are summarized and analyzed in
[Approximate Nearest Neighbor Search on High Dimensional Data --- Experiments, Analyses, and Improvement (v1.0)](https://arxiv.org/abs/1610.02455)
and
[A Revisit of Hashing Algorithms for Approximate Nearest Neighbor Search](https://arxiv.org/abs/1612.07545).
In addition, benchmark results for different algorithms over different datasets are summarized in
[ANN Benchmarks](http://ann-benchmarks.com/).

Existing algorithms are mainly focused on a stable document corpus where all data points in the vector space are known up front.
In this case the index structure is built once, and then used for nearest neighbor searches.
To support real-time updates, we looked for algorithms that were either incremental in nature or could be modified to meet this requirement.

There are three broad categories of algorithms: tree-based, graph-based and hash-based.
We choose one from each category for a more detailed exploration.
This selection was based on how they performed in benchmarks within papers and in
[ANN Benchmarks](http://ann-benchmarks.com/),
and how easy the algorithm was to modify to fit our requirements.

We ended up with the following:
* **Annoy**
  Annoy is tree-based and described in
  [Nearest neighbors and vector models – part 2 – algorithms and data structures](https://erikbern.com/2015/10/01/nearest-neighbors-and-vector-models-part-2-how-to-search-in-high-dimensional-spaces.html).
  It takes a straightforward engineering approach to the ANN problem, and is quite easy to understand and implement.
  An Annoy index consists of N binary trees, where each tree partitions the vector space using random hyperplanes at each node in the tree.
  The implementation is available on [github](https://github.com/spotify/annoy).
* **HNSW - Hierarchical Navigable Small World Graphs**
  This is graph-based and described in
  [Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs](https://arxiv.org/abs/1603.09320).
  HNSW builds a hierarchical graph incrementally,
  and has great search performance with high recall, motivating us to prototype it for comparison.
  Each node in the graph represents a point in the vector space, and nodes are linked to other nodes that are close in space.
  The implementation is available on [github](https://github.com/nmslib/hnswlib).
* **RPLSH - Random Projection based Locality Sensitive Hashing**
  This is hash-based and described in
  [A Revisit of Hashing Algorithms for Approximate Nearest Neighbor Search](https://arxiv.org/abs/1612.07545).
  The implementation is available on [github](https://github.com/ZJULearning/RPLSH).
  Since the random hyperplanes used for projections can be selected up-front
  (only depending on the number of dimensions of the vector space) this approach is data-independent.
  For our purposes, we could use the hash value as a filter,
  where only documents having most bits in common with the hash value of the query data point would be considered for full distance computation.
  This would give us little extra memory and CPU usage and would be easy to fit into our exact (brute-force) nearest neighbor feature.
  It was the first algorithm that we implemented as a prototype.
  However, in our prototype we found that getting a significant speedup required a large sacrifice of quality.
  For more info, see *Dropping RPLSH* below.

We created prototype implementations of the three algorithms in C++.
This gave us a deeper understanding and the ability to make necessary modifications to support real-time updates and query filters.
The prototypes were also used to do low-level benchmarking and quality testing.

## Prototype Benchmark
We benchmarked the three prototype implementations to look at indexing throughput and search throughput with different document corpus sizes.
We used the
[1M SIFT (128 dim)](http://corpus-texmex.irisa.fr/)
and
[1M GIST (960 dim)](http://corpus-texmex.irisa.fr/)
datasets, where one vector corresponds to a document.
In this section, we summarize the results of the 1M SIFT tests. Findings were similar with the 1M GIST dataset.

### Setup
The tests were executed in a CentOS 7 Docker image using Docker Desktop on a MacBook Pro (15 inch, 2018)
with a 2.6 GHz 6-Core Intel Core i7 CPU and 32GB of memory. The Docker setup was 8 CPUs, 16GB of memory and 1GB of Swap.

The configuration of the algorithms were as follows:
* **Float size**: 4 bytes.
* **Annoy**: Number of trees = 50. Max points in leaf node = 128.
* **HNSW**: Max links per node (M) = 16. Note that level 0 has 32 links per node (2\*M). Number of neighbors to explore at insert (efConstruction) = 200.
* **RPLSH**: 512 bits used for hash and linear scan of hash table.

### Indexing Throughput
The 1M SIFT dataset was split into chunks of first 100k, 200k, and 500k vectors,
and indexing throughput was tested with different corpus sizes.
The index structures for all algorithms started empty, and we added one document at a time to simulate real-time feeding.
One thread was used. Necessary adjustments to the prototype implementations were done to accommodate this.
Note that the data points for 10M documents are estimated based on the 100k and 1M data points.

Observations:
* Indexing throughput depends on corpus size for Annoy and HNSW, where throughput is halved when corpus size is increased by 10x.
* Indexing throughput for RPLSH is independent of corpus size.
* Annoy is **4.5 to 5 times** faster than HNSW.
* RPLSH is **23 to 24 times faster** than HNSW at 1M documents.

### Search Throughput (QPS)
The search throughput was measured after the indexes were built, using a single benchmarking client and search thread.
We used the query vectors from the dataset, and searched for the nearest K=100 neighbors from the query vector.
To get comparable quality results between the algorithms we had to adjust some of the parameters used.
The default behavior for Annoy is to collect K=100 candidates per tree, and then calculate brute force distance for all those.
To get comparable quality between Annoy and HNSW we had to collect 8000 candidates instead of 5000.
For RPLSH, we used the Hamming distance between hashes to pre-filter candidates after collecting 200 candidates into a heap,
skipping full distance calculation for most candidates. For HNSW, we asked for 100 candidates.

Observations:
* HNSW outperforms Annoy and RPLSH. At corpus size 1M the QPS is **9 times as high** as Annoy,
  and **16 times as high** as RPLSH at comparable quality.
  Similar observations between hnswlib and Annoy are found in [ANN Benchmarks](http://ann-benchmarks.com/),
  where the QPS of hnswlib is 5-10 times higher at the same quality on all tested datasets.
* The HNSW search algorithm depends heavily on the number of links between nodes, which again depends on corpus size.
  The QPS is halved when the corpus size is increased by 10x.
  We see the same during indexing as that uses the search algorithm to find candidates to connect to.
* The Annoy search algorithm is less dependent on corpus size, at least with small corpus sizes.
  The static cost is driven by brute force calculation of distances for the candidate set, 8000 in this case.
  With high corpus size the cost of traversing the binary trees will likely match and exceed the static cost.
  We don’t know where this limit is.
* For RPLSH, doing exhaustive search (linear scan) of the hashes is more expensive than expected.
  One major consideration here is that the data reduction (from 128 dimensions\*32 bit floats, to 512 bits hash) is just a factor 8,
  and indeed we got around 8 times speedup compared to brute-force linear scan.

## Index Structures & Memory Usage
The prototype implementations used simple data structures to represent the index structures of the algorithms in memory.
Only one thread was used for indexing and searching and we didn’t have to worry about locking.
These challenges would have to be overcome in the actual implementation of the selected algorithm.
We created a rough index structure design for both Annoy and HNSW to see how much memory the index would use.

In Vespa, a data point in a high dimensional vector space is represented by a
[tensor](https://docs.vespa.ai/en/tensor-user-guide.html)
of rank one with dimension size equal to the dimensionality of the vector space.
To use this, a document type with a tensor field of such type is defined, and documents with tensors are fed to Vespa.
A document type typically consists of multiple other fields as well, for instance, metadata fields and other tensor fields.
The tensors across all documents for a given tensor field are stored in-memory.
The index structures were designed such that they just reference the tensor data points stored in-memory.
In addition, they support one writer thread doing changes, while multiple reader threads are searching, without use of locking.
The actual index structure details for HNSW will be covered in an upcoming blog post.

### Annoy Index
An Annoy index consists of multiple binary trees. Each tree consists of split nodes and leaf nodes.
A split node has an offset from origo, a hyperplane that splits the space in two, and reference to left and right child nodes.
A leaf node contains the document ids of the points that ended up in that portion of space.
The document ids are used to lookup the actual tensor data from memory.

### HNSW Index
An HNSW index consists of navigable small world graphs in a hierarchy.
Each document in the index is represented by a single graph node.
Each node has an array of levels, from level 0 to n.
The number of levels is constant during the lifetime of the node and is drawn randomly when the node is created.
All nodes have at least level 0.
At each level there is a link array which contains the document ids of the nodes it is connected to at that level.
The document ids are used to lookup the actual tensor data points from memory.

### Memory Usage Summary
The following summarizes the memory usage of the Annoy and HNSW indexes over the 1M SIFT dataset.
The configuration is the same as used on the prototypes when benchmarking indexing and search.
The memory usage for storing the hash values in RPLSH, 512 bits per document, is also shown for reference.

Observations:
* The Annoy index is almost 3 times larger than the HNSW index, which results in ~40% more total memory usage in the 1M SIFT dataset.
* Both indexes are independent of dimension size, but max points in a leaf node (Annoy)
  and max links per level (HNSW) might need adjustments with higher dimensionality to get decent quality.

| | ** Annoy index ** | ** HNSW index ** | ** RPLSH hash ** |
| :--- | :----: | :----: | :----: |
| Total tensor size (MB) | 488 | 488 | 488 |
| Total index size (MB)  | 387 | 134 | 61  |
| Total size (MB)        | 875 | 622 | 549 |
| Index percent of total | 44% | 22% | 11% |

## Dropping RPLSH
To get good quality (recall) with RPLSH we found that a large hash size was needed.
Running a quality benchmark on the SIFT dataset with 1M data points,
shows the recall (as percentage of correct hits when asking for top K=100) is bad with a 64 bit hash.
You would need to do a full distance calculation for 25000 documents just to get 80% recall.
We worked mostly with a 512-bit hash, where (on average) you should get 80% recall with just 600 candidates, and 90% recall with 1200 candidates.

With 512-bit hashes, doing a linear scan of the table of hash values doesn’t scale well,
and some sort of index structure to search in the transformed space is necessary.

## Choosing HNSW
Several factors were considered when choosing HNSW as the algorithm to use as a baseline for integration in Vespa.
We needed an algorithm with good performance and low resource usage, that was possible to extend and integrate in Vespa.

As seen in the previous section, none of the algorithms have both good indexing and search performance.
We needed to make tradeoffs. As stated in the introduction,
an approximate algorithm is needed to improve the search performance compared to the exact algorithm already supported in Vespa.
Based on this criteria alone, HNSW is the clear winner.
Indexing performance is worse, but this is a tradeoff worth taking for the most common Vespa use cases.
This is the reason indexing is done in the first place, to prepare data structures such that search is fast.
Also, the index structure for HNSW uses significantly less memory than Annoy.

HNSW is also a good fit when it comes to the simplicity of integration in Vespa.
Building the index is inherently incremental, so adding new data points in real-time is already handled.
The Annoy algorithm must be changed to get similar functionality, as it uses all data points when drawing the random hyperplane splits.
Removing data points is also handled in HNSW by having a “deleted” flag on each data point,
but this is not a solution that will work well in Vespa.
Datasets typically evolve over a long period of time, and the size of the index would just keep on growing, dominated by deleted points.
We addressed this with an explicit remove strategy that removes nodes from the graph while re-linking the neighbors.
The details will be described in the next blog post.

The last requirement for the chosen algorithm is that it works well with query filters.
We experimented with a 2-phase solution for both the HNSW and Annoy prototypes.
First, only the query filter is evaluated, resulting in the set of document ids passing the filter.
Then this set is used in the search algorithm to only select neighbors that passed the filter.
This is a simple and effective solution that works well when the amount of documents that are filtered away is not too high.

## Exact vs Approximate
In prototype testing with the 1M SIFT dataset we observed that when more than 90-95% of the documents were filtered away,
calculating the exact nearest neighbors after filtering was cheaper than searching the HNSW index with the filter discarding candidate hits.
This is illustrated in the graph below.

## Conclusion
In this blog post, we explored how the Vespa team selected HNSW (Hierarchical Navigable Small World Graphs)
as the baseline approximate nearest neighbor algorithm for integration in Vespa.
We needed an algorithm that could be extended to support real-time updates and work together with query filters.
Benchmarking showed that HNSW has superior search performance and uses significantly less memory than Annoy.
Building of the index is also inherently incremental. In addition we created a strategy for supporting proper removes.

In the next blog post, we will look at the actual index structure details for HNSW and how we implemented and integrated it in Vespa.

repository: vespa-engine/blog

repo_name: vespa-engine/blog


text:
# Markdown Worm

---
![logo](res/img/logo.jpg)

A very simple markdown viewer implemented by PHP, [ParseDown](http://parsedown.org) and [Mou](http://25.io/mou/)

[中文版说明](README_CN.md)

## What is Markdown ?

Markdown is a lightweight markup language with plain text formatting syntax designed so that it can be converted to HTML and many other formats using a tool by the same name. Markdown is often used to format readme files, for writing messages in online discussion forums, and to create rich text using a plain text editor.

BTW, this paragraph is written in Markdown too.

## Use Case

I use markdown everyday for writing technology & problem notes, but what is a easier way for you share them,
especially between colleages ? For example, someday Dave asks you 'Dude, have you ran into this problem before?

'Yes!' you say, 'I wrote a Markdown file about it, and it has been uploaded to my server at http://<IP_ADDRESS>/mdWorm'

'A FTP server ?' Dave asked.

'No!' you say, 'When you visit the page, the PHP code converts the markdown file to HTML for you so you don't have to download anything at all!'

## Showcase
###1. Markdown File List

![logo](res/img/showcase_1.jpg)

###2. Converted by Parsedown and displayed by CSS from Mou

![logo](res/img/showcase_2.jpg)

## Install

### Mac & Win

1. Install [XAMPP](https://www.apachefriends.org/index.html)

2. Download mdWorm & Unzip it to `xampp/htdocs`
3. under XAMPP GUI, start Apache Server
4. Open browser and type `localhost/mdWorm`

### RHEL & CentOS

1. Install httpd

		sudo yum install httpd

2. Install PHP

		sudo yum install php

3. Download mdWorm & Unzip it to `/var/www/html`

		cd /var/www/html
		wget <mdWorm-release-tarball>
		tar -zxvf <mdWorm-release-tarball>

4. Start Apache Server

		service httpd start

5. Open browser and type

		localhost/mdWorm

### Debian & Ubuntu
1. Install apache2

		sudo apt-get install apache2

2. Install PHP

		sudo apt-get install php5 libapache2-mod-php5

3. Download mdWorm & and unzip to`/var/www/html`

		cd /var/www/html
		wget <mdWorm-release-tarball>
		tar -zxvf <mdWorm-release-tarball>

4. Start Apache Server

		service apache2 start

5. Open browser and type

		localhost/mdWorm

### MIT License

===
Beichen Li 2016-8-29

license: MIT

branch_name: refs/heads/master

extension: md

license_type: permissive


text:
2.3
---
* Added missing `{-# INLINE #-}` pragmas
* Renamed `meanwhile` to `throughout` in `Control.Parallel.Strategies.Lens`

2.2
---
* Added `<&=`, `<&~`, `<|=`, and `<|~`
* Moved `<>~`, `<<>~`, `<>=`, and `<<>=` to `Data.Monoid.Lens`
* Template Haskell now uses eager binding to avoid adding dependencies.

2.1
---
* Renamed `adjust` to `over`
* Added `au`, `auf` and `under`
* Added `Data.Monoid.Lens`
* Increased lower dependency bound on `mtl` for cleaner installation.

repository: mvv/lens

extension: markdown

repo_name: mvv/lens


text:
---
title: "Accounting Metrics"
linkTitle: "Accounting Metrics"
weight:
description: >
  Exposing of Accounting Metrics
---

## Accounting Metrics
Accounting requires that statistics concerning site usage, performance, etc. can be collected. For this the IOP exposes certain metrics which, via an http metrics service, can be gathered periodically by external monitoring services.

The precise metrics that can be monitored are defined in the Reva metrics package.

### Available Accounting Metrics
The following accounting metrics are available in the metrics package (https://github.com/cs3org/reva/tree/master/pkg/metrics):

1. Number of users per site
2. Number of groups per site
3. Amount of storage per site

### Formats and Exporting
The metrics package uses [OpenCensus](https://opencensus.io/) for implementation of the statistical data types and exporting of the metrics in [Prometheus](https://prometheus.io/) exposition format.

A response of the http metrics service to a single GET metrics request contains all defined metrics.

repository: marpapdtu/sciencemesh

repo_name: marpapdtu/sciencemesh


text:
# [`sidroberts/beanstalkd`](https://hub.docker.com/r/sidroberts/beanstalkd)

Docker image for [Beanstalkd](https://beanstalkd.github.io/).

[![Build Status](https://img.shields.io/travis/SidRoberts/docker-beanstalkd/master.svg?style=for-the-badge)](https://travis-ci.org/SidRoberts/docker-beanstalkd)
[![GitHub release](https://img.shields.io/github/release/SidRoberts/docker-beanstalkd.svg?style=for-the-badge)]()

[![GitHub issues](https://img.shields.io/github/issues-raw/SidRoberts/docker-beanstalkd.svg?style=for-the-badge)](https://github.com/SidRoberts/docker-beanstalkd/issues)
[![GitHub pull requests](https://img.shields.io/github/issues-pr-raw/SidRoberts/docker-beanstalkd.svg?style=for-the-badge)](https://github.com/SidRoberts/docker-beanstalkd/pulls)

## License

Licensed under the MIT License.
© [Sid Roberts](https://github.com/SidRoberts)

repository: SidRoberts/docker-beanstalkd

repo_name: SidRoberts/docker-beanstalkd


text:
# Public Teleport AMI IDs

For your convenience, this is a list of public Teleport AMI IDs which are published by Gravitational. This list
is updated when new AMI versions are released.

repository: gabeio/teleport

repo_name: gabeio/teleport


text:
# pdfi-dev

[![latest version published to npm](https://badge.fury.io/js/pdfi-dev.svg)](https://www.npmjs.com/package/pdfi-dev)

Development tools for [`pdfi`](https://github.com/chbrown/pdfi).

Currently builds two files:

* `./build/glyphlist.ts` -> `pdfi/encoding/glyphlist.ts`
* `./build/glyphmaps.ts` -> `pdfi/encoding/glyphmaps.ts`

## License

Copyright 2016–2018 Christopher Brown.
[MIT Licensed](https://chbrown.github.io/licenses/MIT/#2016-2018).

repository: chbrown/pdfi-dev

repo_name: chbrown/pdfi-dev


text:
# Chef Cookie Cutter

This project is archived as of 2018-07-30.

Cookie Cutter is a Ruby Gem / Chef Cookbook combination, that extends the Chef
cookbook DSL with new features and possibilities.

It is mostly the result of me screwing around with Chef and Ruby metaprogramming.
It's motivation is purely educational and never intended to end up in anything
production critical.

Many of the features are questionable hacks. The documentation is crap, tests
are almost nonexistent and there never was any release workflow. There are
still some nifty bits and pieces in here, so if you find anything you like,
feel free to copy it at your leisure. Since I stopped development on the project
and archived it, I put everything into public domain.

license: Unlicense

repository: oclaussen/chef-cookie-cutter

gha_language: Ruby

repo_name: oclaussen/chef-cookie-cutter


text:
Installation
------------

If you have Anaconda Python, you can install yt using conda:

conda install yt

For any other Python distribution, you can install with pip:

pip install yt

Either of these methods should work on Linux, macOS, and Windows for 64-bit platforms. If you have a 32-bit Linux platform, pip is guaranteed to work. 32-bit Windows is not supported.

Please make sure that Jupyter is also installed (via the same methods). If you have issues with installation please show up at 9 am to get help.

Sample Datasets
---------------

The following datasets will need to be downloaded from http://yt-project.org/data:

http://yt-project.org/data/MHDSloshing.tar.gz
http://yt-project.org/data/IsolatedGalaxy.tar.gz
http://yt-project.org/data/snapshot_033.tar.gz

These are necessary to run the examples.

Jupyter Notebooks
-----------------

Please download the notebooks at http://github.com/jzuhone/cfa_yt_workshop so you
can follow along. Untar the sample data directories into the same directory as
these notebooks.

Houdini
-------

For those of you who would like to stay in the afternoon and learn how to use yt
to read your data into the industry standard Visual Effects package Houdini,
please download Houdini (the free version is fine) following these instructions
here: http://www.ytini.com/getstarted.html

Also please download the two *.hip* files here: http://www.ytini.com/listofHoudiniFiles.html

repository: CfA-Library/Training

repo_name: CfA-Library/Training


text:
---
name: senn-review
layout: post
title: Sennheiser HD595 Review
time: 2011-03-05 02:29:00 +00:00
---
During last summer I purchased a set of Sennheiser HD595's - a
great product for Audiophiles. I have to say for someone who constantly
listens to a lot of music - good headphones like these are a must. They
are expensive for sure, but Sennheiser do seem to have a great durability
and solid build quality. This is my first set of such high quality headphones,
so bear that in mind - I can't speak for other manufacturers in this space.

The greatest and most valuable aspect is the wear time of these headphones. Any
other cheap headphones I've bought, I'd always feel after 20-30 minutes my
ears would be burning. It's easy to forget these long periods of wear until
you have a very long Skype call. You start to wish the call was over to rest
your poor ears! The selling point of this particular model is that they are
faithful to the sound that's meant to be heard. Surely that's what you want to hear?
For some people that's not the case and you'll find them buying Dr. Dre or
Skullcandies finest set of headphones and to be honest more power to them! But
for myself, I  want faithful reproduction and not headphones targeted at a
certain genre - HD595's prove a good fit.

To compensate for the lack of targeting of genres, I've found it necessary to use
an equalizer once or twice - but mainly to satisfy my need for bass or drum cymbals
and reinforce the beat of a song that's probably on too loud for my own good anyway.
Normal people shouldn't be this fussy, but then again most people don't spend this
amount of coin on headphones (as one work colleague remarked to me: Your mad! - after
hearing the cost, he liked the 'phones though). The benchmark song I usually use is the
Robert Miles classic "Children". I think if you can hear all the fine intricacies of
that song, your getting fairly good sound reproduction, in my humble opinion.

In the end all I really wanted was a portable alternative to my Creative 7.1 surround
sound system (which I reviewed here a few years back) but having said that I was under
no illusion headphones could replace a very-powerful, room oriented acoustics. HD595's
do the best job I could have ask of them - but one major gripe is the are not portable
music player friendly. Why? 6.3mm as the default jack with a clumsy 6.3 to 3.5mm jack
and the extremely long cord included in the pack. It's great to dock at a desk and with
the included dock adaptor it's more clearly aimed at this type of market. Or maybe Guitar
players with the jack size? I imagine it's probably good for electric guitar players, but
I wouldn't know being allergic to instruments unfortunately. The openear design (it has
holes to allow sound escape at the side of your ears) certainly improves listening, but
will annoy anyone near enough to hear it, so *please* forget these for commuting!! Overall
a great buy if you plan to use them as much as I have and will.


text:
---
title: "Re-Reading Deming’s 14 Points in the Era of Data Science"
source: "New"
date: "2023-05-01"
categories:
- Recommendation
tags:
- Data science
- Quality improvement
output: html_document
---

![Figure 1. Excerpt from article](http://www.pmean.com/new-images/23/re-reading-14-points-01.png)

<div class="notes">

An interesting attempt to adapt Deming's Fourteen Points, written over 40 years ago, to modern data science.

John L. Eltige. Re-Reading Deming’s 14 Points in the Era of Data Science: 14 Questions for Vibrant Management of Statistical Information Systems. Chance Magazine, 2023-04-01. Available in [html format][elt1]

[elt1]: https://chance.amstat.org/2023/04/demings-14-points/

</div>

repository: pmean/build-website

repo_name: pmean/build-website


text:
---
layout: "post"
title: "SQLSaturday #290 - Kiev 2014"
prettydate: "20 September 2014"
---
# SQLSaturday #290 - Kiev 2014

**Event Date**: 09/20/2014 00:00:00

**Event Location**:
- RUS Hotel
- 4 Hospitalna Str
- Kiev, , Ukraine

PDF of Schedule

This event has completed. All data shown below is from the historical XML public data available.

Sessions

Speakers

Sponsors

If there are any data quality issues or corrections needed, please contact the webmaster for this site or submit a pull request for the appropriate file(s).

-----------------------------------------------------------------------------------

# Sessions
This is a list of sessions from the event, based on the schedule in the XML files.

-----------------------------------------------------------------------------------

## Title: Azure SQL Database Tips and Tricks for Beginners

**Abstract**:
Microsoft released SQL Azure more than two years ago - that's enough time for testing (I hope!). So, are you ready to move your data to the Cloud? If you’re considering a business (i.e. a production environment) in the Cloud, you need to think about methods for backing up your data, a backup plan for your data and, eventually, restoring with Red Gate Cloud Services (and not only). In this session, you’ll see the differences, functionality, restrictions, and opportunities in SQL Azure and On-Premise SQL Server 2008/2008 R2/2012. We’ll consider topics such as how to be prepared for backup and restore, and which parts of a cloud environment are most important: keys, triggers, indexes, prices, security, service level agreements, etc.

**Speaker(s):**
- Tobias Koprowski

*Track and Room*: 3. Barcelona - N/A

-----------------------------------------------------------------------------------

## Title: Dealing with Entity Framework 6.1

**Abstract**:
This talk is about new features in Microsoft Entity Framework 6 - the new major release of EF. In December 2012 Entity Framework 6 beta was announced and made publicly available. In October 2013 were released EF 6.00 (major release) and in March 2014 EF 6.1. This is the first new major version of EF since the announcement in 2012 that the product would be Open Sourced. Entity Framework is hosted on CodePlex. This presentation is about the new features, included in EF 6: Async Query and Save, Custom Code First Conventions, Multi-Tenant Migrations, Configurable Migrations History Table, Code-Based Configuration, Dependency Resolution, Updated Provider Model, Enums, Spatial and Better Performance on .NET 4.x, Stored Procedures  Functions in Code First, Connect and also... how to use in Microsoft Azure

**Speaker(s):**
- Mihail Mateev

*Track and Room*: 1. Kyiv - N/A

-----------------------------------------------------------------------------------

## Title:  SQL Server Deep Dive

**Abstract**:
How often do you wonder why SQL Server executes the query in such a way? Why is selecting few records from the table takes a long time? Why SQL Server eats lot of memory? etc. I invite you to join me in this session and look at the architectural components of SQL Server, look at the internal processes of SQL Server, and discuss how it affect performance of your queries.

**Speaker(s):**
- Denis Reznik

*Track and Room*: 1. Kyiv - N/A

-----------------------------------------------------------------------------------

## Title: Я построю свой профайлер, с гридами и кнопками!

**Abstract**:
Давайте напишем целую пачку маленьких, простых, но умных и полезных приложений, которые помогут нам решить ежедневные задачи наблюдения за сервером.

**Speaker(s):**
- Oleksii Kovalov

*Track and Room*: 3. Barcelona - N/A

-----------------------------------------------------------------------------------

## Title: Key-Range Locking — Все тайное становится явным

**Abstract**:
Доклад будет посвящен блокировкам диапазона ключей (Key-Range Locking). Вначале будет рассказано о базовых механизмах, после чего, мы поговорим о некоторых аспектах которые не описаны в MSDN. Дополнительно рассмотрим неявное использование блокировок диапазона ключей в уровне изоляции READ COMMITTED.

**Speaker(s):**
- Vitaliy Popovych

*Track and Room*: 2. New York - N/A

-----------------------------------------------------------------------------------

## Title: Query and Plan Fingerprints

**Abstract**:
Query and Plan Fingerprints впервые появились в SQL Server 2008 и являются довольно мощным механизмом для улучшения производительности систем, генерирующих большое количество ad-hoc запросов, даже если они непараметризированы.
В докладе вы услышите о таких понятиях как parametrization (simple и forced), DMV, plan cache. Немного обсудим работу relational engine и его составных частей - parser, algebrizer, optimizer.

**Speaker(s):**
- Olena Smoliak

*Track and Room*: 4. Amsterdam - N/A

-----------------------------------------------------------------------------------

## Title: Проектирование хранилищ данных для бизнес-аналитики

**Abstract**:
В данном докладе мы познакомимся с  хранилищами данных, методами построения хранилища данных, проектирование справочников и таблиц данных. И в конце доклада построим хранилище данных на MS SQL.

**Speaker(s):**
- Eugene Polonichko

*Track and Room*: 3. Barcelona - N/A

-----------------------------------------------------------------------------------

## Title: Maintenance Plans ad Hoc

**Abstract**:
Maintenance Plans for Beginners (but not only) | Each of experienced administrators used (to some extent) what is called Maintenance Plans - Plans of Conservation. During this session, I'd like to discuss what can be useful for us to provide functionality when we use them and what to look out for. Session at 200 times the forward-300, with the opening of the discussion.

**Speaker(s):**
- Tobias Koprowski

*Track and Room*: 2. New York - N/A

-----------------------------------------------------------------------------------

## Title: MS SQL data types:  features of  conversion

**Abstract**:
Type of  NULL (usage of functions nullif(), isnull(), coalesce()), features of function STR(), implicit conversion and indexes in SQL queries, etc.

**Speaker(s):**
- Andrii Zrobok

*Track and Room*: 2. New York - N/A

-----------------------------------------------------------------------------------

## Title: In-Memory OLTP (Hekaton) в SQL Server 2014 (deep dive)

**Abstract**:
Одно из самых ожидаемых нововведений в SQL Server 2014 - это технология In-Memory OLTP, ранее известная под кодовым именем Hekaton. В этом докладе будут обсуждать особенности архитектуры и специфические настройки системы. Также много внимания будет уделено тем особенностям, с которыми вам придется столкнуться при разработке приложений с использованием In-Memory OLTP.

**Speaker(s):**
- Sergey Olontsev

*Track and Room*: 1. Kyiv - N/A

-----------------------------------------------------------------------------------

## Title: In-Memory OLTP (Hekaton) в SQL Server 2014 (introduction)

**Abstract**:
Одно из самых ожидаемых нововведений в SQL Server 2014 - это технология In-Memory OLTP, ранее известная под кодовым именем Hekaton. В этом докладе мы рассмотрим ее архитектуру, особенности и ограничения. Также уделим внимание некоторым аспектам практического применения In-Memory OLTP.

**Speaker(s):**
- Sergey Olontsev

*Track and Room*: 1. Kyiv - N/A

-----------------------------------------------------------------------------------

## Title: SSIS - Повышение производительности обработки потоков данных

**Abstract**:
SSIS пакет при выполнении съедает много ресурсов?
Или очень долго выполняется?
Тогда заходите на доклад, посвященный оптимизации обработки потоков данных!
Здесь Вы узнаете, как определять размер буфера, устанавливать число потоков выполнения и многое другое.

**Speaker(s):**
- Maksim Garnets

*Track and Room*: 4. Amsterdam - N/A

-----------------------------------------------------------------------------------

## Title: Power BI for Office 365 -  a Complete Self-Service

**Abstract**:
Power BI tools within Excel are available in the cloud with Office 365, allowing customers to access and share BI reports and models across the desktop and web, and all within a managed environment. Power BI for Office 365 includes Power Pivot and Power View, and two new Excel capabilities have been added to allow the over one billion Office 365 users the ability to do more with their data! These two new features are Power Query which was formerly Project Codename “Data Explorer”, and Power Map formerly Project Codename “Geoflow”.

**Speaker(s):**
- Mihail Mateev

*Track and Room*: 4. Amsterdam - N/A

-----------------------------------------------------------------------------------

## Title: Создание надежного перезапускаемого пакета SSIS. Аудит и логирование

**Abstract**:
В докладе поговорим о логирование и аудите ssis пакетов. А также об уровнях изоляции, контрольных точках и обработчиках событий пакета.

**Speaker(s):**
- Eugene Polonichko

*Track and Room*: 4. Amsterdam - N/A

-----------------------------------------------------------------------------------

## Title: Включать иль не включать? Сказочка об индексах

**Abstract**:
Так всё-таки, в чем же разница между обычными индексами  и индексами с included columns?

**Speaker(s):**
- Oleksii Kovalov

*Track and Room*: 2. New York - N/A

-----------------------------------------------------------------------------------

## Title: Database version control

**Abstract**:
The session will describe the typical schemes of the developers work with database and methods how to maintain the database up to date with the history of changes. There will be a demonstration of some methods.

**Speaker(s):**
- Konstantin Proskurdin

*Track and Room*: 3. Barcelona - N/A

-----------------------------------------------------------------------------------

## Speakers
This is a list of speakers from the XML Guidebook records. The details and URLs were valid at the time of the event.

**Sergey Olontsev**

Twitter:  - [SergeyOlontsev](https://www.twitter.com/SergeyOlontsev)

LinkedIn: [Sergey Olontsev](http://linkedin.com/in/sergeyolontsev)

Contact: [http://SergeyOlontsev.com/](http://SergeyOlontsev.com/)

I have been working with SQL Server since SQL Server 2000 version as a database administrator, developer, consultant and trainer, focusing on high availability and disaster recovery solutions, ETL, troubleshooting and performance tuning, developing high performance solutions . I'm a regular speaker at SQL Server user group meetings, SQLSaturday events and other conferences. An owner of MCM certification and MVP award on SQL Server.

**Andrii Zrobok**

LinkedIn: [Andrii Zrobok](https://www.linkedin.com/in/azrobok/)

25+ years of experience in database development: development data-centric applications from scratch, support of legacy databases/applications, data migration tasks, performance tuning,  consulting, database trainer. I have experience with wide range of databases such as  FoxPro for DOS (Fox Software), MS SQL Server (started from version 6.5) , Oracle, Sybase ASE, MySQL, PostgreSQL.
Co-Leader of PASS Local Chapter in Lviv.
Speaker at PASS SQLSaturday conferences (since 2013); PASS Lviv/Vinnitsa/Virtual SQL Server User Group, EPAM IT Week (2015-2017), AIBig Data Day 2019.

**Vitaliy Popovych**

Twitter:  - [https://twitter.com/PopovychVitaliy](https://www.twitter.com/https://twitter.com/PopovychVitaliy)

LinkedIn: [Vitaliy Popovych](https://ua.linkedin.com/in/vitaliipopovych)

Senior Database Developer at  TFG an Intapp Company. Опыт работы с MS SQL Server — более 5 лет.

**Denis Reznik**

Twitter:  - [https://twitter.com/DenisReznik](https://www.twitter.com/https://twitter.com/DenisReznik)

LinkedIn: [Denis Reznik](http://www.linkedin.com/pub/denis-reznik/3/502/234)

Contact: [http://reznik.uneta.com.ua](http://reznik.uneta.com.ua)

Denis Reznik is a Data Architect at Intapp, Inc. He has more than ten years experience in software development, database design, and performance tuning for cloud and on-premises solutions. In 2010 Denis became Microsoft Data Platform MVP and maintains MVP status today. Apart from his professional career, Denis actively participates in the development of the Ukrainian Data Community.

**Oleksii Kovalov**

DBA and DB developer with more than 10 year expirience. SQLSat/SSUG speaker. MCTS, MCITP.
Author of pet-projects ExpressProfiler and SQL Code Guard

**Konstantin Proskurdin**

.NET developer with more than 10 years of experience, experience with MS SQL Server - 8 years.

**Oleksii Kovalov**

DBA and DB developer with more than 10 year expirience. SQLSat/SSUG speaker. MCTS, MCITP.
Author of pet-projects ExpressProfiler and SQL Code Guard

**Tobias Koprowski**

Twitter:  - [@KoprowskiT](https://www.twitter.com/@KoprowskiT)

LinkedIn: [Tobias Koprowski](https://uk.linkedin.com/in/koprowskit)

Contact: [http://koprowskit.eu/geek/](http://koprowskit.eu/geek/)

Founder of Shadowland Consulting. In January 2015 decided to permanently leave Poland and discover new worlds. Actually settled in Hucknall (The Last home of The Byron Family). Community leader focused on SQL Server, SharePoint, security, collaboration and ITIL, DR, BCM, and SLA. Love licensing stuff.

Microsoft Certified Trainer, freelancer, and consultant. Subject Matter Expert at Microsoft. Member of Microsoft Terminology Community, Friends of RedGate PLUS, PASS, ISSA, ACM and more. Since 1st July 2010 Data Platform MVP. Creator of SQLDAY Conference and Conference CEO 2009-2011. Co-Leader of PASS East Midlands Group. Speaker at group meetings and conferences. STEM Ambassador.

Traveler. Coffee Addicted.

**Tobias Koprowski**

Twitter:  - [@KoprowskiT](https://www.twitter.com/@KoprowskiT)

LinkedIn: [Tobias Koprowski](https://uk.linkedin.com/in/koprowskit)

Contact: [http://koprowskit.eu/geek/](http://koprowskit.eu/geek/)

Founder of Shadowland Consulting. In January 2015 decided to permanently leave Poland and discover new worlds. Actually settled in Hucknall (The Last home of The Byron Family). Community leader focused on SQL Server, SharePoint, security, collaboration and ITIL, DR, BCM, and SLA. Love licensing stuff.

Microsoft Certified Trainer, freelancer, and consultant. Subject Matter Expert at Microsoft. Member of Microsoft Terminology Community, Friends of RedGate PLUS, PASS, ISSA, ACM and more. Since 1st July 2010 Data Platform MVP. Creator of SQLDAY Conference and Conference CEO 2009-2011. Co-Leader of PASS East Midlands Group. Speaker at group meetings and conferences. STEM Ambassador.

Traveler. Coffee Addicted.

**Mihail Mateev**

Twitter:  - [mihailmateev](https://www.twitter.com/mihailmateev)

LinkedIn: [Mihail Mateev](http://www.linkedin.com/pub/mihail-mateev/1/6b3/4b1)

Contact: [https://mmateev.wordpress.com/](https://mmateev.wordpress.com/)

Mihail Mateev is a technical consultant, community enthusiast, PASS Regional Mentor for CEE, chapter lead, Microsoft Azure MVP, Microsoft Regional Director. He works as a Senior Solutions Architect at EPAM Systems, focused on Data Platform, IoT and cloud related solutions. He also worked many years like a Technical evangelist in the Infragistics. Last years Mihail was focused on various areas related to technology Microsoft: Data Platform, Visual Studio, ASP.Net, Windows client apps, Data Platform, and Microsoft Azure. Michael also has a PhD in cloud computing area. He is a university lecturer on Smart Homes and Smart Energy IoT Solutions.

**Olena Smoliak**

LinkedIn: [Olena Smoliak](https://www.linkedin.com/in/olenasmoliak)

Senior Software Engineer at Adver-Online
Microsoft Certified Solution Associate (MCSA): SQL Server 2012
Microsoft Certified Technology Specialist (MCTS): SQL Server 2008, Database Development
Vinnitsa Data Platform User Group Leader (#vssug)
Speaker at local user group meetings in Kyiv, L#39;viv, Dnipropetrovsk, SQLSaturday #290 (Kyiv, 2014), Global Russian Virtual Chapter
Participated in organization of Kyiv SQLSaturdays #377, #290 (2014, 2015)

**Eugene Polonichko**

Contact: [http://djeki.blogspot.com/](http://djeki.blogspot.com/)

Немного о себе: Являюсь лидером Донецкой SQL User Group.   BI от Microsoft работаю более 6 лет, начиная с Microsoft Sql Server 2000.
В основном работаю с проектами, которые связаны с построением хранилища данных, кубов, аналитических порталов.

**Maksim Garnets**

SQL/BI Developer at The Frayman Group
Опыт разработки приложений и баз данных более 5-х лет.
Увлекается процессами интеграции данных, оптимизацией запросов.
Решить сложную задачу - дело чести!

**Mihail Mateev**

Twitter:  - [mihailmateev](https://www.twitter.com/mihailmateev)

LinkedIn: [Mihail Mateev](http://www.linkedin.com/pub/mihail-mateev/1/6b3/4b1)

Contact: [https://mmateev.wordpress.com/](https://mmateev.wordpress.com/)

Mihail Mateev is a technical consultant, community enthusiast, PASS Regional Mentor for CEE, chapter lead, Microsoft Azure MVP, Microsoft Regional Director. He works as a Senior Solutions Architect at EPAM Systems, focused on Data Platform, IoT and cloud related solutions. He also worked many years like a Technical evangelist in the Infragistics. Last years Mihail was focused on various areas related to technology Microsoft: Data Platform, Visual Studio, ASP.Net, Windows client apps, Data Platform, and Microsoft Azure. Michael also has a PhD in cloud computing area. He is a university lecturer on Smart Homes and Smart Energy IoT Solutions.

**Sergey Olontsev**

Twitter:  - [SergeyOlontsev](https://www.twitter.com/SergeyOlontsev)

LinkedIn: [Sergey Olontsev](http://linkedin.com/in/sergeyolontsev)

Contact: [http://SergeyOlontsev.com/](http://SergeyOlontsev.com/)

I have been working with SQL Server since SQL Server 2000 version as a database administrator, developer, consultant and trainer, focusing on high availability and disaster recovery solutions, ETL, troubleshooting and performance tuning, developing high performance solutions . I'm a regular speaker at SQL Server user group meetings, SQLSaturday events and other conferences. An owner of MCM certification and MVP award on SQL Server.

**Eugene Polonichko**

Twitter:  - [https://twitter.com/EvgenPolonichko](https://www.twitter.com/https://twitter.com/EvgenPolonichko)

LinkedIn: [Eugene Polonichko](https://www.linkedin.com/in/eugenepolonichko/)

Contact: [https://msolapblog.wordpress.com/](https://msolapblog.wordpress.com/)

Leader of PASS Local Chapter in Donetsk (Ukraine). I work  as DWH/BI architect.  Responsible for designing and developing Data Warehouse and BI solutions with using Microsoft  BI Stack products.

## Sponsors
The following is a list of sponsors that helped fund the event:

- [Intapp](http://www.intapp.com/)

- [Devart](http://www.devart.com/)

- [ApexSQL LLC](http://www.apexsql.com/?utm_source=SQLSaturdaysutm_medium=sponsorlinkutm_campaign=%5BSQLSaturdays-Homepage%5D)

- [Astound](http://sysiq.com/careers)

- [Evernote](http://evernote.com)

- [Infragistics Inc.](http://www.infragistics.com)

- [PluralSight](http://www.pluralsight.com)

- [EPAM](http://www.epam.com/)

- [Luxoft](http://www.luxoft.com/)

- [Kiev ALT.NET](https://www.facebook.com/groups/kievaltnet/)

- [Microsoft Azure Ukraine User Group](https://www.facebook.com/groups/azure.ua/)

- [UNETA](http://uneta.ua/)

- [Dev-Time](http://dev-time.org/)

- [Weekly IT](http://weekly-it.com/)

- [Microsoft Corporation (GAP)](http://www.microsoft.com/en-us/server-cloud/products/sql-server/)

[Back to the SQLSaturday Event List](/past)

[Back to the home page](/index)

repository: red-gate/sql-saturday-website

branch_name: refs/heads/main

repo_name: red-gate/sql-saturday-website


text:
# woocommerce

Woocommerce SDK for Flutter.

## Getting Started
Add the package to your pubspec.yaml and import.

```dart
import 'package:woocommerce/woocommerce.dart';
```
Create an instance of WooCommerce for your project.
#### Example:

```dart
WooCommerce woocommerce = WooCommerce(
  baseUrl: yourBaseUrl,
  consumerKey: yourConsumerKey,
  consumerSecret: consumerSecret);
```

 Parameter, [baseUrl] is the base url of your site. For example, http://me.com, https://me.com or http://my.me.com

 Parameter [consumerKey] is the consumer key provided by WooCommerce, e.g. `ck_12abc34n56j`.

 Parameter [consumerSecret] is the consumer secret provided by WooCommerce, e.g. `cs_1uab8h3s3op`.

 Optional Parameter [apiPath] is the direct url from your baseUrl to your Woo commerce endpoint.
 An example : "/wp-json/wc/v3/"
 This is useful if only you changed your default Wordpress Woocommerce path, otherwise default applies.

 Optional Parameter [isDebug], tells the library if it should print to debug logs.
  /// Useful if you are debuging or in development.

  The goal of Woo Commerce SDK is to make building amazing Ecommerce apps with flutter and Woo Commerce as easy as can be,
  hope it improves your workflow.

## Features.

- User Authentication.
- Customer Management
- Cart Management.
- Order Management.
- Products management.
- Categories.
- Tags.
- Variations.
- Ability to filter on methods that returns a list.
- Supports custom endpoints.
- Shipping, Shipping methods, Shipping Locations.
- Payment.
- Tax, TaxClasses.
- Etc and more.

## Notes.
 Install [Jwt Token Plugin](https://wordpress.org/plugins/jwt-authentication-for-wp-rest-api/), to be able to log in,

## Examples

Put your credentials into the example app for a quick demo.

<img src="https://raw.githubusercontent.com/RayOkaah/woocommerce/master/example/woocommerce-ios-demo.gif" width="30%">.

### Auth

```dart
//Login - Returns the access token on success.

final token = woocommerce.authenticateViaJWT(username: username, password: password);

// Login - Signs a user in and returns the logged in user's (WooUser object) details.

final customer = woocommerce.loginCustomer(username: username, password: password);

// Check if a user is Logged In.

bool isLoggedIn = await woocommerce.isCustomerLoggedIn();

// Fetch Logged in user Id
int id = await fetchLoggedInUserId();

// Log User Out.
await logUserOut();

// Creates a new Woocommerce customer and returns the WooCustomer object.
WooCustomer user = WooCustomer(username: username, password: password, email: email);
final result = woocommerce.createCustomer();

```
 ### Products [see SDK reference](https://pub.dev/documentation/woocommerce/latest/models_products/Product-class.html) for filter options.

```dart
// Get All Products - Returns list of product object, default is 10 per page.

final myProducts = await woocommerce.getProducts();

//Get All Featured Products - Returns a list of featured products, see Api reference for more filter options.

final myFeaturedProducts = await woocommerce.getProducts(featured: true);

// Get All Products marked with category id '22'.

final mySpecificProduct = await getProducts(category: '22');
```

### Cart!

```dart
// Add To Cart! - Returns the added cart item object(Accepts quantity, product id, and list of variations(id) of the product to be added)

final myCart = await woocommerce.addToMyCart(quantity: 2, id: 17);

// Create an Order. - Returns the created order object (Accepts an orderPayload object).

OrderPayload orderPayload = OrderPayload(customerId: customerId, setPaid=true);
final order = await woocommerce.CreateOrder(orderPayload);

```

### Custom Requests - Make your custom authenticated requests to the Woocommerce api.

```dart
final response = await woocommerce.put(endpoint, data);

final anotherResponse = await woocommerce.get(endpoint);
```

## Updates

- [x] Add documentation.
- [x] Add Token Persistence.
- [ ] Add more search filter abilities.
- [ ] Multiple Examples.

## WooCommerce SDK Documentation Reference
[WooCommerce SDK Docs] (https://pub.dev/documentation/woocommerce/latest/)

## WooCommerce Api Documentation Reference
[WooCommerce Docs] (https://woocommerce.github.io/woocommerce-rest-api-docs/)

## Issues and FeedBack
If you find this useful :blue_heart:, feel free to click :star:
You can create a Github issue anytime. Pull requests on both code and documentation are welcomed as well pls :heart_eyes:.
You can also send a mail to<EMAIL_ADDRESS>
For help getting started with Flutter, view the
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.


text:
# Deutsche Bahn Python API(s) wrapper

## Documentation

This module's documentation is hosted on [Gitbook](http://o2ba.gitbook.io/deutschebahn)

## Getting your API token

The first step that you must complete before using the module. To generate an API token, you must first create an account on the [API Portal website](https://developer.deutschebahn.com/).

Then, create an API. The same is non-significant and so is the Callback URL and Description.

![My Applications page](.gitbook/assets/image%20%281%29.png)

You can then go to My Subscriptions, select your application, and generate keys.

![My Subscriptions page](.gitbook/assets/image%20%282%29.png)

Now, you should have an Access Token, which you will use in Python to authenticate yourself.

In order for the module to work, you need to subscribe to modules you intend to use. To be safe, subscribe to the following modules:

* Betriebsstellen
* StaDa Station Data
* FaSta Station Facilities
* Timetable
* Fahrplan
* Reisezentren

![](.gitbook/assets/image%20%283%29.png)

Now in your Python file, you can initialize the module by using the client.Auth function

```
import deutschebahn as db

db.client.Auth("Your token")
```


text:
# [Chomp](https://charcoding.github.io/Chomp/)
JS and C++ Implementation of the poset game, [Chomp](https://en.wikipedia.org/wiki/Chomp).

The AI is pretty strong.

### Notes:
This program uses at least 6.33 MiB of memory just to store the losing position dictionary. And this
is already storing the edges as individual bits as opposed to storing row widths.
The C++ solver can use [parallel hashmap](https://github.com/greg7mdp/parallel-hashmap) for a speed boost.

## Usage:
Running `make` will make the game executable. This executable doesn't require parallel hashmap.
To start the game, run `./chomp [width] [height] [player 1] [player 2]`.
`width` and `height` are between 3 and 16.
Player 1 and 2 can be: `human`, `AI` or `AI0`. `AI` will make mistakes; `AI0` will not.
Note that when `width` equals `height`, the board is trivially won by taking the piece (1, 1).

repository: CharCoding/Chomp

gha_license_id: MIT

repo_name: CharCoding/Chomp


text:
## pscompile

`pscompile` is a [parenscript](http://common-lisp.net/project/parenscript/)
to JavaScript transcompiler. It provides a way to write javascript in a
Lisp-like syntax.

## Building

Right now, there is only support for SBCL; adding a new compiler that supports
POSIX command line options should be trivial.

```
sbcl --load build.lisp
```

will build the `pscompile` binary in the current directory.

## Using

```
pscompile [parenscript files]
```

The files will be saved under the same base file name, with the extension ".js".
For example, `test.lps` will be saved as `test.js`.

## References

0. [The Parenscript reference manual](http://common-lisp.net/project/parenscript/reference.html).

## License

```
Copyright (c) 2013 Kyle Isom<EMAIL_ADDRESS>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
```

license: ISC

repository: tristanstraub/pscompile

repo_name: tristanstraub/pscompile


text:
[![Build Status](https://travis-ci.org/hychen/ke-e.svg?branch=master)](https://travis-ci.org/hychen/ke-e)
[![License](http://img.shields.io/:license-mit-blue.svg)](http://badges.mit-license.org/)

# ké--ê

`ké--ê` is a property-based testing library, inspired by [QuickCheck](https://hackage.haskell.org/package/QuickCheck),
[Hypothesis](https://github.com/HypothesisWorks/hypothesis-python), [JSVerify](https://github.com/jsverify/jsverify) and
[faker.js](https://github.com/marak/Faker.js/).

It is also available to generate fake data for many purpose like faker.js.

## What is ké--ê?

假的 (ké--ê) is a Taiwanese word. the meaning is fake things in English.

## Features

- Property-based test utilities library.
- Repeatable random fake data generators.
- Mocha test framwork integration.
- Support for multiple localities.
- Support for browser and Node.js.

check [documents](http://hychen.me/ke-e/index.html) for more details.

### Property-Based Testing

Property-based tests make statements about the output of your code based on the input, and these statements
are verified for many different possible inputs.

By default, `ke.hold` runs 50 tests. it reports a counter example does not satisfy the property
if any test fail.

for example, the following test.

```
describe('Int', () => {
  ke.hold(
    '> 0',       // property name.
    x => x > 0   // predicate.
  )
  .over(0)       // first especially case.
  .over(2)       // second especially case.
  .over(ke.int)  // universal case.
})
```

will report:

```
1) Int > 0:

      AssertionError: > 0 doesn't hold, counter example: -5, tried: 1/100
      + expected - actual

      -false
      +true
```

### Exception-Based Testing

You can still use `chai` to do the testing with random test values
generated by `ke-e`.

```
describe('Nat', () => {
  it('>= 0',  () => {
    ke.forall(ke.nat).eval((n) => {
      expect(n >= 0).eq(true);
    });
  }
})
```

### Repeatable

test results are repeatable.

```
$ mocha
1) Int >0:
AssertionError: >0 doesn't hold, seed: -1764850555, counter example: -5265798245849472, tried: 3/3`

```

```
Seed=-1764850555 mocha
1) Int >0:
AssertionError: >0 doesn't hold, seed: -1764850555, counter example: -5265798245849472, tried: 3/3`
```

### Localization

This project follows unicode CLDR specification. `en` is default locale id.

```
// Generate English first name.
ke.person.firstName.random.

// Generate Transitional Chinese first name.
ke.person.firstName.locale('zh-Hant-TW').random.
```

### Node.js REPL

```
$ ke
> ke.int.random
123124343
```

## Arbitraries

The purpose of a arbitraries is random generation and shrinking of values
in property-based testing, but you could use them to generate fake data
individually.

some of definitions of arbitraries took from
[faker.js](https://github.com/marak/Faker.js/) project.

### Primitive

- any - produce any primitive types.
- boolean — produce true and false with equal probability.
- falsy — produce falsy values: false, null, undefined, '', 0, and NaN.
- nat — produce a natural number.
- int — produce a integer.
- pint — produce a positive integer.
- nint — produce a negative integer.
- num — produce a float numbers.
- pnum — produce a positive float numbers.
- nnum — produce negative float numbers.
- char — produce a unicode character.
- asciichar — produce an ascii character.
- string — produce a unicode string.
- nestring - produce a non-empty unicode string.
- asciistring — produce an ascii string.
- neasciistring — produce an non-empty ascii string.

### Combinator

- constant — produce a constant value.
- elements — produce one of the given values.
- regex - produce a value from the regular expression.
- frequency - Choose one of the given arbitraries, with a weighted random distribution.
- oneOf — randomly uses one of the given generators.
- maybe - produce a value or null.
- array — produce an array.
- nearray — produce a non-empty array.
- sequence — produce an array of given arbitraries in order.
- object — produce an object.
- impl - produce a instance of class C.
- call - produces a value of function with given arbitrary arguments.
- func — produce a function.
- genfunc - produce a generator.
- promise - produce a promise.
- recursive - produce a recursive value.

### Locale

- locale
 - localeids — produce a locale id.
 - country
 - timezone

### Datetime

- date — produce a Date.

### Literate
- literate
 - word
 - words
 - sentence
 - sentences
 - paragraph
 - paragraphs
 - lines
 - text

### Person

- person - produce an object to reprsent a person.
 - name - produce the name of a person.
 - firstName - produce the first name of a person.
 - lastName - produce the last name of a person.
 - gender - produce the gender of a person.

### Internet

- internet
 - avatar - produce an avatar uri.
 - userName - produce a internet username.
 - password - produce a password string.
 - email - produce an email.
 - url - produce an url.

### Location

- location
 - address
 - streetAddress
 - state
   - abbr
 - zipCode
 - county
 - city
 - street
 - buildingNumber
 - latitude -  produce an latitude.
 - longitude - produce an longitude.
 - coordinates -  produce a coordinates.

### Grahpic

- graphic
  - color
    - rgba
    - hsla
    - hsva
    - hex
    - hexCode
  - image
    - imageURL - an image url.
    - grayImageURL - a gray image url.

## Installation

### Node.js

install the module with: npm install ke-e

```javascript
import ke from `ke-e`

describe('Integer', () => {
  ke.hold(
    'x + y = y + x'
    (x, y) => x + y === y + x
    ).over(ke.int, ke.int);
});
```

### Browser using script tag

Download ke-e.js and place it in your project, then add it as the follwoing.

<error> dones not work now.

```html
<script src="http://hychen.me/ke-e/ke-e.js"</script>
<script>
describe('Integer', () => {
  ke.hold(
    'x + y = y + x'
    (x, y) => x + y === y + x
    ).over(ke.int, ke.int);
});
</script>
```

## Get Involved

- source code : [github.com/hychen/ke-e](https://github.com/hychen/ke-e).

## License

The MIT License (MIT)

repository: hychen/ke-e

gha_language: TypeScript

repo_name: hychen/ke-e


text:
# NOTICE: Re-thinking is happening...

Scala has evolved quite a bit since this project began in 2011, and mainstream Ruby usage
has evolved as well.

In the branch [experimental-0.5](https://github.com/ms-ati/rumonade/tree/experimental-0.5),
new things are going to be tried.

If you're interested in sharing your ideas, join the [mailing list](http://groups.google.com/group/rumonade).

---------------------------------------

# [Rumonade](https://rubygems.org/gems/rumonade)

[![Gem Version](https://img.shields.io/gem/v/rumonade.svg)](https://rubygems.org/gems/rumonade)
[![Build Status](https://travis-ci.org/ms-ati/rumonade.png)](https://travis-ci.org/ms-ati/rumonade)
[![Dependency Status](https://gemnasium.com/ms-ati/rumonade.png)](https://gemnasium.com/ms-ati/rumonade)
[![Code Climate](https://codeclimate.com/github/ms-ati/rumonade.png)](https://codeclimate.com/github/ms-ati/rumonade)
[![Coverage Status](https://coveralls.io/repos/ms-ati/rumonade/badge.png)](https://coveralls.io/r/ms-ati/rumonade)

*_Project_*: [github](http://github.com/ms-ati/rumonade)

*_Documentation_*: [rubydoc.info](http://rubydoc.info/gems/rumonade/frames)

## A [Ruby](http://www.ruby-lang.org) [Monad](http://en.wikipedia.org/wiki/Monad_\(functional_programming\)) Library, Inspired by [Scala](http://www.scala-lang.org)

Are you working in both the [Scala](http://www.scala-lang.org) and [Ruby](http://www.ruby-lang.org) worlds,
and finding that you miss some of the practical benefits of Scala's
[monads](http://james-iry.blogspot.com/2007/09/monads-are-elephants-part-1.html) in Ruby?
If so, then Rumonade is for you.

The goal of this library is to make the most common and useful Scala monadic idioms available in Ruby via the following classes:
* [Option](http://rubydoc.info/gems/rumonade/Rumonade/Option)
* [Array](http://rubydoc.info/gems/rumonade/Rumonade/ArrayExtensions)
* [Either](http://rubydoc.info/gems/rumonade/Rumonade/Either)
* [Hash](http://rubydoc.info/gems/rumonade/Rumonade/Hash)
* _more coming soon_

Syntactic support for scala-like [for-comprehensions](http://www.scala-lang.org/node/111) will be implemented
as a sequence of calls to `flat_map`, `select`, etc, modeling [Scala's
approach](http://stackoverflow.com/questions/3754089/scala-for-comprehension/3754568#3754568).

Support for an [all_catch](http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/scala/util/control/Exception$.html)
idiom will be implemented to turn blocks which might throw exceptions into Option or Either
results. If this proves useful (and a good fit for Ruby), then more narrow functional catchers can be implemented as well.

## Usage Examples

### Option: handle _possibly_ _nil_ values in a _functional_ fashion:

```ruby
def format_date_in_march(time_or_date_or_nil)
  Option(time_or_date_or_nil).    # wraps possibly-nil value in an Option monad (Some or None)
    map(&:to_date).               # transforms a contained Time value into a Date value
    select {|d| d.month == 3}.    # filters out non-matching Date values (Some becomes None)
    map(&:to_s).                  # transforms a contained Date value into a String value
    map {|s| s.gsub('-', '')}.    # transforms a contained String value by removing '-'
    get_or_else("not in march!")  # returns the contained value, or the alternative if None
end

format_date_in_march(nil)                            # => "not in march!"
format_date_in_march(Time.parse('2009-01-01 01:02')) # => "not in march!"
format_date_in_march(Time.parse('2011-03-21 12:34')) # => "20110321"
```

Note:
* each step of the chained computations above are functionally isolated
* the value can notionally _start_ as nil, or _become_ nil during a computation, without effecting any other chained computations

---
### Either: handle failures (Left) and successes (Right) in a _functional_ fashion:

```ruby
def find_person(name)
  case name
    when /Jack/i, /John/i
      Right(name.capitalize)
    else
      Left("No such person: #{name.capitalize}")
  end
end

# success looks like this:
find_person("Jack")
# => Right("Jack")

# failure looks like this:
find_person("Jill")
# => Left("No such person: Jill")

# lift the contained values into Array, in order to combine them:
find_person("Joan").lift_to_a
# => Left(["No such person: Joan"])

# on the 'happy path', combine and transform successes into a single success result:
(find_person("Jack").lift_to_a +
 find_person("John").lift_to_a).right.map { |*names| names.join(" and ") }
# => Right("Jack and John")

# but if there were errors, we still have a Left with all the errors inside:
(find_person("Jack").lift_to_a +
 find_person("John").lift_to_a +
 find_person("Jill").lift_to_a +
 find_person("Joan").lift_to_a).right.map { |*names| names.join(" and ") }
# => Left(["No such person: Jill", "No such person: Joan"])

# equivalent to the previous example, but shorter:
%w(Jack John Jill Joan).
  map { |nm| find_person(nm).lift_to_a }.inject(:+).
  right.map { |*names| names.join(" and ") }
# => Left(["No such person: Jill", "No such person: Joan"])
```

Also, see the `Either` class in action in the [Ruby version](https://gist.github.com/2553490)
of [A Tale of Three Nightclubs](http://bugsquash.blogspot.com/2012/03/example-of-applicative-validation-in.html)
validation example in F#, and compare it to the [Scala version using scalaz](https://gist.github.com/970717).

---
### Hash: `flat_map` returns a Hash for each key/value pair; `get` returns an Option

```ruby
h = { "Foo" => 1, "Bar" => 2, "Baz" => 3 }

h = h.flat_map { |k, v| { k => v, k.upcase => v * 10 } }
# => {"Foo"=>1, "FOO"=>10, "Bar"=>2, "BAR"=>20, "Baz"=>3, "BAZ"=>30}

h = h.select { |k, v| k =~ /^b/i }
# => {"Bar"=>2, "BAR"=>20, "Baz"=>3, "BAZ"=>30}

h.get("Bar")
# => Some(2)

h.get("Foo")
# => None
```

## Approach

There have been [many](http://moonbase.rydia.net/mental/writings/programming/monads-in-ruby/00introduction.html)
[posts](http://pretheory.wordpress.com/2008/02/14/the-maybe-monad-in-ruby/)
[and](http://www.valuedlessons.com/2008/01/monads-in-ruby-with-nice-syntax.html)
[discussions](http://stackoverflow.com/questions/2709361/monad-equivalent-in-ruby)
about monads in Ruby, which have sparked a number of approaches.

Rumonade wants to be a practical drop-in Monad solution that will fit well into the Ruby world.

The priorities for Rumonade are:

1.  Practical usability in day-to-day Ruby
    *  don't mess up normal idioms of the language (e.g., `Hash#map`)
    *  don't slow down normal idioms of the language (e.g., `Array#map`)
2.  Rubyish-ness of usage
    *  Monad is a mix-in, requiring methods `self.unit` and `#bind` be implemented by target class
    *  Prefer blocks to lambda/Procs where possible, but allow both
3.  Equivalent idioms to Scala where possible

## Status

Option, Either, Array, and Hash are already usable.

Supported Ruby versions: MRI 2.0.0, 1.9.3, 1.9.2, JRuby in 1.9 mode, and Rubinius in 1.9 mode.

Please try it out, and let me know what you think! Suggestions are always welcome.

repository: ms-ati/rumonade

repo_name: ms-ati/rumonade


text:
## maintainer readme

Generate README.md related text in your repository.

### Synopsis

Generate README.md related text in your repository.

### Options inherited from parent commands

```
      --config string   config file (default is $HOME/.maintainer.yaml)
      --token string    The token in GitHub.To make more than 50 requests per hour the GitHub token is required.You can generate it at: https://github.com/settings/tokens/new.
```

### SEE ALSO
* [maintainer](maintainer.md)	 - Help you to be a qualified maintainer.
* [maintainer readme toc](maintainer_readme_toc.md)	 - Generate TOC for your repository

###### Auto generated by spf13/cobra on 23-May-2019


text:
Building a vpn-ws bridge server with client-certificates authentication on Ubuntu Trusty
========================================================================================

We have a lan on the subnet <IP_ADDRESS>/24 and we want to allow VPN access from the internet.

The lan has a DHCP server.

One node of the lan (<IP_ADDRESS>) will be the vpn-ws server (the gateway of the lan, with ip <IP_ADDRESS>, has to be configured for allowing access to its
https port from the world)

Clients connecting to the VPN get a <IP_ADDRESS>/24 address from the DHCP server of the lan.

Requirements
============

Ubuntu 14.04 (32 or 64 bit) on the vn-ws server

Installing packages
===================

We are going to install packages on the system that will run the vpn-ws/nginx server

You need only nginx and bridge-utils (we are going to use static binaries for vpn-ws)

```sh
sudo apt-get install nginx bridge-utils
```

Now download a vpn-ws linux binary (32 or 64 bit) from https://github.com/unbit/vpn-ws#binary-packages and place it in /usr/local/bin

Network configuration
=====================

/etc/network/interfaces must be adapted for a bridget setup

```
auto lo

iface lo inet loopback

iface eth0 inet manual

auto br0
iface br0 inet static
        bridge_ports eth0
        address <IP_ADDRESS>
        netmask <IP_ADDRESS>
        gateway <IP_ADDRESS>
        dns-nameservers <IP_ADDRESS>
```

Once rebooted, the server should continue working as before with the difference that traffic is managed by the 'br0' bridge

Certification authority
=======================

We need to create our CA (required for signing client certificates)

```sh
openssl genrsa -des3 -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
```

Now we can start signing our clients CSR (note, that the server certificate can be signed from whatever authority you want/need)

Remember to generate keys directly on the clients and instruct them to send only the csr to the machine signing them (it could be obvious, but the first rule of security is being paranoid)

generate a key (on the client):

```sh
openssl genrsa -des3 -out client.key 2048
```

generate a csr (on the client):

```sh
openssl req -new -key client.key -out client.csr
```

send the csr file to the machine signing it, and run (on the signing machine):

```sh
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
```

now send back client.crt to the client.

If you need the certificate/key pair to be in pkcs12 format you can concert them with:

```sh
openssl pkcs12 -export -in client.crt -inkey client.key -name "Client 01" -out client.p12
```

Configuring nginx
=================

Now we need to configure nginx to use client certificates:

```nginx
server {
    listen        443;
    ssl on;
    server_name example.com;

    ssl_certificate      /etc/ssl/certs/server.crt;
    ssl_certificate_key  /etc/ssl/private/server.key;
    ssl_client_certificate /etc/ssl/certs/ca.crt;
    ssl_verify_client on;

    location /vpn {
        uwsgi_pass   unix:/run/vpn.sock;
        include      uwsgi_params;
    }

    location /admin {
        uwsgi_pass   unix:/run/vpn.sock;
        uwsgi_modifier1 1;
        include      uwsgi_params;
        allow <IP_ADDRESS>;
        deny all;
    }
}
```

adapt ssl_certificate, ssl_certificate_key and ssl_client_certificate to your patch choices and reload nginx.

As yo ucan see we have added a /admin location for allowing access to the json control interface from ip <IP_ADDRESS> (change it to the ip allowed to administer the vpn)

Starting vpn-ws on boot
=======================

Ubuntu trusty is upstart based, so we are going to write a config for it:

```
# vpn-ws script

description "vpn-ws"
start on runlevel [2345]
stop on runlevel [06]

exec /usr/local/bin/vpn-ws --uid www-data --gid www-data --tuntap vpn0 --bridge --exec "brctl addif br0 vpn0" /run/vpn.sock >>/var/log/vpn-ws.log 2>&1
```

save it as /etc/init/vpn-ws.conf and run

```sh
start vpn-ws
```

now check nginx logs (and /var/log/vpn-ws.log) to ensure it can connect

Testing a client
================

We are going to use a linux client from an external network (ensure your lan gateway forward requests to port 8443 to <IP_ADDRESS>:443)

```sh
vpn-ws-client --key client.key --crt client.crt --exec "dhclient vpn1 &" vpn1 wss://server:8443/vpn
```

be sure the dhclient command is followed by & otherwise it will block the whole client

repository: unbit/vpn-ws

gha_language: C

repo_name: unbit/vpn-ws


text:
I am behaviour of Student which collected all recieved messages as study result. For all intercepted messages I find real method by my  teacher class and execute it. At the end my list of studiedMessages contains all messages which was received during education process.

My users then can install studied messages to ghost meta messages class.
	learning installStudiedMessagesInto:  aMetaMessagesClass

I can be created with concrete teacher class:
	learning := GHLearning by: Object

Internal Representation and Key Implementation Points.

    Instance Variables
	metaLevel:		<GHMetaLevel>
	studiedMessages:		<Dictionary>
	teacher:		<Class>

repository: pavel-krivanek/Ghost

repo_name: pavel-krivanek/Ghost


text:
# PEPON

C++ Object Notation file format/reading/writing library for modern C++(17+)

Pepon lets you save and load your **C++ data** easily

```
#include "peponLib/PeponFile.hpp"

std::vector<int> numbers { 1, 2, 3, 4, 5, 6 };
std::deque<unsigned int> units { 10, 20, 30, 40, 50, 60 };
std::list<float> ff { 1.1f, 2.2f, 3.3f };

// All this data can be saved and loaded from Pepon files
pepon::PeponFile pf;
pf.saveFile("./pepon_out.txt");
```

## Configuration:

* Set **PEPON_USE_STL_PATH** variable (in the CMakeLists.txt file) to value 1 to specify file paths using __std::filesystem::path__. Otherwise, you must specify file path using __std::string_view__

* struct **PeponQuotes**: You can enable/disable quotation marks for every value shown by the **print()** functions. And you can set the quotation character you want to use

## File format:

* Comments are optional. Each line starting with '//' (C++), '--' (Lua) or a single '#' (Python style) is detected as a comment and saved, to be attached later to a Group

* Groups. Before declaring variables, you need to create at least one group. Think of it as the sections found in .INI files. Group declaration is written using square brackets. Example:

```
// This is my very first group!
[MyFirstGroup]
```

* Variables: They can be **single values**, for example, just an int or a double. Or they can be **containers**, like a vector of floats. The general format for writing a variable is this:

```
a : int = 1
```
This specifies an __int__ value, named __'a'__, with a value of __1__.
Variable name, type and value **MUST** be set, always

String values must be written using opening and closing double quotation marks ('"')

```
b : string = "Hello, this is my first string"
```

Containers template type must be always set. Container values must be specified using curly brackets ('{' and '}' characters)

```
c : list<bool> = { true, false, NOT_TRUE, 1, I_JUST_LIED }
```

You can write container values in multiple lines, but the opening '{' must be specified in the same line where the container is declared

```
c : list<bool> = {
    true,
    false,
    0
}
```

You can also write long strings in multiple lines, but the opening '"' must be written in the same line where the string is declared. Please note that the endline characters will be part of the string

```
text : string = "First line ............
                 Second line ...........
                 Third line ............"
```

**Note**: You can't write multiline strings if they are the values of a container. Sorry

## Use examples:

```
// Parse Pepon data from memory
std::vector<std::string> lines =
{
    "// Hello, this is a nice C++ style comment",
    "# And this is a nice Python style comment",
    "[My first group]",
    "a : int = 1",
    "b: string=\"Hello world!\"",
    "   EVIL :   vEctOr  <   inT         >   =   {      1,      2,3}",
    "",
    "d:deque<uint> = { 10, 20,",
    "                  30, 40,",
    "                  50, 60 }",
    "",
    " e : string = \"This is a very,",
    "              very long",
    "              string",
    "\"",
    ""
};

pepon::PeponFile pf;
pf.loadFromMemory(lines);

// Show parsed data to console
pf.print();
```

Open **tests/pepon_test.cpp** for more examples

## Future:

* Add support for more containers? (set, unordered_set, map, unordered_map)


text:
This is just a test!
And again

# chirp

Chirp is meant to be set up with Travis CI to repeatedly build itself for
purposes of real world monitoring.  There is a server component called
[chirp-tracker](https://github.com/travis-infrastructure/chirp-tracker) that
understands both github and travis webhook payloads and keeps a record of
timestamps and commits from each such that a delta may be used as a simple
metric for high level alerts.

## setup

0. Add this gem as a dependency in a `Gemfile`, e.g.
   `gem 'chirp', github: 'travis-infrastructure/chirp'`
0. Add a `.travis.yml` with required bits
    * Ensure it is `language: ruby` or at least uses a language with `bundler`
      available
    * Ensure the `script` step includes `bundle exec chirp scripts`
    * Optionally, add an `after_success` step that includes:
        * `bundle exec chirp pushback &>/dev/null`
        * `bundle exec chirp sendstats &>/dev/null`
    * Optionally, add an `after_failure` step with `bundle exec chirp dumplogs`
    * Ensure there is a webhook set up to point at a chirp-tracker instance with
      `on_success: always` and `on_failure: never`
0. `travis enable`
0. Generate a github token with `repo` scope
0. `travis env set GITHUB_OAUTH_TOKEN <github-token>`
0. Add a webhook on github for chirp-tracker, e.g.
   `https://chirp-tracker-production.herokuapp.com/github` with content type of
   `application/x-www-form-urlencoded` and the secret token configured on the
   server side.  Only the `push` event needs to be configured.

repository: not-a-travis-org/chirp

repo_name: not-a-travis-org/chirp


text:
# barman-kludges
Lazy but working bash scripts to fix errors occuring in pgbarman backups.
Work with barman 2.11.

Use them with cron accordingly to your backup schedule.

# delete-failed-and-redo-failed-by-age.sh
Pretty simple — sometimes full backups fail, this one deletes failed backups and asks for anothers.

You could use it early in the morning, when usual backup schedule should be already completed.

# passive-barman-node-resync.sh
There's a strange issue on passive node when barman reports

	ERROR: Failed to retrieve the primary node status: sync-info execution on remote primary server failed: usage: barman sync-info [-h] [--primary]

This one forces barman to sync-info, sync wals and then resync backups with primary node.
Works good when set to run every two hours or so.

repository: apathyzen/barman-kludges

repo_name: apathyzen/barman-kludges


text:
## Contributing to dyconnmap

#### Reporting issues

When reporting issues please include as much detail as possible about your
development environment. Whenever possible, please also include a brief,
self-contained code example that demonstrates the problem.

#### Contributing code

Thanks for your interest in contributing code to `dyconnmap`!

Either fork or create a pull request on our Github page.

repository: makism/dyconnmap

gha_language: Python

repo_name: makism/dyconnmap


text:
Site Owner
Own and Manage a website focused on Powershell
https://kevinmarquette.github.io
I am the sole maintainer of a website that shares my open source PowerShell projects and it hosts my PowerShell blog. In the last 12 months, I have 32 new posts up.

According to Google analytics, here are my stats for the last 12 months.
New Users: 261,967
Sessions: 425,640
Page Views: 486,414

Posts: 26
Visitors: 425640

---
Site Owner
Own and manage a website for a PowerShell user group
http://socalpowershell.org
This is the main landing page for the SoCal PowerShell user group. I own the domain, created and manage the site for the user group.

I don't have any tracking info on this website.

Posts: 1

---
User Group Owner
8/1/2017
Creator and owner of the SoCal PowerShell user group
https://www.meetup.com/SoCal-PowerShell-user-group/
I started and run the user group on Aug 1st, 2017 and have held monthly group sessions.
meetings: 8
members: 104

---
Webcast
3/12/2018
Episode 6 - Interview with Kevin Marquette from the SoCal PowerShell User Group
https://powershellnews.podbean.com/e/interview-with-kevin-marquette-from-the-socal-powershell-user-group/
Mick was heading to San Diego from the Microsoft MVP Global Summit in Seattle and made a stopover to do a podcast in person with Kevin Marquette and Harjit Dhaliwal from Seattle.

Downloads: 845

---
Forum Participation
/r/PowerShell
https://www.reddit.com/r/subreddit_stats/comments/88omam/subreddit_stats_powershell_top_posts_from/
I am an active member of the /r/powershell community that has 45,485 readers. I linked the stats for the last 12 months. Where only 3 people have more post submissions than I do. And only 2 people have more comments then I do.
Answers: 279
posts: 17

---
Open Source Projects
Powershell
https://github.com/PowerShell/PowerShell/graphs/contributors
Contributor to the GitHub/powershell project
commits: 9

---
Open Source Projects
2/25/2018
Select-AST
https://github.com/KevinMarquette/Select-Ast
Created and maintain a module for working with the PowerShell AST
Projects: 1
Commits: 6

---

Open Source Projects
Maintainer of PSGraphPlus
https://github.com/KevinMarquette/PSGraphPlus
I maintain an open source Powershell module that graphs basic information about the local system
Commits: 30
---

Open Source Projects
Maintainer of Chronometer PowerShell Module
https://github.com/KevinMarquette/Chronometer
I maintain an open source powershell module that profiles the performance of scripts
commits: 64

---

Open Source Projects
Maintainer of PSGraph PowerShell Module
https://github.com/KevinMarquette/PSGraph
I maintain an open source project that allows you to generate data driven graphs with powershell
commits: 262

---
Open Source Projects
Maintainer of PSHonolulu PowerShell Module
https://github.com/KevinMarquette/PSHonolulu
I maintain an open source powershell module that interacts with Honolulu
commits: 20

---

Speaking (User Group)
11/2/2017
Visualize Data Using PSGraph user group presentation
https://www.meetup.com/Austin-PowerShell/events/244271778/
I presented to the Austin PowerShell user group on how to work with the PSGraph PowerShell module

Attendees: 18

---

Speaking (User Group)
9/12/2017
MSPSUG September 2017 Virtual Meeting: PSGraph, A hierarchical graph module
http://mspsug.com/2017/09/07/mspsug-september-2017-virtual-meeting-psgraph-a-hierarchical-graph-module/
I presented to the Mississippi PowerShell user group on how to work with the PSGraph PowerShell module

Attendees: 12

---

Speaking (User Group)
10/3/2017
Working with PSGraph user group presentation
https://www.meetup.com/SoCal-PowerShell-user-group/events/241536557/
I presented to the SoCal PowerShell user group on how to work with the PSGraph PowerShell module

Attendees: 20
---

Speaking (User Group)
12/16/2017
Working with PSGraph Dalas user group presentation
http://sp.ntpcug.org/PowerShell/Lists/Announcements/DispForm.aspx?ID=104&Source=http%3A%2F%2Fsp%2Entpcug%2Eorg%2FPowerShell%2Fdefault%2Easpx
I presented to the Dalas PowerShell user group on how to work with the PSGraph PowerShell module

Attendees: 19

---

Speaking (User Group)
8/1/2017
Everything you wanted to know about Hashtables user group presentation
https://www.meetup.com/SoCal-PowerShell-user-group/events/241535192/
I presented to the SoCal PowerShell user group on how to work with PowerShell Hashtables

Attendees: 21

---

Video
8/1/2017
PowerShell Hashtables as presented to the SoCalPowerShell user group
https://www.youtube.com/watch?v=EtHxfTfZD3I
I presented to the SoCal PowerShell user group on how to work with PowerShell Hashtables
Views: 229

---

Video
10/3/2017
SoCal PowerShell User Group: Working with PSGraph
https://www.youtube.com/watch?v=pR_xzZh9qoI
I presented to the SoCal PowerShell user group on how to work with the PSGraph PowerShell module
Views: 125

---
Speaking (Conference)
4/12/2018
Writing A DSL (Domain Specific Language) for PowerShell
https://powershelldevopsglobalsummit2018.sched.com/event/CrVQ
I gave a presentation at the PowerShell and DevOps Summit as part of the main developer track. This covered a specialized concept in PowerShell and how to not only understand how it works but also how to create it.
Attendees: 60
---

Speaking (User Group)
5/1/2018
Custom DSC Resources with Kevin Marquette
https://www.meetup.com/SoCal-PowerShell-user-group/events/248384828/
I presented to the SoCal PowerShell user group on how to create custom DSC resource.

Attendees: 23

---

Speaking (User Group)
5/1/2017
Everything you wanted to know about hashtables
https://www.meetup.com/Research-Triangle-PowerShell-Users-Group/events/251494859/
I presented to the Research Triangle PowerShell user group about hashtables.

Attendees: 60

---

---
blog
https://powershellexplained.comblog

twitter
https://twitter.com/KevinMarquette

Linkedin
https://www.linkedin.com/in/kevinmarquette/

github
https://github.com/KevinMarquette

facebook
https://www.facebook.com/kevin.marquette

YouTube

2018 user group presentations:

* [Custom DSC Resources](https://www.meetup.com/SoCal-PowerShell-user-group/events/248384828/)
* [Dynamic DSC Configuration Data with David and Kevin](https://www.meetup.com/SoCal-PowerShell-user-group/events/248384992/)
* [Enterprise scale DSC, DevOps at loanDepot](https://www.meetup.com/SoCal-PowerShell-user-group/events/251447753/)
* [Advanced Functions](https://www.meetup.com/SoCal-PowerShell-user-group/events/254689518/)
* [Pester in Action](https://www.meetup.com/SoCal-PowerShell-user-group/events/256740027/)

The other half of our sessions were covered either by David, guest speakers or remote presenters.

### Other User Groups

I was able to present a few sessions to the Research Triangle and Portland user groups.

* RTP [Everything you wanted to know about hashtables](https://www.meetup.com/Research-Triangle-PowerShell-Users-Group/events/251494859/)
* RTP [PSGraph: Creating Dynamic Graphs and Diagrams on the fly!](https://www.meetup.com/Research-Triangle-PowerShell-Users-Group/events/256193788/)
* PUG [Everything you wanted to know about hashtables](https://www.evensi.us/monthly-pug-meetup-kevin-marquette-viewpoint/271644771)

gha_license_id: NOASSERTION


text:
# Accent Ui
A modern react ui library built for ambitious design and developer teams

- **Accent based Design.** Accent components are built with accent color design in mind.

- **Flexible & composable.** Modern React is the base for accent ui. If you can React then you can also Accent.

- **Built in Component animations.** Accent offers out of the box beautiful animations to bring components to life.applications.

## Documentation & Community

- [Documentation](coming soon)
- [Discord](coming soon)

##  Migration guide

No migrations Available

## Install and use components

🌲 Accent Ui is made up of various components and tools.Each component can be imported single-handed. All you need to do is install the `accent-ui` package:

```sh
$ yarn add accent-ui
# or
$ npm install --save accent-ui
```

A simple example.This is how a accent ui component ( Button ) is added

```js
import React from 'react'
import ReactDOM from 'react-dom'
import { Button } from 'accent-ui'

ReactDOM.render(
  <Button>I am using Accent!</Button>,
  document.getElementById('root')
)
```

## Why Accent UI ?

## Contributing to Accent UI

### 🍴 Step 1. Fork this repository

In order to contribute to Accent, you need to fork this repo, and develop on your own local clone.

If you don't know how to do so, follow this [guide](https://help.github.com/en/github/getting-started-with-github/fork-a-repo)!

### 📖 Step 2. Run StoryBook

First, move into your local cloned repository with the help of `cd`, after that install your `node_modules` with:

```
$ yarn
```

To actually start seeing the components you have to run React Storybook with the command:

```
$ yarn dev
```

Now go to `http://localhost:6006` in your browser.

### 🛠 Step 3. Make an impressive change

Now you can start developing! All of the components are under the `src` directory and associated code changes will automatically be reflected in StoryBook.

If necessary, we encourage you to update the documentation so users will be aware of your new features/changes.

In order to run the documentation page locally, run these commands in your terminal:

```
$ yarn build
$ cd docs
$ yarn install
$ yarn dev
```

Now you can visit `http://localhost:8000/` in your browser.

Documentation code is coming soon.

### 🏆 Step 4.

From here, you can open up a pull request from your forked repository's branch into `kweku360/accent-ui`'s `master` branch.

In your PR description, explain the changes you made, why you made them, how to test them, and anything that might be a point of interest.

Once you create your PR, it will be reviewed and hopefully merged quickly!

### 🥂 Step 5. Phew

Congrats, you're officially an Accent contributor!

## 🎉 Contributors

We are looking for more contributers

- Kweku O. Kankam

This project is maintained by [kweku kankam)

Please take a look at the [contributing guide](.github/CONTRIBUTING.md) to better understand what to work on.

## License

Accent-Ui is released under the MIT license.

Copyright © 2021 @kweku360


text:
---
title: Swift Snapshot Testing in Github Actions
description: Short discussion on how I run snapshot tests in Github CI
date: 2023-03-05 10:06:00+01:00
author: Brad Howes
tags: Swift, Github, CI
layout: post.hbs
image: computer-keyboard-stones-on-grass-background-header.jpg
---

I have a Swift package called [Knob](http://github.com/bradhowes/Knob) that creates a circular knob control for iOS and
macOS (and apparently tvOS too). For testing, I use the excellent
[SnapshotTesting](http://github.com/pointfreeco/swift-snapshot-testing) package from [Point•Free](https://pointfree.co)
that supports a nice collection of testable types like `NSView` and `UIView`, and artifact representations such as PNG
representations from those views. It works great on my laptop, but when run on Github, the tests fail because the PNG
images that the tests generate are not of the same format as they are on my laptop. This is primarily due to Retina
scaling, though there could also be colorspace issues and rendering environments (Metal vs CPU) coming into play as
well.

The key to making the tests work in a Github continuous-integration (CI) workflow is to partition the snapshot artifacts
into those that come from a dev environment such as my laptop, and those that comee from Github workflow. To that end, I
followed a comment made by another user of the SnapshotTesting library and modified the artifact names based on the
environment the test was running in. Here is the function I use to assert that the rendering of my test knob is the same
as before:

```swift
  func assertSnapshot(file: StaticString = #file, testName: String = #function, line: UInt = #line) throws {
    knob.layoutSubtreeIfNeeded()
    knob.display()
    let snapshotEnv = ProcessInfo.processInfo.environment["SNAPSHOT_ENV"] ?? "dev"
    let failure = verifySnapshot(matching: knob,
                                 as: .image(precision: 1.0, perceptualPrecision: 1.0),
                                 named: snapshotEnv,
                                 record: isRecording,
                                 snapshotDirectory: nil,
                                 file: file,
                                 testName: testName,
                                 line: line)
    guard let message = failure else { return }
    XCTFail(message, file: file, line: line)
  }
```

The start of the method asks the knob to render itself prior to being used for a snapshot -- for some reason on Github
without this I was seeing blank snapshots, and my tests were not exercising some custom `NSBezierPath` routines.

The Github CI workflow script set the `SNAPSHOT_ENV` value to be "ci" before it starts the bnild and test stage of the workflow:

```yaml
    - name: Build and Test
      run: make
      env:
        SNAPSHOT_ARTIFACTS: "$PWD/.snapshots"
        SNAPSHOT_ENV: ci
```

It also sets `SNAPSHOT_ARTIFACTS` so that if the SnapshotTesting library detects a difference, it will save the artifact
for the test failure in a location that we can use later on to upload to Github as a workflow artifact.

The ability to set `SNAPSHOT_ARTIFACTS` is nice, but unfortunately if the test failes because *no* artifact exists to
compare against, the SnapshotTesting library ignores it and instead plops the image file into the repo location where it
expected to find it, which is not very useful for me. To overcome this, I added a step in the CI workflow that saves the
entire contents of this location if the test step failed:

```yaml
    - name: Copy Snapshots
      if: ${{ failure() }}
      run: |
        mkdir .snapshots
        cp -r $(find . -name Knob-macOSTests)/__Snapshots__ .snapshots/
```

Now, when a new test fails because there is not a "ci" tagged image, I can download the artifacts, locate the new "ci"
image file and manually add it to the repo so that a subsequent commit will make it available for the CI tests. Not
ideal, but it works well enough for the times when I add a new test case.

If tests fail because of differences fonund in an existing artifact, the SnapshotTesting framework will do the right
thing and deposit the artifact from the failed test into the `SNAPSHOT_ARTIFACTS` directory. This allows me to evaluate
the difference and hopefully fix why the test failed.

Finally, here is the CI step that uploads any image artifacts. Note that it only executes if the build/test stage fails,
just like the copy step above.

```yaml
    - name: Upload Snapshot Failures
      uses: actions/upload-artifact@v3
      if: ${{ failure() }}
      with:
        name: snapshots
        path: .snapshots/
```

The entire CI script is viewable at [CI.yaml](https://github.com/bradhowes/Knob/blob/main/.github/workflows/CI.yml)

repository: bradhowes/keystrokecountdown

gha_language: Jupyter Notebook

repo_name: bradhowes/keystrokecountdown