text:
# qPyUtils
<!---
![Progress](http://progressed.io/bar/30?title=completed)
[![codebeat badge](https://codebeat.co/badges/a0171eb6-cda3-4c33-b5bc-fbba1affa373)](https://codebeat.co/projects/github-com-koyo922-qpyutils-master)
[![MIT Licence](https://badges.frapsoft.com/os/mit/mit.svg?v=103)](https://opensource.org/licenses/mit-license.php)
[![Join the chat at https://gitter.im/qPyUtils/Lobby](https://badges.gitter.im/qPyUtils/Lobby.svg)](https://gitter.im/qPyUtils/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-->
[![Build Status](https://travis-ci.org/koyo922/qPyUtils.svg?branch=master)](https://travis-ci.org/koyo922/qPyUtils)
[![codecov](https://codecov.io/gh/koyo922/qPyUtils/branch/master/graph/badge.svg)](https://codecov.io/gh/koyo922/qPyUtils)
[![PyPI version](https://badge.fury.io/py/qPyUtils.svg)](https://badge.fury.io/py/qPyUtils)
[![Python versions](https://img.shields.io/badge/python-2.7%20|%203.6-blue.svg)](https://www.python.org/downloads/release)
![platform](https://img.shields.io/badge/platform-mac%20os%20|%20linux-lightgrey.svg)

Python/Bash utils by qianws and his collections
--- A util package for human (usability/readability is the first-concern)

## Getting Started

Basically, it's a warehouse of all the handy "wheels" I built/collected along my life as a Pythonista.

Just open and use, intuitively as the following examples:

### Debuging / Testing

- `start_in_thread(fn, *args, **kwargs)` single line to run a function in background thread
- `auto_unstub()` Automatically unstub mockito patch/mocks
- `mockify`a context protocol for modifying one or more objects

```python
from qPyUtils.debug import auto_unstub, mockify, start_in_thread

# ---------- start_in_thread
start_in_thread(function_to_start_a_web_server, host='localhost', port=8011)
time.sleep(0.1)  # waiting server to start, critical for Travis-CI
assert requests.get('http://localhost:8011/...') == ...

# ---------- auto_unstub
@auto_unstub  # `mockito.unstub()` is inserted into `tearDown()` logic
class TestInitLog(TestCase):
    def test_method(self):
        ... # code that may use mockito

    def test_method2(self):
        # ---------- mockify
        with mockify(sys.stderr) as sys.stderr:  # temporarily suppress stderr
            ...  # code that calls `sys.stderr.write()`
            verify(sys.stderr, atleast=1).write(Ellipsis)
```

### Log (or any text file) parser

Just inherent the `BaseLogParser` and implement some methods;
the framework will do the heavy-lifting for you, including:
- filtering files by date
- using thread/process_pool for multiple loading files in parallel
- logging malformed lines
- recursively find and load all target files under specified path

```python
from qPyUtils.log.parser.base import BaseLogParser

# extend and implement some logic (please read full API documentation for complete info)
class MyLogLoader(BaseLogParser):
    LOG_TYPE = 'my_log'

    def glob_files(self, base_path):
        # type: (Path) -> Iterable[Path]
        return base_path.rglob('*.log')

    def logfile2blocks(self, path):
        # type: (Path) -> Iterable[Text]
        from qPyUtils.text import csplit  # python mimic for the `csplit` command in bash
        with path.open(mode='rt', encoding='utf8') as lines:
            return (''.join(block) for block in csplit(lines, re.compile(r'^{"version')))

    def block2records(self, block):
        # type: (Text) -> Iterable[dict]
        for rec in dirty_json_or_none(block)['records']:
            yield dict(**rec)

# now, use the magic power for free
my_log_loader = MyLogLoader()
my_log_loader.load_dir('./log')
my_log_loader.load_single_file('./log/my_log.2018-08-01.log')
```

### Standardized manner of initializing a logger

The easy & standardized usage of logger in Python
```python
from qPyUtils.log.writer import init_log

# set logger_name to None or ''(as default), to use the root-logger
# the directories along the log_path will be automatically created if not yet exist
# a reasonable default format string, and daily log rotation is also provided.
logger = init_log(log_path='/home/my_name/my_project/log/my_log_file')

# set log_path to None or ''(as default)
# so that no file handlers are involved, only logs to console
logger = init_log()

# set `is_writing_console=False` to suppress console output
# not that for such case, you must provide a log_path; otherwise, no handlers will work
logger = init_log(is_writing_console=False, log_path='./log/my_log_file')
```

### `Timer` as a context manager

```python
import time
import qPyUtils.log.timer

# user-defined output_fn; feel free to try using `output_fn=logger.info` etc.
res = []
with qPyUtils.log.timer.Timer('Long task 中文', output_fn=res.append) as timer:
    with timer.child('large step'):
        time.sleep(1)
    for _ in range(5):
        with timer.child('small step'):
            time.sleep(0.5)
    print(res[0])
# ----- result:
# Long task 中文: 3.506s
#   5x small step: 2.503s (71%)
#   1x large step: 1.001s (28%)

# user-defined format_string
with qPyUtils.log.timer.Timer('Long task 中文', fmt='{name} --> {elapsed:.3f}') as timer:
    time.sleep(0.1)
# ----- result:
# Long task 中文 --> 0.101s
```

### Constant variables and functions

- `dummy_fn(*args, **kwargs)`: accepts anything but does nothing
- `identify_fn(arg)`: just reflect the `arg` passed in
- `T`: a `typing.TypeVar` for generic programming type-hints

### Parallel util

A light weight thread/process pool
- intuitive interface
- auto utilize multi CPU cores
- progress bar
- support `*args` / `*kwargs`
- Exception object returned in place of the corresponding task result

```python
from qPyUtils.parallel import para
import math

# simple usage; pass in tasks and function, get results
tasks = range(5)
fn = math.factorial
assert [1, 1, 2, 6, 24] == para(tasks, fn)

# you can still degrade to single thread --- sequential
# or even suppress the progress bar
para(tasks, fn, n_jobs=1, is_suppress_progressbar=True)

# support kwargs via the `use_kwargs` param
# CAUTION: `fn` should avoid appear in closure of the `para()` func; this is just for demo
fn2 = lambda x: math.factorial(x)
para([{'x': t} for t in tasks], fn2, use_kwargs=True)
```
### Streaming utils
Data streaming / Functional programming related utils.

```python
from qPyUtils.streaming import Repeat

# ---------- decorator over function
# turns a generator factory function into a sequence-like iterable;
# which could be iterated multiple epochs
@Repeat
def my_gen():
    for i in range(3):
        yield i

# NOTE: now the name `my_gen` is the wrapped structure; no parenthesis here
assert (0, 1, 2) == tuple(my_gen)
assert (0, 1, 2) == tuple(my_gen)

# ---------- decorator over method
class MyClazz(object):
    @Repeat
    def my_method(self, a, b, prefix='>>>'):
        for i in range(a, b):
            yield '{}{}'.format(prefix, i)

obj = MyClazz()
my_gen = obj.my_method(0, 3, prefix=':') # call as normal

assert (':0', ':1', ':2') == tuple(my_gen)
assert (':0', ':1', ':2') == tuple(my_gen)
```

### Text utils

```python
from qPyUtils.text import *

>>> assert is_none_or_empty('')
>>> assert is_none_or_empty(None)

# avoid python2's stupid handling logic for str/unicode
>>> dump_utf8({'name': u'中文'})  # use json.dumps() to avoid the ugly `\u....` / `\x..`
{"name": "中文"}

>>> lines = [
...     'line1',
...     '---- line2',
...     'line3',
...     'line4',
...     '---- line5',
...     'line6'
... ]
>>> pattern = r'----'
# mimic the `csplit` command in bash
# which groups text lines into blocks; from current line (inclusive) to next pattern-matching-line (exclusive)
# auto handles last buffer or empty input sequence
>>> list(csplit(lines, pattern))
[('line1',), ('---- line2', 'line3', 'line4'), ('---- line5', 'line6')]

# unify str/unicode/bytes in py2/py3 into Text type, using UTF8
>>> ensure_text(b'abc')
u'abc'
>>> ensure_text(b'中文')
u'中文'
>>> ensure_text(u'中文')
u'中文'
```

### Web utils

One-liner annotation turns your function into a RESTful service

```python
# ----- server side (CAUTION: UNICODE_LITERALS OR u'...' IS NECESSARY FOR NON-ASCII REQUESTS)
# encoding: utf-8
from __future__ import unicode_literals
from qPyUtils.web import RESTful

@RESTful(port=8004, route='/')
def introduce(name, friends):
    return '{} has friends: {}'.format(name.upper(), ', '.join(friends))

introduce.serve()
```

```bash
# ----- client side
# Unicode is automatically translated by UTF8
$ curl 'http://localhost:8004?name=koyo' -d 'friends=solar' -d 'friends=ape' -d 'friends=tutor' -d 'friends=斑马'
KOYO has friends: solar, ape, tutor, 斑马%
```

### System utils

A command line tool for forwarding port(s); Unicode Domain-Name is also supported.

```bash
# ----- ensure PYTHON_BIN is in the PATH; consider adding it to ~/.bashrc
PYTHON_BIN=$(python -c 'from distutils.sysconfig import EXEC_PREFIX as p; print(p + "/bin")')
export PATH=${PYTHON_BIN}:$PATH
portforward -H www.nic.ad.jp -p 80 -l 8012

# ----- OR just simply call by `python -m ...` as an ad-hoc solution
python -m qPyUtils.system.portforward -H www.nic.ad.jp -p 80 -l 8012
```

```commandline
Usage:
  portforward (-c <conf_path> | -H <host> -p <port> -l <local_port>)
  portforward -h | --help

Demo conf file:
<host>	<port>	<local_port>
www.nic.ad.jp	80	8012
中国互联网络信息中心.中国	80	8013
```

A function simulating `rm -f <path>`
- support both dir and file
- ignore_errors, if not exist

```python
from qPyUtils.system.file_system import rm
rm('path/to/your/dir/or/file', ignore_errors=True)
```

### Prerequisites

- A *NIX OS
- python >= 2.7 or python >= 3.5

### Installing

For common package users,
it's as simple as typing `pip install qPyUtils` and having a cup of coffee, then it's done.

If you want to develop it, please follow the instructions below:

1. `git clone <url-of-this-repo> && cd qPyUtils/` , get the repo and cd inside
2. `pip install -r requirements-dev.txt` , install all the dependencies for developing
3. `pyb install_dependencies analyze -v` , using the powerful PyBuilder build-system to get the rest job done.

## Running the tests

1. following the installing procedure for developers as above
2. `pyb run_integration_tests -v`

## Deployment

Read the `.travis.yml` file for deployment settings, I use Travis-CI for PyPI/ReadTheDocs continuous delivery.

## Built With

* [PyBuilder](http://pybuilder.github.io) - The modern build tool for Python(just like maven/gradle for java)
* [Travis-CI](https://travis-ci.org) - The famous CI service vendor
* [Sphinx](http://www.sphinx-doc.org) - The de facto standard for docs the Python world

## Contributing

Bug, Issues, Doc, Pull Request ... --- Any contribution is welcomed!
Feel free to get your hands dirty and help me improve it.

Most of the code is well-documented and carefully-tested;
It's easier than you might think to extend it.

## Authors

- **QIAN Weishuo** - *Initial work* - [Facebook](https://www.facebook.com/profile.php?id=100005178853657)

See also the list of [contributors](https://github.com/koyo922/qPyUtils/contributors) who participated in this project.

## License

This project is licensed under the MIT License
[![MIT Licence](https://badges.frapsoft.com/os/mit/mit.svg?v=103)](https://opensource.org/licenses/mit-license.php)

## Acknowledgments

* `debug.auto_unstub()` https://gist.github.com/jnape/5767029
* `log.writer()` http://styleguide.baidu.com/style/python/index.html
* `text.dirty_json_or_none()` https://github.com/codecobblers/dirtyjson
* `log.timer.Timer()` https://github.com/mherrmann/timer-cm

gha_language: Python


text:
# overdub
[![Build Status](https://travis-ci.org/vinsonchuong/overdub.svg?branch=master)](https://travis-ci.org/vinsonchuong/overdub)

Add full ES.Next support to Node.js

## Usage
Install [overdub](https://yarnpkg.com/en/package/overdub)
by running:

```sh
yarn add --dev overdub
```

Import `overdub/register` from the `node` CLI or from a test runner. For
example:

```sh
node -r overdub/register
```

Support for all standardized ECMAScript features is provided via Babel. React
and Flow syntax is also supported.

For test runners and other CLI tools that require users to specify a Babel
config, reuse the `overdub` Babel config like so:

```json
{
  "extends": "overdub/babel"
}
```

license: MIT

repository: vinsonchuong/overdub

branch_name: refs/heads/master

extension: md

gha_language: JavaScript

gha_license_id: MIT

license_type: permissive

repo_name: vinsonchuong/overdub


text:
# Containers

## Handling requests

In order to handle requests to your Async API, one of your containers must run a web server which is listening for HTTP requests on the port which is configured in the `pod.port` field of your [API configuration](configuration.md) (default: 8080).

Requests will be sent to your web server via HTTP POST requests to the root path (`/`) as they are pulled off of the queue. The payload and the content type header of the HTTP request to your web server will match those of the original request to your Async API. In addition, the request's ID will be passed in via the "X-Cortex-Request-ID" header.

Your web server must respond with valid JSON (with the `Content-Type` header set to "application/json"). The response will remain queryable for 7 days.

## Readiness checks

It is often important to implement a readiness check for your API. By default, as soon as your web server has bound to the port, it will start receiving traffic. In some cases, the web server may start listening on the port before its workers are ready to handle traffic (e.g. `tiangolo/uvicorn-gunicorn-fastapi` behaves this way). Readiness checks ensure that traffic is not sent into your web server before it's ready to handle them.

There are two types of readiness checks which are supported: `http_get` and `tcp_socket` (see [API configuration](configuration.md) for usage instructions). A simple and often effective approach is to add a route to your web server (e.g. `/healthz`) which responds with status code 200, and configure your readiness probe accordingly:

```yaml
readiness_probe:
  http_get:
    port: 8080
    path: /healthz
```

## Multiple containers

Your API pod can contain multiple containers, only one of which can be listening for requests on the target port (it can be any of the containers).

The `/mnt` directory is mounted to each container's filesystem, and is shared across all containers.

## Resource requests

Each container in the pod requests its own amount of CPU, memory, GPU, and Inferentia resources. In addition, Cortex's dequeuer sidecar container (which is automatically added to the pod) requests 100m CPU and 100Mi memory.

## Observability

See docs for [logging](../../clusters/observability/logging.md), [metrics](../../clusters/observability/metrics.md), and [alerting](../../clusters/observability/metrics.md).

## Using the Cortex CLI or client

It is possible to use the Cortex CLI or client to interact with your cluster's APIs from within your API containers. All containers will have a CLI configuration file present at `/cortex/client/cli.yaml`, which is configured to connect to the cluster. In addition, the `CORTEX_CLI_CONFIG_DIR` environment variable is set to `/cortex/client` by default. Therefore, no additional configuration is required to use the CLI or Python client (which can be instantiated via `cortex.client()`).

Note: your Cortex CLI or client must match the version of your cluster (available in the `CORTEX_VERSION` environment variable).

## Chaining APIs

It is possible to submit requests to Async APIs from any Cortex API within a Cortex cluster. Requests can be made to `http://ingressgateway-apis.istio-system.svc.cluster.local/<api_name>`, where `<api_name>` is the name of the Async API you are making a request to.

For example, if there is an Async API named `hello-world` running in the cluster, you can make a request to it from a different API in Python by using:

```python
import requests

# make a request to an Async API
response = requests.post(
    "http://ingressgateway-apis.istio-system.svc.cluster.local/hello-world",
    json={"text": "hello world"},
)

# retreive a result from an Async API
response = requests.get("http://ingressgateway-apis.istio-system.svc.cluster.local/hello-world/<id>")
```

To make requests from your Async API to a Realtime, Batch, or Task API running within the cluster, see the "Chaining APIs" docs associated with the target workload type.

repository: cortexlabs/cortex

gha_language: Go

repo_name: cortexlabs/cortex


text:
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
![PyPI](https://img.shields.io/pypi/v/video2images?style=plastic)
![Open Source? Yes!](https://badgen.net/badge/Open%20Source%20%3F/Yes%21/blue?icon=github)
![Python3](https://img.shields.io/badge/python->=3.5-green.svg)
[![made-with-python](https://img.shields.io/badge/Made%20with-Python-1f425f.svg)](https://www.python.org/)
[![install](https://img.shields.io/badge/pip%20install-video2images-green)](https://pypi.org/project/video2images/)

[![DOI](https://zenodo.org/badge/299598465.svg)](https://zenodo.org/badge/latestdoi/299598465)
[![Downloads](https://pepy.tech/badge/video2images)](https://pepy.tech/project/video2images)
[![Downloads](https://pepy.tech/badge/video2images/month)](https://pepy.tech/project/video2images)
[![Downloads](https://pepy.tech/badge/video2images/week)](https://pepy.tech/project/video2images)

## About
A library that helps to convert volumetric video data into image frames with adjustable frame capturing rate functionality.

The main reason why I created this library is to ease the video to image frames conversion process. During video annotation we need frames of an video or a subpart of a video and that too custom frame capture rate, so this problems led to this library development.

## How to install?
```pip install video2images```

## Requirements
It will be automatically installed
- tqdm, imageio, imageio-ffmpeg, moviepy

## Class Object Argument Description

    Argument
    Description

    video_filepath
    source path of the video

    start_time
    Default is None i.e 0s will be considered

    end_time
    Default is None i.e  till last duration will be
considered

    capture_rate
    No. of frames you want to capture per second.
For e.g if my capture_rate= 20 then only first 20
frames will captured out of input Frames per second rate

    save_format
    Output frame image extension. By default ".jpg"

    out_dir
    Output directory for saving images. If not specified
a folder will be made in current directory and saved

#### **Note**:- The capture_rate if not specified will consider the original video frames per second rate

## Frame Capture Rate Explaination

## Valid Extensions

### For Video
- .mov
- .avi
- .mpg
- .mpeg
- .mp4
- .mkv
- .wmv

### For Image
- .jpg, .jpeg
- .png
- .bmp
- .tiff, .tif
- .dicom, .dcm

## How to use?

### Minimal setting (Basic)
```
from video2images import Video2Images

Video2Images(video_filepath="--path-to-video-file--",
             out_dir="--path-to-output-directory--")

```

### Want to capture frames in between some interval
```
from video2images import Video2Images

# Lets take start_time to be 2mins i.e 120s
# & end_time to be 10 mins i,e 600s out of 20mins videos

Video2Images(video_filepath="--path-to-video-file--",
             start_time=120,
             end_time=600,
             out_dir="--path-to-output-directory--")

```
### Want only first 'f' frames out of 30 frames per second
```
from video2images import Video2Images

# Let say f = 20 i.e capturing only first 20 frames
Video2Images(video_filepath="--path-to-video-file--",
             capture_rate=20,
             out_dir="--path-to-output-directory--")
```

### Want output image to be saved in png or other format
```
from video2images import Video2Images

Video2Images(video_filepath="--path-to-video-file--",
             save_format=".png",
             out_dir="--path-to-output-directory--")

```
## From command line
We can convert video frames to images by using simple command line as follows
```
$video2images --video_filepath <input video filepath> \
--start_time <some integer number in seconds> \
--end_time <some integer number in seconds> \
--capture_rate <some integer capture rate> \
--save_format <any one image extension> \
--out_dir <output folder name where all images will be pushed>
```

#### **Note**:- The output will be saved in a folder named frames_folder_{timestamp}

## Output Process Screenshot

## Author

I will be happy to connect with you guys!!

[Linkedin](https://www.linkedin.com/in/abhishek-c-salian/)

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

## Citation
```
@software{abhishek_c_salian_2020_4384148,
  author       = {Abhishek C. Salian},
  title        = {Video2Images: A python library for video frames extraction for video annotation based task},
  month        = dec,
  year         = 2020,
  publisher    = {Zenodo},
  version      = {v1.1},
  doi          = {10.5281/zenodo.4384147},
  url          = {http://doi.org/10.5281/zenodo.4384147}
}
```

### **Any suggestions are most welcome.**


text:
![build badge](https://github.com/PacktPublishing/Effortless-Cloud-Native-Apps-Development-using-Skaffold/actions/workflows/main.yml/badge.svg)

### Effortless-Cloud-Native-Apps-Development-using-Skaffold

Simplify development and deployment of cloud-native Spring Boot applications on Kubernetes with Skaffold.

### Key Features:
* Learn how to build and deploy cloud-native applications quickly with Kubernetes
* Create a production-ready continuous integration and continuous delivery (CI/CD) pipeline for cloud-native apps
* Discover ways to create a GitOps-style CD workflow for cloud-native applications

### What you will learn?

:bulb: Solve the challenges faced while working in an inner development loop using Skaffold

:rocket: Accelerate your development workflow using Skaffold

:open_book: Understand the architecture, the internal working of Skaffold, and supported CLI commands

:hammer_and_wrench: Build and deploy containers to Kubernetes using the Skaffold CLI and Cloud Code

:wheel_of_dharma: Deploy Spring Boot applications to fully managed Kubernetes services such as Google Kubernetes Engine using Skaffold

:man_technologist: Explore best practices for developing an app with Skaffold

:warning: Avoid common pitfalls when developing cloud-native apps with Skaffold in Kubernetes

branch_name: refs/heads/main


text:
PHP JobQueue component
======================

Simple Job/Queue PHP composent to help applications distribute Tasks through
multiple workers.

Tasks may have children (sub tasks that are added to Queue when their parents
have been successfuly executed).

Queue enables to follow Tasks progress. A Task reach 100% progress when all its
children have been finished too.

Currently only Redis has been integrated to store Queue data.

Vocabulary:

  * **Job** define the work

  * **Task** register all options and params to run Jobs, set profile, and
    track progress

  * **Queue** store and manage Tasks, provide Tasks for Workers

  * **Worker** takes Tasks from Queue to setup Jobs and execute them

  * **profile** affected to Tasks, Workers are then set up to only take Tasks
    having certain profiles

  * **status** a Task may have one of the following profiles:
    - `pending`  not in Queue yet
    - `waiting`  in Queue
    - `running`  currently setting up a Job that is executed
    - `success`  successfuly executed, may still have children not yet treated
    - `failed`   an error prevented the Job from being executed
    - `finished` out of Queue, successfuly treated, not more waiting children

Install
-------

Use composer to install the composent dependancies :

	cd /path/to/composent
	php composer.phar install

Write a Job
-----------

Jobs are simple class that must extend the `AbstractJob` parent class.

Jobs must be setup through a `setup()` method that must at least provide
a name and may add some Job required parameters and settings, and pre
execute routines.

See example/Job to view a Job example.

Useful methods:

  * `$this->hasParameter($name)`            check if a parameter exists

  * `$this->getParameter($name, $default)`  retrieve a parameter by its name

  * `$this->setTaskProgress($float)`        to track Job progress while running

Add Tasks to Queue
------------------

Here is an example of how you create and add Tasks to Queue (you can also look
at the `task:import` command):

```php
<?php

require '/path/to/vendor/autoload.php';

use Libcast\JobQueue\Task\Task;
use Libcast\JobQueue\Queue\QueueFactory;
use Predis\Client;

$task = new Task(
    new Libcast\JobQueue\Test\DummyJob,
    'dummy',
    [
        'param1' => 'foo',
        'param2' => 'bar',
    ]
);

// setup a Redis client
$redis = new Client('tcp://localhost:6379');

// load Queue
$queue = QueueFactory::build($redis);

// add Tasks to the Queue
$queue->enqueue($task);
```

CLI
---

### Synopsis

    queue
      queue:show        List jobs from the queue
      queue:flush       Flush the queue
      queue:recover     Move all buggy Tasks to the `waiting` list
    task
      task:add          Add a Task
      task:delete       Delete a Task
      task:edit         Edit a Task
    worker
      worker:run        Run a worker

A typical command would look like:

    bin/jobqueue queue:show example/config.php
    bin/jobqueue worker:run profile example/config.php

repository: msumme/JobQueue

repo_name: msumme/JobQueue


text:
---
title: document-similarity-social-network
date: 2020-08-25 13:00:00 +08:00
tags: [Social Network, Natural Language Processing, Machine Learning]
description: This project is to compare the similarity of documents.
image: "/document-similarity-social-network/tf-idf.png"
---

# Document Similarity Social Network

## Flow

### Calculate tf-idf feature.

TF-IDF stands for “Term Frequency, Inverse Document Frequency.” It’s a way to score the importance of words (or “terms”) in a document based on how frequently they appear across multiple documents.

![tf-idf](https://raw.githubusercontent.com/ekko771/ekko771.github.io/master/_posts/document-similarity-social-network/tf-idf.png)

### Calculate cosine similarity matrix.

![similarity matrix](https://raw.githubusercontent.com/ekko771/ekko771.github.io/master/_posts/document-similarity-social-network/similarity_matrix.png)

### Calculate nodes relationships with threshold-based neighbors.

![pick neighbors](https://raw.githubusercontent.com/ekko771/ekko771.github.io/master/_posts/document-similarity-social-network/pick.gif)

## What is Vis.js

A dynamic, browser based visualization library. The library is designed to be easy to use, to handle large amounts of dynamic data, and to enable manipulation of and interaction with the data. The library consists of the components DataSet, Timeline, Network, Graph2d and Graph3d.

## Document Social Network Result

![document network result](https://raw.githubusercontent.com/ekko771/ekko771.github.io/master/_posts/document-similarity-social-network/document-network.png)

### Practical application

![document similarity application](https://raw.githubusercontent.com/ekko771/ekko771.github.io/master/_posts/document-similarity-social-network/recommand.png)

## Methodology references:

* [The TF-IDF algorithm explained.](https://www.onely.com/blog/what-is-tf-idf)
* [Calculate cosine similarity matrix.](https://en.wikipedia.org/wiki/Cosine_similarity)
* Calculate nodes relationships with threshold-based neighbors.
## Tool references:

* Social Network Visualization.
    * [Vis.js](https://visjs.github.io/vis-network/examples/)
    * [[Network - groups](https://visjs.github.io/vis-network/docs/network/groups.html)
    * [[Network - nodes](https://visjs.github.io/vis-network/docs/network/nodes.html)
    * [[Network - edges](https://visjs.github.io/vis-network/docs/network/edges.html)

gha_language: SCSS


text:
---
external help file: AutomatedLab-help.xml
Module Name: AutomatedLab
online version:
schema: 2.0.0
---

# Get-LabHyperVAvailableMemory

## SYNOPSIS
Get available HyperV memory

## SYNTAX

```
Get-LabHyperVAvailableMemory
```

## DESCRIPTION
Gets the available of the amount of RAM the local HyperV manages (TotalVisibleMemorySize of the Win32_OperatingSystem WMI class)

## EXAMPLES

### Example 1
```powershell
PS C:\> Get-LabHyperVAvailableMemory
```

Gets the available of the amount of RAM the local HyperV manages (TotalVisibleMemorySize of the Win32_OperatingSystem WMI class)

## PARAMETERS

## INPUTS

## OUTPUTS

## NOTES

## RELATED LINKS

repository: nyanhp/AutomatedLab

gha_language: PowerShell

repo_name: nyanhp/AutomatedLab


text:
Please can we have a general nim interactive? Ideally it would allow a user to play against the computer or against another user.

Ideally it would be designed so you could play:
1. with counters (any number of piles and each pile containing any number of counters), simplest version being like Nim-7 (id 1204), but being adaptable like (id 1274), also being able to play Last Biscuit (id 2656)
2. with numbers like Got It (id 1272)
3. with a particular spatial arrangement, like a spiral (see Liz) and something like Slippery Snail (id 1210)

No idea if I've given you enough info here or whether this is feasible in terms of being different 'views' of the same interactive

path: /longpages/Strategy Games/animations.md


text:
# ESP8266IFTTT
an IFTTT Webhook trigger library for ESP8266 dev boards.

## Installation

Clone this repository to a following directory.

```
 /Users/YOUR_USER_NAME/Documents/Arduino/libraries/
 (for those who use Mac. )
```

Please google "Where to install Arduino additional libraries on Windows PC?" if you use Windows PC.

## How to use

### Request to use a header file in your sketch

Insert a following line to top of your sketch.

```
#include <ESP8266Ifttt.h>
```

### Call a function

Call function like following...

```
IFTTT.trigger(IFTTT_WEBHOOK_NAME, IFTTT_KEY);
```

where IFTTT_WEBHOOK_NAME is your IFTTT Webhook's name, and IFTTT_KEY is your IFTTT Webhook api key.


text:
## QuickStart
**simpler-paper** is a minimalist document generator.
you only need to run a command, all of the Markdown will be automatically integrated into the site.

In principle, we have reduced the configuration as much as possible, most of the functions are customary,
you can find the way to use in the **feature** directory.

In addition, we have also prepared a different style of css-style for you, you never to worry about style. everything is so simple.

### Build and preview
with just one command, you can easily compile the file and the local preview.
```bash
# install
npm install -g simpler-paper

# init
paper init

# dont forget to add some markdown files.
# build to html
paper build

# preview
paper s
```

### Deploy

```bash
# In default, the document will be released to github.
paper deploy
```

you need set github pages (maybe...🙄):

  1. go to your rep.
  2. Settings > Options > GitHub Pages
  3. choose the source for **gh-pages branch**

the actual effect:

![example](assets/example-pages.png)

repository: Lzumikonata/simpler-paper

repo_name: Lzumikonata/simpler-paper


text:
# Prepare your data

## Download the WaMDaM Workbook
Templates for Input Data to prepare your data into it. Each dataset into one workbook

|Download|         |Use it for |
|---| :---------------: |:------------- |
|WaMDaM Workbook Template  |Download| Generic template for any data source to WaMDaM|

## Data Preparation Utility

|Download|         |Use it for |
|---| :---------------: |:------------- |
|Prepre shapefile template   | Download |Transform the shapefile columns into WaMDaM sheets |
|Prepare time series template| Download|Transform time series data into WaMDaM sheets|
|Prepare seasonal data template| Download|Transform seasonal data into WaMDaM sheets|

## Why Excel?
We chose Excel as a generic input data medium with a custom Excel workbook that has 17 sheets with fixed column headers for the main tables of input data in WaMDaM. Each dataset is prepared to a single workbook one-at-a-time. The sheets are related with each other through dropdown lists to help users for example to relate metadata elements to the attributes and data values

The Wizard maps all the bridge tables’ complex relationships and users do not need to know anything about primary or foreign keys.

## Preprare data order
**First**: Load the controlled vocabulary or leave them blank.
Controlled vocabulary are available in the template workbook and users can update them in a button on the workbook’s homepage sheet. The button calls the online registry application user interface and updates the list of vocabularies in the sheet. Then the CVs are available as dropdown lists in each sheet where they apply.

**Second**: Define metadata that will be used for the Attributes and Instances.

**Third**: Define the data structure of Object Types and Attributes.

**Fourth**: Add the master network, scenario, and nodes and links.

**Fifth**: Load data values to each attribute of each Instance.

## Simple case
Users have to populate at least six sheets for any dataset and they can populate more as the complexity of the dataset increases. In a simple case, the three sheets of Organizations&People, Sources&Methods, Networks&Scenarios can be populated with only two rows each.

repository: WamdamProject/WaMDaM-software-ecosystem

repo_name: WamdamProject/WaMDaM-software-ecosystem


text:
# canvas-where-am-I
Theme .js and .css to add within course navigation to Instructure Canvas *on the web*. Because the Canvas student app does not support ajax calls, it will not work on the student app. Does the following:

## Add Modules sub-menu
* Modules sub-menu item takes you to Modules page but hides other Modules
![Clicking on Module in menu shows only that Module](./readme-images/sub-menu-shows-only-selected-module.png)
* For Pages and other items that are launched via the Modules page, the appropriate Module will be highlighted in the list below Modules (note that there is a switch: allowMultilineModuleTitles to specify whether to allow Module titles to wrap)
![See containing Module](./readme-images/sub-menu-shows-module-containing-page.png)
* Modules takes you to normal Modules view (unless it is the Home page)
![Modules works as normal](./readme-images/modules-shows-normal-modules.png)

## Add tiles at top of Modules tool (ONLY if Modules is set as home page):
![Autogenerated tiles for home page](./readme-images/autogenerated-module-tiles-and-navigation.png)
* Tiles are generated by calling the Canvas api
* Added a drop-down arrow which gives you a quick link to the Module item (page, discussion, etc) - NOTE: only if showItemLinks==1
* Clicking the tile anywhere except the drop-down arrow takes you to the appropriate part of the Modules page

## Add progress bar below content (between Previous and Next buttons) as either:
* icon buttons for each item in a Module, linking to that item - rollover to see what that item is
![Icons buttons for progress](./readme-images/autogenerated-progress-buttons.png)
* if insufficient space for buttonms, shows rectangle for each page, indicating position through Module. Tooltip shows title of item.
![Bar for progress](./readme-images/autogenerated-progress-bar.png)

## Copy Previous and Next buttons from bottom of page to top (** Code curently comented out **)
![Previous and next at top of page](./readme-images/previous-and-next-buttons-at-top-of-page.png)
* currently not working on every content type - see notes in code

# Installation
You'll need admin rights in a subaccount to be able to upload the canvas-where-am-I.css and canvas-where-am-I.js files into a Theme - see: https://community.canvaslms.com/docs/DOC-10862-4214724282
**NOTE: Please read the 'Custom File Risks' section of the Canvas docs on theming to make sure you understand what you are doing**
1. Look at the various 'Configurable variables' at the top of the canvas-where-am-I.js - they are commented - and adjust as appropriate
2. Upload the canvas-where-am-I.css and canvas-where-am-I.js into the **CSS** and **JavaScript File** boxes for the **Canvas desktop application** only (it will not work on the student app).
3. If you would like your Home page to display the tiles for each Module, set the Modules page as your Home page.

# Contributing
I would be grateful for any help you can give with this. Some of the more obvious enhancements are in the 'Issues' for this repository. As well as these issues, there are some TODOs at the top of canvas-where-am-I.js.

# Development
If you are wanting to work on this script there are some supporting files that make development faster. To set this up you first need to install [npm](https://www.npmjs.com/get-npm) and [mkcert](https://github.com/FiloSottile/mkcert). Once installed run the initial setup of `mkcert`:

    mkcert -install

This will install a trusted root certificate which will mean your browser can load files from a local webserver over HTTPS without forcing you to accept the untrusted certificate first.

The next step is to generate a certificate to use with:

    mkcert localhost

Then install all the `npm` dependencies with:

    npm install

Then startup the local webserver that will response to requests.

    npm run start

There is then a file, [development.js](./development.js) that should be added to your theme as a JavaScript file which will dynamically add JS/CSS from your local webserver to Canvas.

# Problems
Please report these as Issues and I will try and sort them out as soon as possible

# Caveat
This code relies heavily on the ids and classes of various elements in Canvas. As a result it is likley to break when Instructure make changes to the Canvas UI. I hope I am not being naive in thinking that these should be fairly simple to fix when necessary, particularly with help from others in the lovely Canvas community :)

repository: msdlt/canvas-where-am-I

repo_name: msdlt/canvas-where-am-I


text:
# Replit-Env
Keep your code private without hacker plan

## How to compile
To compile, just download and run `compile.js`. Just enter the file name for the source and destination, and you'll be good to go.

## How to run
To run, make sure your `.env` contains the compiled code. Next, install the `replit-env` module and require it. Then run the function and it will import the code from the `.env` file, write it to a file, require that file, and then delete the file. You can now run code with the source hidden.

## Example
`index.js`:
```js
const env = require('replit-env');
env();
```
`.env`:
```
L0=console.log("Hello, world!");
```
console output:
```
Hello, world!
```

repository: YodaLightsabr/Replit-Env

repo_name: YodaLightsabr/Replit-Env


text:
# Third digit

## Description
Write a program that reads an integer **N** from the console and prints **true** if the third digit of **N** is **7**, or **"false THIRD_DIGIT"**, where you should print the third digits of **N**.
  - The counting is done from **right to left**, meaning 123**4**56's third digit is **4**.

## Input
- The input will always consist of exactly one line, containing the number **N**.

## Output
- The output should be a single line - print whether the third digit is **7**, following the format described above.

## Constraints
- **N** will always be valid non-negative integer number.
- Time limit: **0.1s**
- Memory limit: **16MB**

## Sample tests

|     Input      |     Output     |
|----------------|----------------|
|5               |False 0         |
|701             |True            |
|9703            |True            |
|877             |False 8         |
|777877          |False 8         |
|9999799         |True            |

## Submission
- Submit your code [here](???)

repository: nakov/Python-Course-SoftUni

repo_name: nakov/Python-Course-SoftUni


text:
---
layout: post
title: "OsPS1-F"
description: ""
category: genes
tags: [growth, development, grain, tiller, grain yield, tiller number, photosystem]
---

* **Information**
    + Symbol: OsPS1-F
    + MSU: [LOC_Os03g56670](http://rice.uga.edu/cgi-bin/ORF_infopage.cgi?orf=LOC_Os03g56670)
    + RAPdb: [Os03g0778100](https://rapdb.dna.affrc.go.jp/locus/?name=Os03g0778100)

* **Publication**
    + [The OsPS1-F gene regulates growth and development in rice by modulating photosynthetic electron transport rate.](http://www.ncbi.nlm.nih.gov/pubmed?term=The OsPS1-F gene regulates growth and development in rice by modulating photosynthetic electron transport rate.%5BTitle%5D), 2017, Plant Cell Rep.

* **Genbank accession number**

* **Key message**
    + The OsPS1-F gene regulates growth and development in rice by modulating photosynthetic electron transport rate.
    + Our results illustrate that OsPS1-F plays an important role in regulating proper growth and development of rice plants
    + Ds insertion in rice OsPS1-F gene results in semi-dwarf plants with reduced tiller number and grain yield, while genetic complementation with OsPS1-F rescued the mutant phenotype
    + Here, we report the characterization of OsPS1-F (encoding Oryza sativa PHOTOSYSTEM 1-F subunit) using a single copy Ds insertion rice mutant line

* **Connection**

[//]: # * **Key figures**


text:
# Change Log - @microsoft/fast-router

This log was last generated on Fri, 21 May 2021 17:48:08 GMT and should not be manually modified.

<!-- Start content -->

## 0.2.3

Fri, 21 May 2021 17:48:08 GMT

### Patches

- Bump @microsoft/fast-element to v1.4.0<EMAIL_ADDRESS>
## 0.2.2

Wed, 19 May 2021 23:37:36 GMT

### Patches

- Bump @microsoft/fast-element to v1.3.0<EMAIL_ADDRESS>
## [0.2.1](https://github.com/Microsoft/fast/compare/@microsoft/fast-router@0.2.0<EMAIL_ADDRESS>(2021-04-06)

**Note:** Version bump only for package @microsoft/fast-router

# 0.2.0 (2021-03-16)

### Features

* **fast-router:** add a web-components-based router to FAST ([#3993](https://github.com/Microsoft/fast/issues/3993)) ([c787a96](https://github.com/Microsoft/fast/commit/c787a96d72d92fd171b37ace1f49479a9d9b3eec))

repository: musale/fast

repo_name: musale/fast


text:
# Podochytrium dentatum Longcore, 1992 SPECIES

#### Status
ACCEPTED

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

#### Published in
Mycologia 84(2): 185 (1992)

#### Original name
Podochytrium dentatum Longcore, 1992

### Remarks
null

repository: mdoering/backbone

repo_name: mdoering/backbone


text:
# Web Foundations - Major Assignment 1 | FANSITE 2017

## Purpose

"This assignment will allow you to experience what it is like to develop a website from scratch.  To do this you will create a fan site of one your favourite subjects; this can be a Movie, TV show, Book, Band, Video Game or anything that you have a great interest in."

Instructions on specific requirements are as follows:
* Main Page: Navigation links ("return to top", link section pictures to individual pages), External link
* 2 additional .html pages: 2 col and 3 col + "Under Construction" page

# Get started

* Visit: https://catherineolej.github.io/star-wars-fansite.github.io/

## How it was built

The development process of this project was done in visual studio code.
The programming languages used for this devlopment are:
* Use well-formed HTML5 and CSS3 structure including use of semantic elements
* Keep in mind AODA considerations when developing your template

## Author

**Catherine Olejarczyk** - initial work


text:
# Project MPP website

This is based on a subset the [template](https://github.com/douglaslab/templates/tree/master/project) we use for projects in the lab. We've omitted experiments, paper, and protocols.

### BEFORE this can be hosted in production, remove the line _site/* from .gitignore

## directory structure

* **code**
* **data**
	* **images**
	* **json**
* **meetings**
* *outline.md*
* **slides**
* **website**

## content description

### code

Source code lives here!

### data

Data lives here. Whenever possible, structure as json (your code should read and write json), or in its original raw format (e.g. tiff).

### meetings

What's happened recently? What's our plan?

### *outline.md*

This is bullet-point outline of the project. It can be considered a rough outline of the paper, but of course things can change before things get to the manuscript-writing phase, so this document should be the primary home of all the project ideas and questions until it's clear that it's time to write the paper.

### slides

Summary slides of the project that could be used for introducting the project, teaching, etc.

### website

Every project should ultimately be able to serve its own website. The site (e.g. jekyll, etc) should live here.

If you're working on a blog post and it isnt finished you can name it 'something-title.md'; and commit it to the repository. When it's ready you can 'pubish' it by prepending the date to the name. Alternatively you can add:
    published: true
to that file's yaml frontmatter.

## Template Particulars.

### SCSS and CSS

The /assets/css/main.scss is really the important file here. It just imports a list of .scss files - jekyll knows where those are located (/assets/_sass), we tell it in the _config.yml file in the root dir.

Jekyll parses all the files imported in the '/assets/css/main.scss' file, and generates it into one, single, compressed file ucalled /_site/assets/css/main.css.

#### Grid

The grid we use is [Bourbon's Neat](http://neat.bourbon.io/). It's a semantic grid, so we style elements directly, not fill our html up with classes like 'article class="etc"'. The documentation is pretty easy.

The grid is only invoked in two places: assets/_sass/layout.scss and /assets/_sass/grid-settings.scss

We don't mention the grid anywhere else, not in styles or typography or anywhere else.

#### Typography

We use [Typeplate](http://typeplate.com/) to set some basicly proper typographical proportions - not font choices but their behavior, relationship stuff. This is very subtle stuff, and shouldnt be touched. They're loaded in /assets/_sass/typelate-scss/*

repository: douglaslab/mpp

gha_language: CSS

repo_name: douglaslab/mpp


text:
# Overview

WLog is a configurable and flexible logging system used throughout winpr and
FreeRDP.

The primary concept is to have a hierarchy of loggers that can be be configured
independently.

TODO add more details and configuration examples.

# Environment variables

* WLOG_APPENDER  - the appender to use possible values below also see the Appender section.
  * CONSOLE
  * FILE
  * BINARY
  * SYSLOG
  * JOURNALD
  * UDP
* WLOG_PREFIX - configure the prefix used for outputting the message (see
  Format for more details and examples)
* WLOG_LEVEL - the level to output messages for
* WLOG_FILTER - sets a filter for WLog messages. Only the filtered messages are
printed
* WLOG_FILEAPPENDER_OUTPUT_FILE_PATH  - set the output file path for the file
file appender
* WLOG_FILEAPPENDER_OUTPUT_FILE_NAME - set the output file name for the output
appender
* WLOG_JOURNALD_ID - identifier used by the journal appender
* WLOG_UDP_TARGET - target to use for the UDP appender in the format host:port

# Levels

The WLog are complementary the higher level always includes the lower ones.
The level list below is top down. Top the highest level.

* WLOG_TRACE - print everything including package dumps
* WLOG_DEBUG - debug messages
* WLOG_INFO - general informations
* WLOG_WARN - warnings
* WLOG_ERROR - errors
* WLOG_FATAL - fatal problems
* WLOG_OFF - completely disable the wlog output

# Format

The format a logger prints in has the following possible options:

* "lv" - log level
* "mn" - module name
* "fl" - file name
* "fn" - function
* "ln" - line number
* "pid" - process id
* "tid" - thread id
* "yr" - year
* "mo" - month
* "dw" - day of week
* "hr" - hour
* "mi" - minute
* "se" - second
* "ml" - millisecond

A maximum of 16 options can be used per format string.

An example that generally sets the WLOG_PREFIX for xfreerdp would look like:
```
WLOG_PREFIX="pid=%pid:tid=%tid:fn=%fn -" xfreerdp /v:xxx
```

# Appenders

WLog uses different appenders that define where the log output should be written
to. If the application doesn't explicitly configure the appenders the above
described variable WLOG_APPENDER can be used to choose one appender.

The following represents an overview about all appenders and their possible
configuration values.

### Binary

Write the log data into a binary format file.

Options:
* "outputfilename", value const char* - file to write the data to
* "outputfilepath", value const char* - location of the output file

### Callback
The callback appender can be used from an application to get all log messages
back the application. For example if an application wants to handle the log
output itself.

Options:

* "callbacks", value struct wLogCallbacks*, callbacks to use

### Console

The console appender writes to the console. Depending of the operating system
the application runs on the output might be handled differently. For example
on android log print would be used.

Options:

* "outputstream", value const char * - output stream to write to
  * "stdout" - write everything to stdout
  * "stderr" - write everything to stderr
  * "default" - use the default settings - in this case errors and fatal would
  go to stderr everything else to stdout
  * debug - use the debug output. Only used on windows on all operating systems
  this behaves as as if default was set.

### File
The file appender writes the textual output to a file.

Options:

* "outputfilename", value const char*, filename to use
* "outputfilepath", value const char*, location of the file

### Udp

This appender sends the logging messages to a pre-defined remote host via UDP.

Options:

* "target", value const char*, target to send the data too in the format
host:port

If no target is set the default one <IP_ADDRESS>:20000 is used. To receive the
log messages one can use netcat. To receive the default target the following
command could be used.
```
nc -u <IP_ADDRESS> -p 20000 -l
```

### Syslog (optional)

Use syslog for outputting the debug messages. No options available.

### Journald (optional)

For outputting the log messages to journald this appender can be used.
The available options are:

* "identifier", value const char*, the identifier to use for journald (default
  is winpr)

repository: awakecoding/FreeRDP

gha_language: C

repo_name: awakecoding/FreeRDP


text:
# Hack12athon-First-Five
Platform to create a classroom culture with virtual engagement ideas. We provide a simple site for teachers and students to add and pick random activities! It helps teachers and students empathize using the first five minutes of class.

Here is how it works:

![The First Five Prototype](https://user-images.githubusercontent.com/64348681/80864626-0ab42e00-8cae-11ea-940f-916d646da616.png)

Feel free to reach out if you are interested in making this idea real with some web-based prototypes!

Made during Stanford d.school Hack12athon in 2020.


text:
---
layout: default
markdown: 1
social_text: "Let's Scaffold A Web App With @Yeoman!"
social_url: http://yeoman.io/codelab.html
sidebar: sidebars/codelab.html
---

# Step 6: Start writing our AngularJS application

The files that you see in the web browser can be found in the ***app*** subfolder of your ***mytodo*** directory. All the instructions in this section assume that you are editing files in this *app* folder.  If you are unsure about any of the changes you should be doing, refer to the final source code.

## Create a new template to show a todo list

Open ***views/main.html***.

To start from a cleaner slate, delete everything from your *main.html* file except for the `div` with a class of `"jumbotron"`. Replace `"jumbotron"` with the class name `"container"`.

This is all you should have in *main.html* now:

```html
<div class="container">
</div>
```

Open ***scripts/controllers/main.js***.

Modify this boilerplate Angular Controller to contain a list of `todos` instead of `awesomeThings`:

```js
'use strict';

angular.module('mytodoApp')
  .controller('MainCtrl', function ($scope) {
    $scope.todos = ['Item 1', 'Item 2', 'Item 3'];
  });

```

Then modify our view (*main.html*) to output our todos items as HTML text `input` fields:

```html
<div class="container">
  <h2>My todos</h2>
  <p class="form-group" ng-repeat="todo in todos">
    <input type="text" ng-model="todo" class="form-control">
  </p>
</div>
```

The [`ng-repeat`](http://docs.angularjs.org/api/ng.directive:ngRepeat) attribute on the paragraph tag is an Angular [directive](http://docs.angularjs.org/guide/directive) that instantiates a template once per item from a collection.

In our case, imagine that the paragraph element and its content is turned into a virtual rubber stamp by adding the `ng-repeat` attribute. For each item in the `todos` array, Angular will stamp out a new instance of the `<p><input></p>` HTML block.

The [`ng-model`](http://docs.angularjs.org/api/ng.directive:ngModel) attribute is another Angular directive that works with `input`, `select`, `textarea`, and custom directives to create a [two-way data binding](http://docs.angularjs.org/guide/databinding). In our example, it populates a text `input` field with the value from the current `todo` item in the `ng-repeat` loop.

Let's see `ng-repeat` and `ng-model` in action within the browser. Upon saving, our application should now look like this:

![](/assets/img/codelab/image_15.png)

Manually update `$scope.todos` with a fourth todo item:

```js
$scope.todos = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];
```

With live reload, you should see the new todo item appear in the list.

Manually remove the fourth item and watch it disappear from the list.

## Add a todo

Let’s implement a way for the user to add new todo items to the list.

Modify *main.html* by adding a `form` element in between the `<h2>` and `<p>` elements from the previous section. Your *main.html* should now look like this:

```html

<div class="container">
  <h2>My todos</h2>

  <!-- Todos input -->
  <form role="form" ng-submit="addTodo()">
    <div class="row">
      <div class="input-group">
        <input type="text" ng-model="todo" placeholder="What needs to be done?" class="form-control">
        <span class="input-group-btn">
          <input type="submit" class="btn btn-primary" value="Add">
        </span>
      </div>
    </div>
  </form>
  <p></p>

  <!-- Todos list -->
  <p class="form-group" ng-repeat="todo in todos">
    <input type="text" ng-model="todo" class="form-control">
  </p>
</div>

```

This adds a HTML form with a submit button to the top of the page. It utilises another Angular directive, [`ng-submit`](http://docs.angularjs.org/api/ng.directive:ngSubmit) which we’ll get to next. Return to your browser and the UI should now look similar to this:

![](/assets/img/codelab/image_16.png)

If you click **Add** currently, nothing will happen — let’s change that.

`ng-submit` binds an Angular expression to the onsubmit event of the form. If no action attribute is applied to the form, it also prevents the default browser behaviour. In our example we’ve added an Angular expression of `addTodo()`.

The following `addTodo()` function pushes new todo items onto the existing todo items array and then clears the text input field:

```js
$scope.addTodo = function () {
  $scope.todos.push($scope.todo);
  $scope.todo = '';
};
```

Edit *main.js* by adding the `addTodo()` function within the `MainCtrl` controller definition. Your complete controller should look like this:

```js
'use strict';

angular.module('mytodoApp')
  .controller('MainCtrl', function ($scope) {
    $scope.todos = ['Item 1', 'Item 2', 'Item 3'];
    $scope.addTodo = function () {
      $scope.todos.push($scope.todo);
      $scope.todo = '';
    };
  });
 ```

Note: If you encounter linting errors in the command line window, this may be due to indentation warnings being thrown from jshint. They are only warnings so your todo app will continue to work. However, do look at the suggestions made from jshint and adjust your code accordingly for clean and readable code.

View the app in the browser again. Type some text in the input field for a new todo item and hit **Add**. It will be immediately reflected in your todos list!

Note: If you enter in more than one blank todo item, or a todo item with the same name, your todo app will unexpectedly stop working. :( As a fun exercise on your own time, enhance the addTodo() function with error checking.

## Remove a todo

Let’s now add the ability to remove a todo item. We’ll need to add a new remove button alongside each todo item.

Going back to our view template (*main.html*), add a button to the existing `ng-repeat` directive. And to make sure our input field and remove button line up nicely, change the class on the paragraph tag from `"form-group"` to `"input-group"`.

Previous markup:

```html
<!-- Todos list -->
<p class="form-group" ng-repeat="todo in todos">
  <input type="text" ng-model="todo" class="form-control">
</p>
```

New markup:

```html
<!-- Todos list -->
<p class="input-group" ng-repeat="todo in todos">
  <input type="text" ng-model="todo" class="form-control">
  <span class="input-group-btn">
    <button class="btn btn-danger" ng-click="removeTodo($index)" aria-label="Remove">X</button>
  </span>
</p>
```

Have a look at your browser. Your todo app is looking snazzy!

![](/assets/img/codelab/image_19.png)

We introduced a new Angular directive above, [`ng-click`](http://docs.angularjs.org/api/ng.directive:ngClick). `ng-click` allows you to specify custom behaviours when an element is clicked. In this instance, we call `removeTodo()` and pass `$index` to the function.

The value of `$index` will be the array index of the current `todo` item within the `ng-repeat` directive. For example, the first item will have an array index of 0 and `removeTodo()` will be passed the value of 0. Similarly, the last item of a todo list with 5 items will have an array index of 4 and `removeTodo()` will be passed a value of 4.

Let’s now add some logic for removing todo items to our controller. The following `removeTodo()` function removes one todo item from the items array using the JavaScript `splice()` method at the given `$index` value:

```js
$scope.removeTodo = function (index) {
  $scope.todos.splice(index, 1);
};
```

The complete controller (*main.js*) with the new `removeTodo()` function is below:

```js
'use strict';

angular.module('mytodoApp')
  .controller('MainCtrl', function ($scope) {
    $scope.todos = ['Item 1', 'Item 2', 'Item 3'];
    $scope.addTodo = function () {
      $scope.todos.push($scope.todo);
      $scope.todo = '';
    };
    $scope.removeTodo = function (index) {
      $scope.todos.splice(index, 1);
    };
  });
```

Back in the browser, you can now hit the **X** button to remove the item from the todo list. Fantastic!

One thing you might notice is that we don’t have a way to persist our todo list. Any time we refresh the page our todo items are reset back to the defaults in our `todos` array hardcoded in *main.js*. Don’t worry, we’ll fix this in [Step 9](local-storage.html) after we learn more about installing packages with Bower next in [Step 7](install-packages.html).

  « Return to overview
  or
  Go to the next step »


text:
---
title: Javascript SDK
permalink: /docs/javascript-sdk/
---

## Install
------

#### npm

```bash
npm install oopsie-sdk
```

#### CDN

```html
<script src="https://cdnjs.cloudflare.com/oopsie/libs/oopsie-sdk/0.99.0/js/oopsie.min.js"></script>
```

## Usage

#### Initialization and basics

```js
var oopsie = new OopsieSite(prodApiUrl, siteId, customerId);
oopsie.init(err => {
    // We have initialized oopsie sdk...
});
```

After the initialization you can start to Create, Get, Delete and Update your entities. You can also Register, Login, Logout and Refresh Users.
The SDK works in the same way as you model and Deploy your Site. You will initialize the SDK for a specific Site to get the Application you want to work with and choose a Resource on it. The Resource object is where you will make all your queries to retrieve and create entities for the specified Resource.

```js
// First you need to get one of your Applications that you have deployed to your site.
var app = oopsie.getApp('MyApp');

// On this object you can then retrieve the different Resources you have.
// It is this object that you use to create, get, update and delete entities on your Resource.
var myResource = app.getResource('MyResource');
```

#### Get

```js
myResource.get().execute((err, res) => {
    if (err) {
        alert('We got an error when getting entities');
        return;
    }

    // Else we have our result
}));

let params = {
    eid: 'f89028c3-7d02-4ce8-8bd4-1d88b51aa461'
};
myResource.get().withParams(params).execute(cb);
myResource.get().byView('MyView').execute(cb);
myResource.get().limit(100).execute(cb);
myResource.get().expandRelations().execute(cb);

// You can also add all of the methods after get() in different order and use the ones you need.
myResource.get().withParams(params).byView('MyView').limit(100).expandRelations().execute(cb);

// You can also store the query to later get nextPage or previous page, if they exists.
var query = myResource.get().byView('MyView').execute(cb);
if (query.hasNextPage()) {
    query.nextPage(cb);
}

if(query.hasPrevPage()) {
    query.prevPage(cb);
}
```

#### Create

```js
let params = {
    name: 'Smith',
    age: 22
};
myResource.create().execute(cb);
myResource.create().withParams(params).execute(cb);
```

#### Update

```js
let params = {
    name: 'Smith',
    age: 22,
    // Save will need to have eid and all Partition Keys and Clustering Keys.
    eid: 'f89028c3-7d02-4ce8-8bd4-1d88b51aa461'
};
myResource.save().execute(cb);
myResource.save().withParams(params).execute(cb);
```

#### Delete

```js
let params = {
    name: 'Smith',
    age: 22
};
myResource.delete().execute(cb);
myResource.delete().withParams(params).execute(cb);
```

## Users

The Javascript SDK can also help you manage Users for your site.

#### Login

```js
var user = {
    email<EMAIL_ADDRESS>    password: 'my-super-secret'
};
oopsie.login(user, (err) => {
    if (err) {
        // We are not logged in!
        return;
    }
    // We are logged in!
});
```

#### Register

```js
var user = {
    email<EMAIL_ADDRESS>
    password: 'my-super-secret',
    auths:['User'],
    firstname: 'Andreas',
    lastname: 'Andersson'
};

oopsie.register(user, (err) => {
    if (err) {
        // We are not logged in!
        return;
    }

    // We are logged in!
});
```

#### Logout

```js
oopsie.logout((err) => {
    if (err) {
        // We are not logged out!
        return;
    }
    // We logged out!
});
```

#### Refresh

```js
oopsie.refresh((err) => {
    if (err) {
        // We didnt manage to refresh the users session.
        return;
    }
    // We refreshed the session for your user.
});
```

#### Me

```js
oopsie.me((err, me) => {
    if (err) {
        // Something went wrong!
        return;
    }
    // We can inspect the logged in user, email etc.
});
```

repository: wreyesus/oopsie-docs

repo_name: wreyesus/oopsie-docs


text:
# Vim Pipe - A Productivity-Boosting Plugin

## Do you do this?

```
        hack <---------- alt-tab <---------- react
          |                                    |
+-------------------+                +-------------------+
| code code         |                | result result     |
| code              |                | result            |
|                   |                |                   |
|                   |                |                   |
|                   |                |                   |
|                   |                |                   |
|                   |                |                   |
+-------------------+                +-------------------+
          |                                    |
         :w -----------> alt-tab ---------> invoke
```

This plugin lets you do this instead:

```
+-------------------+
| code code         |
| code              |---------\
|                   |         |
|-------------------|   <LocalLeader>r
| result result     |         |
| result            |<--------/
|                   |
+-------------------+
```

Which saves tonnes of time. It's even faster than using screen or tmux.

It's useful for developing SQL queries, fast HTML previews, markdown-checking,
and anything that needs to pass through a shell command while you develop.

## Detail

You associate a shell command with your file, something that will take your
buffer on STDIN and show the result on STDOUT. For example, if you're editing an
SQL query, that command might be `psql mydatabase`.

Having done that, `<LocalLeader>r` will run the current buffer against that
command and show you the results. You no longer need to
save-switch-execute-switch, which makes life faster and easier.

## Installation

* Install [Pathogen][pathogen]. (You're already using Pathogen, right?)
* Clone this project into `~/.vim/bundle/vim-pipe`.
* Set a `b:vimpipe_command` variable for your buffer. The easiest way is to add
a `let` command in `~/.vim/ftplugin/<filetype>.vim`. For example:

```vim
" In ~/.vim/ftplugin/sql.vim
let b:vimpipe_command="psql mydatabase"
" In ~/.vim/ftplugin/markdown.vim
let b:vimpipe_command="multimarkdown"
```

See below for various examples.

## Usage & Tips

Once `b:vimpipe_command` is configured, type `<LocalLeader>r` to get the list
results.  There's no need to save the file first. It works on the current
buffer, not the contents on disk.

You can set `g:vimpipe_silent=1` to disable runtime information in the output
window.

### PostgreSQL
```vim
" In ~/.vim/ftplugin/sql.vim
let b:vimpipe_command="psql mydatabase"
```

See also [vim-postgresql-syntax][vim-postgresql-syntax].

### Oracle

If you have an OPS$ login, it's as simple as:
```vim
" In ~/.vim/ftplugin/sql.vim
let b:vimpipe_command="sqlplus -s /"
```

### HTML

This is only text-based, obviously, but can still speed up initial development.

```vim
" In ~/.vim/ftplugin/html.vim
let b:vimpipe_command="lynx -dump -stdin"
```

### JavaScript

I usually run JavaScript in a browser, so I bind vim-pipe to JSLint, for
code-quality checking on-the-fly.

```vim
" In ~/.vim/ftplugin/javascript.vim
let b:vimpipe_command='jslint <(cat)'
```

Note: JSLint doesn't accept input on STDIN, so this configuration uses bash's
virtual file support. `<(cat)` takes the STDIN and re-presents it to look like a
regular file.

### JSON

I find attaching vim-pipe to a pretty-printer useful for development:

```vim
" Vim doesn't set a FileType for JSON, so we'll do it manually:
" In ~/.vimrc
autocmd BufNewFile,BufReadPost *.json setlocal filetype=javascript.json

" In ~/.vim/ftplugin/javascript.vim
" Requires that you have Python v2.6+ installed. (Most *nix systems do.)
let b:vimpipe_command="python -m json.tool"
```

### Markdown

Fast-preview the HTML:

```vim
" In ~/.vim/ftplugin/markdown.vim
let b:vimpipe_command="multimarkdown"
let b:vimpipe_filetype="html"
```

Or combine wth the HTML tip to preview the rendered result:

```vim
" In ~/.vim/ftplugin/markdown.vim
let b:vimpipe_command="multimarkdown | lynx -dump -stdin"
```

### MongoDB

Is there an official FileType for MongoDB query files? Let's say it's `mongoql`, for all files `*.mql`:

```vim
" In ~/.vimrc
autocmd BufNewFile,BufReadPost *.mql setlocal filetype=mongoql

" In ~/.vim/ftplugin/mql.vim
let b:vimpipe_command="mongo"
let b:vimpipe_filetype="javascript"
```

Then try editing a file called `somequery.mql` with something like this in:

```javascript
use books;
db.book.find(null, {author: 1, title: 1 });
db.runCommand({dbStats: 1});
```

## Help

See `:help vim-pipe` for more.

## FAQ

### What's the difference between this and `:make`?

The biggest difference is the way the output is presented & read. If the whole of the
output is interesting, use Vim Pipe. If the only interesting part of the output
is a summary of errors/warnings, use `:make`.

### Does Vim Pipe fork/exec?

_..or is there a long-lived background process?_

It forks. So it works well with commands you'd invoke frequently from the
command line, but not so well with something like `javac`, which has a (deathly)
slow startup time.

## Credits

Thanks to Steve Losh for his excellent guide to Vimscript, [Learn Vimscript the Hard Way][learnvim], and Meikel Brandmeye of [vimclojure][vimclojure] for the inspiration.

Thanks to [Markus Seeger][codegourmet] and [Dhruva Sagar][dhruvasagar] for their
contributions.

[pathogen]: https://github.com/tpope/vim-pathogen/
[learnvim]: http://learnvimscriptthehardway.stevelosh.com/
[vimclojure]: https://github.com/kotarak/vimclojure
[vim-postgresql-syntax]: https://github.com/krisajenkins/vim-postgresql-syntax
[codegourmet]: https://github.com/codegourmet
[dhruvasagar]: https://github.com/dhruvasagar

repository: krisajenkins/vim-pipe

gha_language: VimL

repo_name: krisajenkins/vim-pipe


text:
# Shipped - Create Application and Service

## Access CLI

1. Open a command window.

1. Enter shipped **help -t xxx**, where xxx is the token you copied earlier.

    Shipped displays an overview help information.

## Create an Application
Shipped groups services into applications. You create an application with the project create command, and provide a name and optional description for the application.

Example:

    shipped project create name=testProject description="A Demo Application"

Shipped echoes the project name and description.

    Changed to new project directory c:\shipped\Demo
    Application  Description
    -------      -----------
    testProject	 A Demo Application

## Create a Service

A service is an independently deployable component of a project. Most services are based on a buildpack that includes starter code for the service. You can list buildpacks with the command:

1. Issue the buildpack getall command to see a list of available buildpacks.

    Example:

        shipped buildpack getall

    Shipped shows the available buildpacks.

    ![](posts/files/shipped-cli-labs/assets/buildpack-getall.png)

1. Issue the service create command, and provide the name of the project, the name of the buildpack to use, and the name for the new service.

    Example:

        shipped service create testProject golang name=testservice
    Respond:

       ![](posts/files/shipped-cli-labs/assets/service-create.png)

repository: CiscoCloud/Shipped-Learning-Labs

gha_language: HTML

repo_name: CiscoCloud/Shipped-Learning-Labs


text:
---
layout: post
title: "[Design Pattern] Template Method"
description: "Template Method is a behavioral design pattern that defines the skeleton of an algorithm in the superclass but lets subclasses override specific steps of the algorithm without changing its structure."
date: 2020-02-06 14:09
tags: [디자인패턴]
comments: true
share: true
---

/  [Design Patterns](https://algamza.github.io/2020-02-06/Design-Patterns)  /  [Behavioral Patterns](https://algamza.github.io/2020-02-06/Behavioral-Design-Patterns)

## Intent

**Template Method**  is a behavioral design pattern that defines the skeleton of an algorithm in the superclass but lets subclasses override specific steps of the algorithm without changing its structure.

![Template method design pattern](https://refactoring.guru/images/patterns/content/template-method/template-method.png)

## Problem

Imagine that you’re creating a data mining application that analyzes corporate documents. Users feed the app documents in various formats (PDF, DOC, CSV), and it tries to extract meaningful data from these docs in a uniform format.

The first version of the app could work only with DOC files. In the following version, it was able to support CSV files. A month later, you “taught” it to extract data from PDF files.

![Data mining classes contained a lot of duplicate code](https://refactoring.guru/images/patterns/diagrams/template-method/problem.png)

Data mining classes contained a lot of duplicate code.

At some point, you noticed that all three classes have a lot of similar code. While the code for dealing with various data formats was entirely different in all classes, the code for data processing and analysis is almost identical. Wouldn’t it be great to get rid of the code duplication, leaving the algorithm structure intact?

There was another problem related to client code that used these classes. It had lots of conditionals that picked a proper course of action depending on the class of the processing object. If all three processing classes had a common interface or a base class, you’d be able to eliminate the conditionals in client code and use polymorphism when calling methods on a processing object.

## Solution

The Template Method pattern suggests that you break down an algorithm into a series of steps, turn these steps into methods, and put a series of calls to these methods inside a single “template method.” The steps may either be  `abstract`, or have some default implementation. To use the algorithm, the client is supposed to provide its own subclass, implement all abstract steps, and override some of the optional ones if needed (but not the template method itself).

Let’s see how this will play out in our data mining app. We can create a base class for all three parsing algorithms. This class defines a template method consisting of a series of calls to various document-processing steps.

![Template method defines the skeleton of the algorithm](https://refactoring.guru/images/patterns/diagrams/template-method/solution-en.png)

Template method breaks the algorithm into steps, allowing subclasses to override these steps but not the actual method.

At first, we can declare all steps  `abstract`, forcing the subclasses to provide their own implementations for these methods. In our case, subclasses already have all necessary implementations, so the only thing we might need to do is adjust signatures of the methods to match the methods of the superclass.

Now, let’s see what we can do to get rid of the duplicate code. It looks like the code for opening/closing files and extracting/parsing data is different for various data formats, so there’s no point in touching those methods. However, implementation of other steps, such as analyzing the raw data and composing reports, is very similar, so it can be pulled up into the base class, where subclasses can share that code.

As you can see, we’ve got two types of steps:

-   _abstract steps_  must be implemented by every subclass
-   _optional steps_  already have some default implementation, but still can be overridden if needed

There’s another type of step, called  _hooks_. A hook is an optional step with an empty body. A template method would work even if a hook isn’t overridden. Usually, hooks are placed before and after crucial steps of algorithms, providing subclasses with additional extension points for an algorithm.

## Real-World Analogy

![Mass housing construction](https://refactoring.guru/images/patterns/diagrams/template-method/live-example.png)

A typical architectural plan can be slightly altered to better fit the client’s needs.

The template method approach can be used in mass housing construction. The architectural plan for building a standard house may contain several extension points that would let a potential owner adjust some details of the resulting house.

Each building step, such as laying the foundation, framing, building walls, installing plumbing and wiring for water and electricity, etc., can be slightly changed to make the resulting house a little bit different from others.

## Structure

![Structure of the Template Method design pattern](https://refactoring.guru/images/patterns/diagrams/template-method/structure.png)

1.  The  **Abstract Class**  declares methods that act as steps of an algorithm, as well as the actual template method which calls these methods in a specific order. The steps may either be declared  `abstract`  or have some default implementation.

2.  **Concrete Classes**  can override all of the steps, but not the template method itself.

## Pseudocode

In this example, the  **Template Method**  pattern provides a “skeleton” for various branches of artificial intelligence in a simple strategy video game.

![Structure of the Template Method pattern example](https://refactoring.guru/images/patterns/diagrams/template-method/example.png)

AI classes of a simple video game.

All races in the game have almost the same types of units and buildings. Therefore you can reuse the same AI structure for various races, while being able to override some of the details. With this approach, you can override the orcs’ AI to make it more aggressive, make humans more defense-oriented, and make monsters unable to build anything. Adding a new race to the game would require creating a new AI subclass and overriding the default methods declared in the base AI class.

```java
// The abstract class defines a template method that contains a
// skeleton of some algorithm composed of calls, usually to
// abstract primitive operations. Concrete subclasses implement
// these operations, but leave the template method itself
// intact.
class GameAI is
    // The template method defines the skeleton of an algorithm.
    method turn() is
        collectResources()
        buildStructures()
        buildUnits()
        attack()

    // Some of the steps may be implemented right in a base
    // class.
    method collectResources() is
        foreach (s in this.builtStructures) do
            s.collect()

    // And some of them may be defined as abstract.
    abstract method buildStructures()
    abstract method buildUnits()

    // A class can have several template methods.
    method attack() is
        enemy = closestEnemy()
        if (enemy == null)
            sendScouts(map.center)
        else
            sendWarriors(enemy.position)

    abstract method sendScouts(position)
    abstract method sendWarriors(position)

// Concrete classes have to implement all abstract operations of
// the base class but they must not override the template method
// itself.
class OrcsAI extends GameAI is
    method buildStructures() is
        if (there are some resources) then
            // Build farms, then barracks, then stronghold.

    method buildUnits() is
        if (there are plenty of resources) then
            if (there are no scouts)
                // Build peon, add it to scouts group.
            else
                // Build grunt, add it to warriors group.

    // ...

    method sendScouts(position) is
        if (scouts.length > 0) then
            // Send scouts to position.

    method sendWarriors(position) is
        if (warriors.length > 5) then
            // Send warriors to position.

// Subclasses can also override some operations with a default
// implementation.
class MonstersAI extends GameAI is
    method collectResources() is
        // Monsters don't collect resources.

    method buildStructures() is
        // Monsters don't build structures.

    method buildUnits() is
        // Monsters don't build units.
```

## Applicability

Use the Template Method pattern when you want to let clients extend only particular steps of an algorithm, but not the whole algorithm or its structure.

The Template Method lets you turn a monolithic algorithm into a series of individual steps which can be easily extended by subclasses while keeping intact the structure defined in a superclass.

Use the pattern when you have several classes that contain almost identical algorithms with some minor differences. As a result, you might need to modify all classes when the algorithm changes.

When you turn such an algorithm into a template method, you can also pull up the steps with similar implementations into a superclass, eliminating code duplication. Code that varies between subclasses can remain in subclasses.

## How to Implement

1.  Analyze the target algorithm to see whether you can break it into steps. Consider which steps are common to all subclasses and which ones will always be unique.

2.  Create the abstract base class and declare the template method and a set of abstract methods representing the algorithm’s steps. Outline the algorithm’s structure in the template method by executing corresponding steps. Consider making the template method  `final`  to prevent subclasses from overriding it.

3.  It’s okay if all the steps end up being abstract. However, some steps might benefit from having a default implementation. Subclasses don’t have to implement those methods.

4.  Think of adding hooks between the crucial steps of the algorithm.

5.  For each variation of the algorithm, create a new concrete subclass. It  _must_  implement all of the abstract steps, but  _may_  also override some of the optional ones.

## Pros and Cons

-   You can let clients override only certain parts of a large algorithm, making them less affected by changes that happen to other parts of the algorithm.
-   You can pull the duplicate code into a superclass.

-   Some clients may be limited by the provided skeleton of an algorithm.
-   You might violate the  _Liskov Substitution Principle_  by suppressing a default step implementation via a subclass.
-   Template methods tend to be harder to maintain the more steps they have.

## Relations with Other Patterns

-   [Factory Method](https://algamza.github.io/2020-02-06/Factory-Method-Design-Pattern)  is a specialization of  [Template Method](https://algamza.github.io/2020-02-06/Template-Method-Design-Pattern). At the same time, a  _Factory Method_  may serve as a step in a large  _Template Method_.

-   [Template Method](https://algamza.github.io/2020-02-06/Template-Method-Design-Pattern)  is based on inheritance: it lets you alter parts of an algorithm by extending those parts in subclasses.  [Strategy](https://algamza.github.io/2020-02-06/Stategy-Design-Pattern)  is based on composition: you can alter parts of the object’s behavior by supplying it with different strategies that correspond to that behavior.  _Template Method_  works at the class level, so it’s static.  _Strategy_  works on the object level, letting you switch behaviors at runtime.

## Code Example
**Template Method**  is a behavioral design pattern that allows you to defines a skeleton of an algorithm in a base class and let subclasses override the steps without changing the overall algorithm’s structure.

[Learn more about Template Method](https://algamza.github.io/2020-02-06/Template-Method-Design-Pattern)

## Usage of the pattern in Java

**Complexity:**

**Popularity:**

**Usage examples:**  The Template Method pattern is quite common in Java frameworks. Developers often use it to provide framework users with a simple means of extending standard functionality using inheritance.

Here are some examples of Template Methods in core Java libraries:

-   All non-abstract methods of  [`java.io.InputStream`](http://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html),  [`java.io.OutputStream`](http://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html),  [`java.io.Reader`](http://docs.oracle.com/javase/8/docs/api/java/io/Reader.html)  and  [`java.io.Writer`](http://docs.oracle.com/javase/8/docs/api/java/io/Writer.html).

-   All non-abstract methods of  [`java.util.AbstractList`](http://docs.oracle.com/javase/8/docs/api/java/util/AbstractList.html),  [`java.util.AbstractSet`](http://docs.oracle.com/javase/8/docs/api/java/util/AbstractSet.html)  and  [`java.util.AbstractMap`](http://docs.oracle.com/javase/8/docs/api/java/util/AbstractMap.html).

-   [`javax.servlet.http.HttpServlet`](http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServlet.html), all the  `doXXX()`  methods by default send a HTTP 405 “Method Not Allowed” error as a response. You’re free to override any of them.

**Identification:**  Template Method can be recognized by behavioral methods that already have a “default” behavior defined by the base class.

## Overriding standard steps of an algorithm

In this example, the Template Method pattern defines an algorithm of working with a social network. Subclasses that match a particular social network, implement these steps according to the API provided by the social network.

## [](https://algamza.github.io/2020-02-06/Template-Method-Design-Pattern/java/example#example-0--networks)**networks**

#### [](https://algamza.github.io/2020-02-06/Template-Method-Design-Pattern/java/example#example-0--networks-Network-java)**networks/Network.java:**  Base social network class
```java
package algamza.template_method.example.networks;

/**
 * Base class of social network.
 */
public abstract class Network {
    String userName;
    String password;

    Network() {}

    /**
     * Publish the data to whatever network.
     */
    public boolean post(String message) {
        // Authenticate before posting. Every network uses a different
        // authentication method.
        if (logIn(this.userName, this.password)) {
            // Send the post data.
            boolean result =  sendData(message.getBytes());
            logOut();
            return result;
        }
        return false;
    }

    abstract boolean logIn(String userName, String password);
    abstract boolean sendData(byte[] data);
    abstract void logOut();
}
```
#### [](https://algamza.github.io/2020-02-06/Template-Method-Design-Pattern/java/example#example-0--networks-Facebook-java)**networks/Facebook.java:**  Concrete social network
```java
package algamza.template_method.example.networks;

/**
 * Class of social network
 */
public class Facebook extends Network {
    public Facebook(String userName, String password) {
        this.userName = userName;
        this.password = password;
    }

    public boolean logIn(String userName, String password) {
        System.out.println("\nChecking user's parameters");
        System.out.println("Name: " + this.userName);
        System.out.print("Password: ");
        for (int i = 0; i < this.password.length(); i++) {
            System.out.print("*");
        }
        simulateNetworkLatency();
        System.out.println("\n\nLogIn success on Facebook");
        return true;
    }

    public boolean sendData(byte[] data) {
        boolean messagePosted = true;
        if (messagePosted) {
            System.out.println("Message: '" + new String(data) + "' was posted on Facebook");
            return true;
        } else {
            return false;
        }
    }

    public void logOut() {
        System.out.println("User: '" + userName + "' was logged out from Facebook");
    }

    private void simulateNetworkLatency() {
        try {
            int i = 0;
            System.out.println();
            while (i < 10) {
                System.out.print(".");
                Thread.sleep(500);
                i++;
            }
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}
```
#### [](https://algamza.github.io/2020-02-06/Template-Method-Design-Pattern/java/example#example-0--networks-Twitter-java)**networks/Twitter.java:**  One more social network
```java
package algamza.template_method.example.networks;

/**
 * Class of social network
 */
public class Twitter extends Network {

    public Twitter(String userName, String password) {
        this.userName = userName;
        this.password = password;
    }

    public boolean logIn(String userName, String password) {
        System.out.println("\nChecking user's parameters");
        System.out.println("Name: " + this.userName);
        System.out.print("Password: ");
        for (int i = 0; i < this.password.length(); i++) {
            System.out.print("*");
        }
        simulateNetworkLatency();
        System.out.println("\n\nLogIn success on Twitter");
        return true;
    }

    public boolean sendData(byte[] data) {
        boolean messagePosted = true;
        if (messagePosted) {
            System.out.println("Message: '" + new String(data) + "' was posted on Twitter");
            return true;
        } else {
            return false;
        }
    }

    public void logOut() {
        System.out.println("User: '" + userName + "' was logged out from Twitter");
    }

    private void simulateNetworkLatency() {
        try {
            int i = 0;
            System.out.println();
            while (i < 10) {
                System.out.print(".");
                Thread.sleep(500);
                i++;
            }
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}
```
#### [](https://algamza.github.io/2020-02-06/Template-Method-Design-Pattern/java/example#example-0--Demo-java)**Demo.java:**  Client code
```java
package algamza.template_method.example;

import algamza.template_method.example.networks.Facebook;
import algamza.template_method.example.networks.Network;
import algamza.template_method.example.networks.Twitter;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * Demo class. Everything comes together here.
 */
public class Demo {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        Network network = null;
        System.out.print("Input user name: ");
        String userName = reader.readLine();
        System.out.print("Input password: ");
        String password = reader.readLine();

        // Enter the message.
        System.out.print("Input message: ");
        String message = reader.readLine();

        System.out.println("\nChoose social network for posting message.\n" +
                "1 - Facebook\n" +
                "2 - Twitter");
        int choice = Integer.parseInt(reader.readLine());

        // Create proper network object and send the message.
        if (choice == 1) {
            network = new Facebook(userName, password);
        } else if (choice == 2) {
            network = new Twitter(userName, password);
        }
        network.post(message);
    }
}
```
#### [](https://algamza.github.io/2020-02-06/Template-Method-Design-Pattern/java/example#example-0--OutputDemo-txt)**OutputDemo.txt:**  Execution result
```java
Input user name: Jhonatan
Input password: qswe
Input message: Hello, World!

Choose social network for posting message.
1 - Facebook
2 - Twitter
2

Checking user's parameters
Name: Jhonatan
Password: ****
..........

LogIn success on Twitter
Message: 'Hello, World!' was posted on Twitter
User: 'Jhonatan' was logged out from Twitter
```

path: /_posts/2020/design-pattern/Behavioral-patterns/2020-02-06-Template Method Design Pattern.md