text:
# Testing Strategy
>
> Work In Progress !!! Infrastructure Level tests are not documented yet.
>

TalkAdvisor is following the [microservice testing philosophy](https://martinfowler.com/articles/microservice-testing/#conclusion-summary).
We will try here to explain how to get a cleaner test strategy in a microservice implemented according to the Hexagonal Architecture.

![Testing Strategy](images/testing-strategy.png)

## Functional Tests

### The anti-pattern

Working with Domain-Driven Design and the Hexagonal Architecture, usually means applying the Behavior-Driven Development methodology.
Many people have understood it and this technique is now widely spread. Unfortunately, we often see that the functional tests used to describe the behavior of modern application, are implemented as a http client hitting the endpoints of the controllers.
The main drawback of this (anti-)pattern is the mix of the testing concerns. With this kind of test, we have something that has the responsibility to verify:
 * the business logic of the application *(functional tests)*
 * the contract of the external API *(contract tests)*
 * the workflow offered to the consumer - or something which looks like to it *(end to end tests)*
 * sometimes the mapping between the domain objects and the adapters *(unit tests / integration tests)*
 * the integration of the different sub-components of the application such as the Controllers, the DomainServices, the Repositories... *(integration tests / component tests)*
 * and most of the time without knowing it: the living documentation *(contract testing)*

A simple serialization problem will fail this kind of test, and as a developer we will have to figure out if a regression has been made in the business logic or if something goes wrong with the configuration of a framework.

The sustainability is not the only victim of this technique. Which framework to use when having a test which has that many responsibilities? [Cucumber](https://docs.cucumber.io/) might be one of the best choice to express the rules and the acceptance criteria of the business.
But testing the contract of a web API with it, can be really cu-cumbersome and the developer efficiency might be left behind.

### The Best practices

Back to the basics, since the aim of a functional test is "testing the business logic", putting it inside the domain of our application looks like a good idea. As a result instead of calling the endpoints, those tests are plugged in top of the API of the domain (not the Web API one).

![Functional Tests in the Hexagonal Architecture](images/hexagon-stubbed.png)

In TalkAdvisor, [Cucumber](https://docs.cucumber.io/) is used to define the features and the scenarios of our business logic. As you can see the feature files are located in [the tests packages of the domain](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/tree/master/talkadvisor-domain/src/test/resources/features) beside the [step definitions](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/tree/master/talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/stepdefs).
Using the [Gherkin language](https://docs.cucumber.io/gherkin/reference/), we express the scenarios of a feature [creating-a-profile.feature](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/test/resources/features/creating-a-profile.feature):
```gherkin
Feature: As a frequent user,
  In order not repeat my preferences at each request,
  I want to create my profile with my preferences

  Scenario: The user is creating his profile with his preferences

    Given a user
    And he wants to learn
      | DDD | hexagonal architecture |
    And he only wants to see
      | QUICKIE | CONFERENCE |
    When he creates his profile
    Then his preferences are stored within
```

Let's remind some best practices here:
 * the scenario must be functional and [not technical](https://docs.cucumber.io/bdd/better-gherkin/)
 * the persona must be defined ``As a frequent user`` because a feature performed by different persona is really likely to have distinct acceptance criteria. Think about what differences you can have when an admin or an user are using the same feature
 * Only **ONE** When, you should test one thing at a time, what's about the acceptance criteria with several whens ?
 * Don't use conjunctions in your Givens and Thens, it makes them really hard to reuse, prefer to split your step into several ones

The step definitions are the fixtures of your test, they implement all the Gherkin's directives of your features [ProfileStepdefs.kt](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/stepdefs/ProfileStepdefs.kt):
```kotlin
import org.craftsrecords.talkadvisor.recommendation.api.CreateProfile
import org.craftsrecords.talkadvisor.recommendation.spi.Profiles

class ProfileStepdefs(private val testContext: TestContext,
                      private val createProfile: CreateProfile,
                      private val profiles: Profiles) {

    @Given("^he already has a profile$")
    fun `he already has a profile`() {
        val profile = Profile(testContext.userId, createPreferences())
        profiles.save(profile)
    }

    @When("^he creates his profile$")
    fun `he creates his profile`() {
        val preferences = preferencesFromContext()

        val profile = createProfile.forUserWithPreferences(testContext.userId, preferences)

        testContext.requestedPreferences = preferences
        testContext.createdProfile = profile
    }

    @Then("^his preferences are stored within$")
    fun `his preferences are stored within`() {
        val profile = testContext.createdProfile
        val frequentUser = testContext.userId
        val hisPreferences = testContext.requestedPreferences

        profile.that `corresponds to user` frequentUser
        profile.that `has preferences` hisPreferences
    }
}
```
> You may have noticed some strange assertions here: ```profile.that `corresponds to user` frequentUser```, which framework is that? Let's discover it in that [section](#custom-assertions).

Like said above, instead of hitting the web endpoints of the application, we are using directly here the domain API, through [CreateProfile](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/api/CreateProfile.kt) - a domain service.
So basically all the Whens of our step definitions will call the methods of the domain services exposed through the API = **the features**. In the Givens and the Thens, we respectively creates and asserts on the domain objects. And if needed we can bootstrap or assert some data through the SPI.
You can see this in the example above, in a scenario [not shown here](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/d58d0dee5b92eac15765d6f0f1bd467040dae915/talkadvisor-domain/src/test/resources/features/profiles.feature#L17), the fact that the user already has a profile is a prerequisite.
So a profile is bootstrapped for this user directly stored in the "database" using the [Profile repository](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/spi/Profiles.kt) in the SPI.
You can also use the same technique when using a side effect feature to perform some assertions in a Then.

Most of the time, users split their step definitions in the same way as their scenarios. As you can read from the [cucumber documentation itself](https://docs.cucumber.io/guides/anti-patterns/), it couples everything together and the steps you made cannot be reused for another scenario.
The step definitions should be organised in the same way than your domain concepts and, moreover, named after them. This way your step definitions code will be factorized, easier to find and navigate through, you'll get easier steps to manage and reuse. In other words, **the step definitions should be designed with the same processes we use to create our business domain!**

You may wondering how we can share data between several step definitions which is mandatory if we need to reuse them. Cucumber is offering [an integration with the Pico container](https://docs.cucumber.io/cucumber/state/#dependency-injection), a lightweight dependency injection framework.
Once the dependency is added to your pom, you simply have to define a Bean Factory where you will register the beans you need [CustomPicoFactory](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/CustomPicoFactory.kt):

```kotlin
class CustomPicoFactory : PicoFactory() {
    init {
        addClass(TestContext::class.java)
        addClass(TalksAdvisor::class.java)
        addClass(HardCodedTalksSearcher::class.java)
        addClass(InMemoryRecommendations::class.java)
        addClass(ProfileCreator::class.java)
        addClass(InMemoryProfiles::class.java)
    }
}
```

Then define a [cucumber.properties](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/test/resources/cucumber.properties) in your test resources, to register this factory in the Cucumber context.

```properties
cucumber.api.java.ObjectFactory=org.craftsrecords.talkadvisor.CustomPicoFactory
```

With that no need to have a test dependency on the whole Spring Framework! Pico is really easy to set-up as easy to use.
Now you can inject your Domain Services and Stubs inside your step definitions and as well share [a context](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/stepdefs/TestContext.kt) between them.

> Last Tip: Instead of having one single launcher for all the function tests, you can have one launcher per scenario. This is pretty convenient when you only want to run the scenarios of a single feature without playing with tags and configuration. Take a look at this [example](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/RecommendationFunctionalTests.kt).

### Domain Stubs

While implementing a feature, we often need to call some external dependencies which offers a service to our domain, such as [YouTubeSearchTalks](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-infra/talkadvisor-infra-application/src/main/kotlin/org/craftsrecords/talkadvisor/infra/youtube/YouTubeSearchTalks.kt) our YouTube client.
But since the domain cannot depends on external stuff, how can we test it ? The response is pretty simple, we creates a lightweight component which implements the SPI **inside the domain** [HardCodedTalksSearcher](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/spi/stubs/HardCodedTalksSearcher.kt).
This will ensure the inside of the hexagon - the domain of our application - will be self-tested.
Why not only a Mock inside the tests ? The domain stub is more that just a testing tool, it helps you to focus on the important thing of your development process, more information about that [here](https://beyondxscratch.com/2017/08/19/decoupling-your-technical-code-from-your-business-logic-with-the-hexagonal-architecture-hexarch/).

Actually in TalkAvisor, only the SPI part related to the provisioning of the Talks has been implemented through a YouTube client. The repositories which are used to store our profiles and recommendations are implemented using HashMaps e.g. [InMemoryProfiles](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/spi/stubs/InMemoryProfiles.kt).
This way we can focus on the main purpose of the application - recommending talks - and delay some technical concern like "what will be the best database system for my software ?".

![Functional Tests in the Hexagonal Architecture](images/hexagon-stubbed.png)

### Low-Level Assertions Caveat

Assertions frameworks like [AssertJ](http://joel-costigliola.github.io/assertj/) are widely spread now. They are offering a fluent way of writing our acceptance criteria.
TalkAdvisor has to make sure that talks which belong to a recommendation are related to the topics of the user preferences. In the MVP of our application, we will consider a [talk](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/talk/Talk.kt) is related to a topic
if its title contains the given topic. In the different tests where we want to check this post-condition, we will end-up with something like this:
```kotlin
//Talk level tests assertion
assertThat(talk.title).contains("topic")

//Recommendation level tests assertion
assertThat(recommendation.talks.map { it.title }).anyMatch{ it.contains("topic") }
```

First we lost the intend of the test, it will require some thought for someone who doesn't know the project why - the hell - we are checking a talk is containing the requested topic.
But that's not the only caveat. If now we have this new requirement "We consider a talk is related to a topic, if its title AND its description contains the topic", we will have to update all the tests
which are responsible to verify (may be at different levels) this new requirement. We can add the new assertion on the first test but leave the second one as it and all the tests will pass.
In that case we may have a functional hole on the recommendation side, but everyone is reviewing all the tests of the application each time a new business rule is added right?..

To fix the problem, with the help of some Domain-Driven Design & Clean Code concepts, we will **encapsulate** the acceptance criteria - the second assertion is btw violating the encapsulation of the recommendation.
This way those "encapsulations" will be reused so it will ensure that every tests which requires the same acceptance criteria will be checked the same way.
But where ? In the production code? No, we will use custom assertions.

### Custom Assertions

AssertJ is extendable, you can write [custom assertions](http://joel-costigliola.github.io/assertj/assertj-core-custom-assertions.html) dedicated to your own domain in a fluent way like this:

```kotlin
assertThat(talks).areRelatedTo(topic)
```

To do such thing you need to create some Assertions class like [TalkAsserts](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/assertions/TalkAsserts.kt):

```kotlin
class TalkAssert(actual: Talk) : AbstractAssert<TalkAssert, Talk>(
        actual,
        TalkAssert::class.java
) {

    infix fun `is related to topic`(topicName: String) {
        matches({ it.title.contains(topicName) }, "is related to topic $topicName")
    }

    infix fun `is in the format`(talkFormat: TalkFormat) {
        matches({ it.format == talkFormat }, "correspond explicitly to the format $talkFormat")
    }
}

```

If you look also to [RecommendationAssert](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/assertions/RecommendationAssert.kt)

```kotlin
class RecommendationAssert(actual: Recommendation) : AbstractAssert<RecommendationAssert, Recommendation>(
        actual,
        RecommendationAssert::class.java
) {

    infix fun `has talks related to`(topicName: String) {
        matches({
            it.criteria.topics.any { topic -> topic.name == topicName }
        }, "recommendations criteria has the topic $topicName")

        actual.talks.those `are related to topic` topicName
    }
}

```

You can also see that there is a real encapsulation of the acceptance criteria, because a recommendation related to a specific topic means at least one of its talk is related to that topic and also the stored user criteria are also related to it.
Otherwise there will be an inconsistency. So next time we have to write a test where we want to check this acceptance criteria, we won't have to recode all of them - we will keep in our tests a **single level of abstraction on the assertions** as well.

And TJWHEN!!! *(Thanks JetBrains We Have Extensions Now)* We can write it in a sexier way than the assertThat. Once your assertions classes are created, you can extend your class in your test to attach the assertions to it.

So you'll be able to write stuffs like:

```kotlin
 @Then("^the recommended talks correspond to his preferences$")
    fun `the recommended talks correspond to his preferences`() {
        val recommendation = testContext.recommendation
        val profile = testContext.createdProfile
        val preferences = profile.preferences

        recommendation.that `corresponds to the criteria` preferences
        recommendation.that `has talks related to` preferences.topics
        recommendation.that `has only talks in the formats` preferences.talksFormats
    }
```

To do such things, take a look at [DomainAssertions](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/assertions/DomainAssertions.kt)
```kotlin
val Recommendation.that: RecommendationAssert
    get() = RecommendationAssert(this)

val Talk.that: TalkAssert
    get() = TalkAssert(this)

val Iterable<Talk>.those: TalksAssert
    get() = TalksAssert(this)

val Profile.that: ProfileAssert
    get() = ProfileAssert(this)
```

We also have custom assertions inside the infrastructure [ResourcesAssertions](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-infra/talkadvisor-infra-application/src/test/kotlin/org/craftsrecords/talkadvisor/infra/resources/assertions/ResourcesAssertions.kt).
They are mainly used to make sure the "acceptance criteria" of a mapping of a domain object to an adapter one (and also the opposite) will be shared by all the mappers.

> AssertJ also provide some [assertions generators](http://joel-costigliola.github.io/assertj/assertj-assertions-generator.html), in order to get automatically domain-field based assertions like ``assertThat(talk).hasTitle(title)``.
> This feature is unfortunately not used on the current project.

## Unit Tests

### Domain Object Factories

In Domain-Driven Design, the domain **is not composed of POJOs!** It means the domain objects should not exposes their states but their behaviors through the encapsulation. So mocking a domain object is prohibited.
Why ? Let's imagine you are mocking a Talk object so it will say that it has a duration of 1 hour and its [format](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/talk/TalkFormat.kt) is an IGNITE.
Which doesn't make sense right ? And what's about [the test which is built on top of it](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/39338377d4ac8b76b128e7767d6de9f602e37b7c/talkadvisor-infra/talkadvisor-infra-application/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/MockCaveatTest.kt)?

A domain object, thanks to the validation logic of its constructor, will always ensures that it is coherent, no need to check it after the creation. It saves us from a lot of bugs!
But the counterpart is it makes the tests harder to write. Because each time we want to do a test where a recommendation is needed, it has to be built correctly and you have to think about all the business rules...
The best way to fix that is the usage of domain object factories. In those factory, we put once for all the creation logic of a domain object which is reused in every tests which needs an instance.

In TalkAdvisor, we have for example [TalkFactory](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/talk/TalkFactory.kt)

```kotlin
fun createTalk(criteria: Criteria): Talk {
    return prepareBuilder()
            .apply { duration = durationFrom(criteria) }
            .build()
}

private fun durationFrom(criteria: Criteria) = criteria.talksFormats.random().randomDuration()

fun createTalk(): Talk {
    return prepareBuilder().apply { duration = ofMinutes(Random.nextLong(2, 120)) }.build()
}
```

As you can see here, we have a factory of Talks which is taking as parameters some criteria. The reason is when you want to create a Recommendation, you have to make sure the stored criteria and the talks are aligned.
So in the [tests](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/RecommendationTest.kt) we are reusing them to create a valid Recommendation.

```kotlin
   @Test
    fun `should create a recommendation`() {
        val (criteria, talks) = bootstrap()

        val recommendation = Recommendation(criteria = criteria, talks = talks)

        assertThat(recommendation.id).isNotNull()
        assertThat(recommendation.talks).isEqualTo(talks)
        assertThat(recommendation.criteria).isEqualTo(criteria)
    }

    private fun bootstrap(): Pair<Criteria, Set<Talk>> {
        val criteria = createCriteria()
        val talks = createTalks(criteria)
        return Pair(criteria, talks)
    }

```

**IMPORTANT NOTICE:** You should never use this kind of factory when you care about the values inside - because if someone is changing the creation logic, your test will fail. It should be used only like black boxes in order to quickly bootstrap data for the tests.
When you are expecting some specific values for domain objects, **you should create it explicitly in your test**, like done in [RecommendationControllerTest](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-infra/talkadvisor-infra-application/src/test/kotlin/org/craftsrecords/talkadvisor/infra/controller/RecommendationControllerTest.kt#L112).
Since the controller test if actually verifying the values inside the returned JSON are the expected ones - more precisely the preferences of stored the profile, we explicitly create the profile.

> You can also share pre-initialized builders if needed.

### Test Composition

Opening the debate...

Let's now take a look at the [Profile](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-infra/talkadvisor-infra-application/src/main/kotlin/org/craftsrecords/talkadvisor/infra/resources/Profile.kt) resource inside the REST adapter.

```kotlin
data class Profile(private val id: String, val preferences: Preferences) : Identifiable<String> {
    override fun getId() = id
}

fun DomainProfile.toResource(): Profile = Profile(this.id, this.preferences.toResource())
```

Profile is a top-level resource which contains a sub-resource named preferences (same composition than the domain). In order to convert a Profile of the domain to a resource, an extension method ``toResource`` has been defined.
You can also see the resource transformation is cascaded to the inner preferences. When [testing the Profile resource transformation](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-infra/talkadvisor-infra-application/src/test/kotlin/org/craftsrecords/talkadvisor/infra/resources/ProfileTest.kt), we will also test by transitivity the transformation of the preferences into a resource.
So there is no need to repeat this test at [Preferences level](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-infra/talkadvisor-infra-application/src/test/kotlin/org/craftsrecords/talkadvisor/infra/resources/PreferencesTest.kt).

That's totally fine since the Preferences resource is never used outside of the transformation of a Profile or a Recommendation (the only objects using it). When adopting a black-box test approach, e don't really care about the implementation, but only the exposed behavior.
Fortunately with the encapsulation principle, we expose the behavior only through a limited number of classes: domain aggregates for entities and value objects and domain services implementing the API.
It means you only have to write a test where the behavior is exposed. You'll limit this way the number of (useless) tests you'll have to maintain.

On the other hand, edge-cases should be tested directly on the object which has the effective responsibility of dealing with those cases. For example [PreferencesTest](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-infra/talkadvisor-infra-application/src/test/kotlin/org/craftsrecords/talkadvisor/infra/resources/PreferencesTest.kt) is testing for the mapping of an unknown TalkFormat (enum):

```kotlin
    @Test
    fun `should throw IllegalArgumentException when trying to map an unknown TalkFormat`() {
        val topics = listOf(Topic("topic"))
        val talksFormats = listOf("UNKNOWN")
        val preferences = Preferences(topics, talksFormats)

        assertThatThrownBy { preferences.toDomainObject() }
                .isInstanceOf(IllegalArgumentException::class.java)
                .hasMessage("No enum constant ${TalkFormat::class.java.name}.UNKNOWN")
    }
```

You'll not find this test in the upper-levels of the hierarchy of the Preferences resource, like [Profile](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-infra/talkadvisor-infra-application/src/test/kotlin/org/craftsrecords/talkadvisor/infra/resources/ProfileTest.kt) and [Recommendation](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-infra/talkadvisor-infra-application/src/test/kotlin/org/craftsrecords/talkadvisor/infra/resources/RecommendationTest.kt).
The following reasons are:
* If you move all the edge-cases of the children hierarchy at the higher-level (and everywhere in the hierarchy), you'll end-up with a lot of hard-to-maintain tests.
* In the previous example, you'll have to put the same test inside ProfileTest and RecommendationTest, and it won't change at all the test coverage of your application.

That's basically the concept of test composition.

## Integration Tests, Contract Testing & End-To-End Tests

>The documentation is coming soon !

## Documentation

More than a specification, the feature tests written in Gherkin is a real living documentation of your application. It should reflects what is the behavior of a feature in a given scenario, pretty helpful when you need to improve or maintain the domain.
That's why we strongly recommend to make sure the Cucumber tests will fails if your step definitions are not implemented. **Having a confusing (lying) documentation is worse than not having documentation at all!**
By default cucumber will just log some warns, to prevent the test from being successful just add the ``strict`` option in the configuration of your [runners](https://gitlab.com/crafts-records/talkadvisor/talkadvisor-back/blob/master/talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/RecommendationFunctionalTests.kt).

```kotlin
@CucumberOptions(strict = true, plugin = ["pretty", "json:target/cucumber/recommendation.json"], features = ["classpath:features/recommendations.feature"])
```

repository: craftsrecords/talkadvisor-backend

gha_language: Kotlin

repo_name: craftsrecords/talkadvisor-backend


text:
## 0.3.2
* warning when user updates `attr: "data-*"` - it should be done with `data: *` (#14)

## 0.4.0
Changes:

## Bugs:
* Ignoring unmatched topic "drab:/drab" in DrabPoc.UserSocket

## Future
Changes:
* rewrite Drab.Query - use meta, Luke!
* broadcast to all except you
* tests, tests, tests
* benchmarks
* timeout for event handlers
* timeout for Drab.Query and Drab.Modal functions
* specify on which pages drab broadcasts, with wildcard
* dependencies for modules (for ex. Modal depends on Query)
* extract Drab Store and Session to standalone module (loaded by default)
* group JS commands to be launched in one step
* render templates, views in commanders (accutally it can already be done, must thing about some helpers)
* render Drab templates in a compile-time
* compress Drab templates (js)
* before_handler, only: should take a list or atom (currently list only)

## Bugs or features?
* Drab.Socket steals all `connect` callbacks. Bad Drab

license: MIT

repository: rrevanth/drab

branch_name: refs/heads/master

extension: md

license_type: permissive

repo_name: rrevanth/drab


text:
# liri-node-app

LIRI stands for Language Interpretation and Recognition Interface. LIRI is a command line node app that takes in parameters and gives you back data.

## Preview

## Full Video Demo ⬇

https://youtu.be/mys_RsMbCaE

* Watch on YouTube
* Length: 1:20
* No audio

## Getting Started

Download or clone the Git Repository will get you a copy of the project up and running on your local machine for development and testing purposes.

Make liri.js take in one of the following commands:

`concert-this`
`spotify-this-song`
`movie-this`
`do-what-it-says`

### What Each Command Should Do

Navigate to the local directory of the project inside your Terminal. Enter the following command to render information based on your search request:

```
node liri.js concert-this <artist/band name here>
```
![concert-this](https://i.ibb.co/PrxzRcn/Screen-Shot-2019-03-28-at-11-23-54-pm.png)

```
node liri.js spotify-this-song <song name here>
```
![spotify-this-song](https://i.ibb.co/g9xnjrN/Screen-Shot-2019-03-28-at-11-24-28-pm.png)

```
node liri.js movie-this <movie name here>
```
![movie-this](https://i.ibb.co/4gsgd9L/Screen-Shot-2019-03-28-at-11-24-45-pm.png)

```
node liri.js do-what-it-says
```
![do-what-it-says](https://i.ibb.co/XVVb16y/Screen-Shot-2019-03-28-at-11-25-08-pm.png)

# License

This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/xmkchen/liri-node-app/blob/master/LICENSE) file for details.

# Acknowledgement

* TA's - Adrian Pearman and Dimitry Besson

* UofT Boot Camp 2019


text:
# Best Practices

A collection of things I consider to be best practices in test-driven iOS development

## Practices and Principles

Some of the practices and principles I tried to demonstrate in this sample project are:

* [Test-driven development][tdd] using [Cedar][]
* [Dependency injection][di] using [Blindside][]
* Promise-based async APIs using [KSDeferred][]
* [Single responsibility principle][srp]
* [Composition over inheritance][coi]
* Stateless objects where possible

[blindside]: https://github.com/jbsf/blindside
[cedar]: https://github.com/pivotal/cedar
[coi]: http://en.wikipedia.org/wiki/Composition_over_inheritance
[di]: http://en.wikipedia.org/wiki/Dependency_injection
[ksdeferred]: https://github.com/kseebaldt/deferred
[srp]: http://en.wikipedia.org/wiki/Single_responsibility_principle
[tdd]: http://en.wikipedia.org/wiki/Test-driven_development

repository: alexbasson/BestPractices

repo_name: alexbasson/BestPractices


text:
![GraphVite logo](asset/logo/logo.png)

GraphVite - graph embedding at high speed and large scale
=========================================================

[![Install with conda](https://anaconda.org/milagraph/graphvite/badges/installer/conda.svg)][conda]
[![License](https://anaconda.org/milagraph/graphvite/badges/license.svg)][license]

[conda]: https://anaconda.org/milagraph/graphvite
[license]: LICENSE

GraphVite is a general graph embedding engine, dedicated to high-speed and
large-scale embedding learning in various applications.

GraphVite provides complete training and evaluation pipelines for 3 applications:
**node embedding**, **knowledge graph embedding** and
**graph & high-dimensional data visualization**. Besides, it also includes 9 popular
models, along with their benchmarks on a bunch of standard datasets.

        Node Embedding
        Knowledge Graph Embedding
        Graph & High-dimensional Data Visualization

Here is a summary of the training time of GraphVite along with the best open-source
implementations on 3 applications. All the time is reported based on a server with
24 CPU threads and 4 V100 GPUs.

Node embedding on [Youtube] dataset.

| Model      | Existing Implementation       | GraphVite | Speedup |
|------------|-------------------------------|-----------|---------|
| [DeepWalk] | [1.64 hrs (CPU parallel)][1]  | 1.19 mins | 82.9x   |
| [LINE]     | [1.39 hrs (CPU parallel)][2]  | 1.17 mins | 71.4x   |
| [node2vec] | [24.4 hrs (CPU parallel)][3]  | 4.39 mins | 334x    |

[Youtube]: http://conferences.sigcomm.org/imc/2007/papers/imc170.pdf
[DeepWalk]: https://arxiv.org/pdf/1403.6652.pdf
[LINE]: https://arxiv.org/pdf/1503.03578.pdf
[node2vec]: https://www.kdd.org/kdd2016/papers/files/rfp0218-groverA.pdf
[1]: https://github.com/phanein/deepwalk
[2]: https://github.com/tangjianpku/LINE
[3]: https://github.com/aditya-grover/node2vec

Knowledge graph embedding on [FB15k] dataset.

| Model           | Existing Implementation       | GraphVite | Speedup |
|-----------------|-------------------------------|-----------|---------|
| [TransE]        | [1.31 hrs (1 GPU)][3]         | 14.8 mins | 5.30x   |
| [RotatE]        | [3.69 hrs (1 GPU)][4]         | 27.0 mins | 8.22x   |

[FB15k]: http://papers.nips.cc/paper/5071-translating-embeddings-for-modeling-multi-relational-data.pdf
[TransE]: http://papers.nips.cc/paper/5071-translating-embeddings-for-modeling-multi-relational-data.pdf
[RotatE]: https://arxiv.org/pdf/1902.10197.pdf
[3]: https://github.com/DeepGraphLearning/KnowledgeGraphEmbedding
[4]: https://github.com/DeepGraphLearning/KnowledgeGraphEmbedding

High-dimensional data visualization on [MNIST] dataset.

| Model        | Existing Implementation       | GraphVite | Speedup |
|--------------|-------------------------------|-----------|---------|
| [LargeVis]   | [15.3 mins (CPU parallel)][5] | 15.1 s    | 60.8x   |

[MNIST]: http://yann.lecun.com/exdb/publis/pdf/lecun-01a.pdf
[LargeVis]: https://arxiv.org/pdf/1602.00370.pdf
[5]: https://github.com/lferry007/LargeVis

Requirements
------------

Generally, GraphVite works on any Linux distribution with CUDA >= 9.2.

The library is compatible with Python 2.7 and 3.6/3.7.

Installation
------------

### From Conda ###

GraphVite can be installed through conda with only one line.

```bash
conda install -c milagraph graphvite cudatoolkit=x.x
```

where `x.x` is your CUDA version, e.g. 9.2 or 10.0.

If you only need embedding training without evaluation, you can use the following
alternative with minimal dependencies.

```bash
conda install -c milagraph graphvite-mini cudatoolkit=x.x
```

### From Source ###

Before installation, make sure you have `conda` installed.

```bash
git clone https://github.com/DeepGraphLearning/graphvite
cd graphvite
conda install -y --file conda/requirements.txt
mkdir build
cd build && cmake .. && make && cd -
cd python && python setup.py install && cd -
```

Quick Start
-----------

Here is a quick-start example of the node embedding application.

```bash
graphvite baseline quick start
```

Typically, the example takes no more than 1 minute. You will obtain some output like

```
Batch id: 6000
loss = 0.371641

macro-F1@20%: 0.236794
micro-F1@20%: 0.388110
```

Baseline Benchmark
------------------

To reproduce a baseline benchmark, you only need to specify the keywords of the
experiment. e.g. model and dataset.

```bash
graphvite baseline [keyword ...] [--no-eval] [--gpu n] [--cpu m]
```

You may also set the number of GPUs and the number of CPUs per GPU.

Use ``graphvite list`` to get a list of available baselines.

High-dimensional Data Visualization
-----------------------------------

You can visualize your high-dimensional vectors with a simple command line in
GraphVite.

```bash
graphvite visualize [file] [--label label_file] [--save save_file] [--perplexity n] [--3d]
```

The file can be either in numpy dump or text format. For the save file, we recommend
to use a `png` format, while `pdf` is also supported.

Contributing
------------

We welcome all contributions from bug fixs to new features. Please let us know if you
have any suggestion to our library.

Development Team
----------------

GraphVite is developed by [MilaGraph], led by Prof. [Jian Tang].

Authors of this project are [Zhaocheng Zhu], [Shizhen Xu], [Meng Qu] and [Jian Tang].
Contributors include [Kunpeng Wang] and [Zhijian Duan].

[MilaGraph]: https://github.com/DeepGraphLearning
[Zhaocheng Zhu]: https://kiddozhu.github.io
[Shizhen Xu]: https://github.com/xsz
[Meng Qu]: https://mnqu.github.io
[Jian Tang]: https://jian-tang.com
[Kunpeng Wang]: https://github.com/Kwinpeng
[Zhijian Duan]: https://github.com/zjduan

Citation
--------

If you find GraphVite useful for your research or development, please cite the
following [paper].

[paper]: https://arxiv.org/pdf/1903.00757.pdf

```
@inproceedings{zhu2019graphvite,
    title={GraphVite: A High-Performance CPU-GPU Hybrid System for Node Embedding},
     author={Zhu, Zhaocheng and Xu, Shizhen and Qu, Meng and Tang, Jian},
     booktitle={The World Wide Web Conference},
     pages={2494--2504},
     year={2019},
     organization={ACM}
 }
```

Acknowledgements
----------------

We would like to thank Compute Canada for supporting GPU servers. We specially thank
Wenbin Hou for useful discussions on C++ and GPU programming techniques.

repository: awesomemachinelearning/graphvite

repo_name: awesomemachinelearning/graphvite


text:
---
title: Key Features
page_title: Getting Started with Xamarin.Forms MaskedInput Control
description: Check our "Key Features" documentation article for Telerik MaskedInput for Xamarin control.
position: 1
slug: maskedinput-key-features
---

#  Key Features

The purpose of this help article is to show you the key features of the RadMaskedInput control.

## Mask-related properties:

* **MaskType**(*of type Telerik.XamarinForms.Input.MaskedInput.MaskType*): Defines the expected validation type of the Mask. Here are the two options:
	* **Text** (for Tokens validation)
	* **Regex** (for RegEx validation)
* **Mask**(*string*): Specifies a string defining the mask. In case of using Text validation, you should use the available Mask Tokens. Otherwise, a regular expression should be set.
* **IsMaskFull**(*bool*): Gets a value indicating if all required symbols are filled. The default value is true. Can be false only when required symbols tokens are present in the mask. (*ReadOnly*)
* **InputValue**(*string*): Defines the input value.
* **IsInputAccepted**(*bool*): Gets a value indicating whether the input matches the mask.(*ReadOnly*)
* **Keyboard** (*Xamarin.Forms.Keyboard*): Defines the type of the keyboard that will be visualized by the device.

## Appearance-related properties:

* **WatermarkText**(*string*): Specifies the text used as watermark.
* **WatermarkTextColor**(*Color*): Specifies the color of the text of the watermark.
* **DisplayedText**(*string*): Gets the displayed text.(*ReadOnly*)
* **DisplayedTextColor**(*Color*): Defines the color of the displayed text.
* **DisplayedTextFont**(*string*): Defines the font of the displayed text.
* **DisplayedTextFontSize**(*double*): Defines the size of the font used for the displayed text.
* **BorderStyle**(*of type Telerik.XamarinForms.Input.BorderStyle*) Gets or sets a Telerik.XamarinForms.Input.RadMaskedInput.BorderStyle defining the look of the border around the entry. The default value is defined by the OS.
* **Placeholder**(*char*): Specifies the symbol that will be used to mark an empty position. The default value is '_'.

## Validation-related properties:

* **InvalidInputErrorText**(*string*): Defines the text that is shown as error message on invalid input.
* **ErrorColor**(*Color*): Specifies the color of the error text.
* **ErrorFontSize**(*double*): Specifies the font size of the error text.
* **RejectedSymbolErrorText**(*string*):  Defines the error text when a symbol was rejected.
* **IsErrorTextVisible**(*bool*): Gets a value indicating whether the error text is visible. (*ReadOnly*)

>important **SDK Browser** and **QSF** applications contain different examples that show RadMaskedInput's main features. You can find the applications in the **Examples** and **QSF** folders of your local **Telerik UI for Xamarin** installation.

## See Also

* [Tokens]({%slug maskedinput-features-mask-tokens%})
* [RegEx]({%slug maskedinput-features-mask-extensions%})
* [Validation]({%slug maskedinput-features-validation%})
* [Commands]({%slug maskedinput-features-commands%})
* [Events]({%slug maskedinput-features-events%})
* [Theming and Style]({%slug maskedinput-theming-style%})

repository: telerik/xamarin-forms-docs

gha_language: JavaScript

repo_name: telerik/xamarin-forms-docs


text:
# BuyMe Auction Site

[![Java CI](https://github.com/b361asd/Auction_Site/actions/workflows/maven.yml/badge.svg)](https://github.com/b361asd/Auction_Site/actions/workflows/maven.yml)

BuyMe is an implementation of a web auction site, similar to the likes of Ebay.
It is implemented using Java, [JSP](https://en.wikipedia.org/wiki/JavaServer_Pages) and MySQL.

## Prerequisites

-   Java 17
-   [Apache Maven](https://maven.apache.org/)
-   MySQL Workbench
-   MySQL Server
-   [Apache Tomcat](https://tomcat.apache.org/)

## How to run

### Docker

Run

```console
$ docker build -t b361asd/auctionsite .
```

to build the image. To start it, run

```console
$ docker run -p 8888:8080 b361asd/auctionsite
```

Navigate to

```
http://localhost:8888/auctionsite
```

### Local Development

If locally, run:

```console
$ mvn install
```

The `.war` file will be in the `target` directory.

## License

[MIT](LICENSE)


text:
[Previous](./ex02-03.md)                [Solution](../ans/ans03-01.md)            [Next](./ex03-02.md)
# Exercise 03.01 - Strings - Concatenation

Aim:
- understand string concatenation

Print a greeting in the form ``Hello <firstname> <lastname>!`` where
``<firstname>`` and ``<lastname>`` should be the values entered by the user
in the two dialogs that will be displayed when running the macro.

Use string concatenation to produce the output String.

```java
firstname = getString("Enter your first name: ", "Alan");
lastname = getString("Enter_your last name:", "Turing");
"\\Clear";
```
Your code starts after this line
```java

```
 Your code ends before this line

The code below is for automatically checking the result. Please ignore it!
```java
parts = split(getInfo("log"));
result = (parts[0] == "Hello");
result = result && (parts[1] == firstname);
result = result && (startsWith(parts[2], lastname));
result = result && (endsWith(parts[2], "!"));

if (result)
	showMessage("That's right. Great, you did it!");
else
	showMessage("Your result is wrong! Please check your macro and try again!");
```

[Previous](./ex02-03.md)                [Solution](../ans/ans03-01.md)            [Next](./ex03-02.md)


text:
# Redux Multilanguage
A higher-order component used with Redux to support multilanguage

![Demo](https://media.giphy.com/media/mXVGIebpCTTpAAN35N/giphy.gif)

## Installation
```
npm install --save redux-multilanguage
```
or
```
yarn add redux-multilanguage
```

## Setup

1. Prepare language.json files. File name should be a unique language code. For example:
```js
//vi.json
{
  "Title": "Tieu de",
  "Name": "Ten",
  "Language": "Ngon ngu"
}

//en.json
{
  "Title": "Title",
  "Name": "Name",
  "Language": "Language"
}
```

2. Create `multilanguage` reducer in your root reducer:

```js
// reducers.js
import {combineReducers} from 'redux'
import {createMultilanguageReducer} from 'redux-multilanguage'

export default combineReducers({
  multilanguage: createMultilanguageReducer({currentLanguageCode: 'en'}),
  //...
})
```

3. Connect your component to `redux-multilanguage`:

```jsx
// App.js
import React from 'react'
import {
  languageLoader,
  multilanguage,
  changeLanguage,
  loadLanguages
} from 'redux-multilanguage'
import {connect} from 'react-redux'

class App extends React.Component{
  state = {language: 'en'}
  componentDidMount(){
    this.loadLanguages()
  }
  loadLanguages(){
    // Below is to load languages, must call this once on app start,
    // and when user switch to new language that haven't loaded yet.
    this.props.dispatch(loadLanguages({
      languages: {
        vi: require('./vi.json'),
        en: require('./en.json')
      }
    }))
  }
  changeLanguage = (e) => {
    const languageCode = e.target.value
    // To change language:
    this.props.dispatch(changeLanguage(languageCode))
  }
  render(){
    const {
      /*
        Below props are passed by 'multilanguage' HOC.
        'strings' is the JSON of the language file.
        For example, if 'currentLanguageCode' is 'en',
        then 'strings' is the content of 'en.json'
       */
      strings,
      currentLanguageCode
    } = this.props
    return <div>
      {strings["Title"]}

      Change language: <select
        value={currentLanguageCode}
        onChange={this.changeLanguage}
      >
        <option value="en">en</option>
        <option value="vi">vi</option>
      </select>
    </div>
  }
}
export default connect()(multilanguage(App))
```

For more, see [full working example](https://github.com/stssoftware/redux-multilanguage/tree/master/example).

## APIs
Below are what exported by `redux-multilanguage`
* [HOC] `multilanguage(WrappedComponent)`: Use this to wrap your component, wrapped component will have these passed props:
  * `strings`: The JSON of current selected language.
  * `currentLanguageCode`: The code of current language, to change this, dispatch `changeLanguage()`
* [action creator] `loadLanguages(config)`: Load languages, this action should be dispatched when app start or dispatched mutiple times when ever demand to lazy-load languages.
  * `config.languages`: An object, keys are language codes, equivalent values are json of code-string values. Example:

    ```
    dispatch(loadLanguages({
      languages: {
        vi: {Title: 'Tieu de', Name: 'Tên'},
        en: {Title: 'Title', Name: 'Name'}
      }
    }))
    ```

* [action creator] `changeLanguage(languageCode)`: an action creator to change language.
Example usage: `dispatch(changeLanguage('en'))`
* `createMultilanguageReducer(initState)`: returns a reducer for multilanguage in redux store
  * `initState.currentLanguageCode`: language code to be loaded by default

branch_name: refs/heads/main


text:
# My Rule-Validation API
A Flutterwave Assessment. You can test the [heroku live link](https://comurule-flwsoln.herokuapp.com/api-docs/), using Swagger API Documentation

## Table of Contents
1. Application Features
2. How To Use
3. Author
4. License

## Tech Stack Used

- [Node.js](https://nodejs.org/)
- [Express](https://expressjs.com/)
- [Swagger Documentation](https://swagger.io/)

## Application Features

*  Get the profile of the repository author
*  Validate a given `data` object with a condition set in a `rule` object.

## How To Use

To clone and run this application, you'll need [Git](https://git-scm.com) and [Node.js](https://nodejs.org/en/download/) (which comes with [npm](http://npmjs.com)) installed on your computer. From your command line:

```bash
# Clone this repository
$ git clone https://github.com/Comurule/rule-validation-api.git

# Go into the repository
$ cd rule-validation-api

# Install dependencies
$ npm install or yarn install

# Run the app
$ npm start or yarn start
```

## API endpoints
```
GET Request -> localhost:3000/

response:
{
    "message": "My Rule-Validation API",
    "status": "success",
    "data": {
        "name": "Chibuike Umechukwu",
        "github": "@comurule",
        "email"<EMAIL_ADDRESS>        "mobile": "07039601940"
    }
}

POST Request -> localhost:3000/validate-rule
body:
{
  "rule": {
    "field": "missions.count",
    "condition": "gte",
    "condition_value": 30
  },
  "data": {
    "name": "James Holden",
    "crew": "Rocinante",
    "age": 34,
    "position": "Captain",
    "missions": {
      "count": 45,
      "successful": 44,
      "failed": 1
    }
  }
}

response:
{
  "message": "field missions.count successfully validated.",
  "status": "success",
  "data": {
    "error": false,
    "field": "missions.count",
    "field_value": 45,
    "condition": "gte",
    "condition_value": 30
  }
}

```
## Author

Chibuike Umechukwu

## License

MIT

---

repository: Comurule/rule-validation-api

repo_name: Comurule/rule-validation-api


text:
---
title:  The Role of Stewardship
date:   03/03/2018
---

**Introduction:** Col. 1:16–18

### The Stewardship Triangle

Let us think about stewardship as a triangle, with God at the upper tip and Christians and resources at the base. God is a faithful provider, and He has given us the Holy Spirit to direct our ways and inform our decisions on how to use His gifts wisely. From the Creation week, God gave humanity the responsibility of stewardship (Gen. 1:28).

**“It shall be given away or kept, only as by giving or keeping it I shall most promote the glory of Him to whom I owe all my hopes in time or eternity.”**

However, when sin came, it disrupted the original setup, and humans lost the power that God gave them to be good stewards. Nevertheless, not all was lost when God decided to restore the order through His Son Jesus Christ. Our understanding of stewardship, as followers of Christ, involves the knowledge that He is at the center of our lives and the resources around us.

God gives to us freely, and He wants us to use the resources to advance His kingdom. We can achieve this goal when we accept the cost of discipleship. We choose to follow Christ and obey God’s Word, regardless of the prevailing circumstances. As Christian disciples, we experience a change of heart and mind in order to commit ourselves to the Lord.

Christian stewardship is part of a reformed way of life in which we recognize God as the source of our lives, freedom, and everything that we possess. It goes beyond responsible use of material and human resources. It surpasses generous giving of our talents, time, or treasure. It has the power to reconstruct our understanding of our way of life and help us abide by what the Giver of life and resources wants us to do.

What we can do as Christian stewards is to receive God’s gifts, use them responsibly, share them lovingly, and return them to God to advance His kingdom. David Livingstone once said, “I place no value on anything I have or may possess, except in relation to the kingdom of God. If anything will advance the interests of the kingdom, it shall be given away or kept, only as by giving or keeping it I shall most promote the glory of Him to whom I owe all my hopes in time or eternity.”*

This week, we shall learn more about the role of stewardship in our lives as Christians.

<sub>*David Livingstone, quoted in “Stewardship,” Sermon Illustrations, accessed October 17, 2016, http://www.sermonillustrations.com/a-z/s/stewardship.htm.</sub>

_Mark Gift, Nairobi, Kenya_

repository: Adventech/sabbath-school-lessons

branch_name: refs/heads/stage

gha_license_id: MIT

repo_name: Adventech/sabbath-school-lessons


text:
---
title: Sentiment Analysis in Tableau & R
date: 2016-03-02 15:00:00
template: post
draft: false
description: In this blog I will run you through the basics of one element of text analysis, sentiment analysis, how to connect and install R, R Server and R packages. I will be using some Twitter data to illustrate the sentiment analysis in Tableau.
socialImage: https://www.theinformationlab.co.uk/wp-content/uploads/2016/03/blog-image-two2.png
category: "Tableau"
tags:
  - tableau
---

## Sentiment Analysis in Tableau & R

At the Tableau Partner Summit in London I attended a session about statistics and sets in Tableau. In this session, Oliver Linder, Sales Consultant at Tableau, explained the basics of the R integration in Tableau. During this presentation he explained step-by-step how to connect the R server in Tableau and he did a short demonstration of how to write a calculated field in which you can calculate the correlation between two variables with R.

This session made me think about different ways of applying the capabilities of R in Tableau and one of my main analytic interests is corpus analysis. Tableau doesn’t natively support Natural Language Processing (NLP) for various reasons but with the R integration you can do basic text analysis on your set of text. In this blog I will run you through the basics of one element of text analysis, sentiment analysis, how to connect and install R, R Server and R packages. I will be using some Twitter data to illustrate the sentiment analysis.

What is Sentiment Analysis?
First of all, what is sentiment analysis? We call this the process of computationally identifying, processing and categorising text data in order to obtain opinions and attitudes towards certain themes, topics, products etc. There are several methods to recognise or mine people’s attitudes, ranging from human analysis to supervised and unsupervised machine learning with programming languages such as Python and R (“bag of words”) . Sentiment analysis can be object/feature based when we determine the expressed sentiment on different objects of entities, or based on document level. The latter determines the polarity of, for example, news items or product reviews. There are several ways of showing sentiment, from the most common three polarity levels positive, neutral and negative to polarity scales of, for example, -10 to +10.

Getting the data
Now that we know the principle elements of sentiment analysis we can apply this to a set of text. For this blog I downloaded some raw Twitter data from the API through Alteryx. I limited the API call to 5,000 tweets and used the keywords “Tableau” and “#Tableau” to find the most recent tweets mentioning these keywords.

alteryx twitter api

How to install and setup R?

This isn’t by far the most cleaned text data set I ever worked with, or the most sophisticated Alteryx workflow, but that is not the purpose of this blog. Once Alteryx has completed the workflow we can move towards downloading and installing R and RStudio. You can download both here and here. The latter is called an integrated development environment (IDE) for R. After installation you need to start the R Server in order to make a connection with Tableau. This is a server that allows applications to access R functionality. You can also host the R Server on your local machine, which I did for this blog. The installation of both is self explanatory and when you open RStudio you need to type the following commands in the console to install the Rserve:
install.packages(“Rserve”)
library(Rserve)
Rserve()

I installed R and RStudio on a Mac so I needed to change the last command that executes the Rserve to Rserve(args=”–no-save”). You will see a response from R saying that the Rserve is starting and it will return you to the command line in order to write more code when it’s done.

rserve

After you’ve successfully installed R and RStudio and you have your Rserver running you can make the connection with Tableau. The official documentation from Tableau to set up the connection is straightforward. You can connect to R by going to the Help Menu in Tableau Desktop choose Settings and Performance > Manage R Connection.

connectionr

Note that in Tableau 9.3 this will be changed to Help > Settings and performance > Manage External Service Connection. As you can see Tableau removed Rserve in the dropdown, but this doesn’t mean Tableau will stop the support of R. When you run the server locally you can set the connection as described in the image. You can test the connection by clicking on Test Connection and Tableau will return a message saying “Successfully connected to the Rserve service”.

R in Tableau

Next you want to connect to your text data, in this case my Twitter corpus with tweets about Tableau. There are four functions to pass R expressions in calculated fields:

SCRIPT_BOOL
SCRIPT_INT
SCRIPT_REAL
SCRIPT_STR

For text analysis we need to use the latter, SCRIPT_STR. These four R expressions are included in the Table Calculations window. They consist of the following elements (R expression, (.arg1, .arg2)’, AGG([Field1]), AGG([Field2]). You can add in more arguments than two. In this case, arg1 is Field1 and arg2 is Field2. As you can see you have to input an aggregate or a constant number in order to make the calculation valid. Before we can write our sentiment analysis calculation, we first need to install a couple of R packages. There are various R packages that do text analysis but in this blog we are using tm and Sentiment. You can either download them here and here or you can run the following scripts in your R console:

tm:
install.packages(“tm”)
download.file(“http://cran.cnr.berkeley.edu/src/contrib/Archive/Rstem/Rstem_0.4-1.tar.gz”, “Rstem_0.4-1.tar.gz”)
install.packages(“Rstem_0.4-1.tar.gz”, repos=NULL, type=”source”)

sentiment:
download.file(“http://cran.r-project.org/src/contrib/Archive/sentiment/sentiment_0.2.tar.gz”, “sentiment.tar.gz”)
install.packages(“sentiment.tar.gz”, repos=NULL, type=”source”)

This sentiment package is relatively old which means that you need an older version of R installed on your machine to run the package. It has two functions:
classify_polarity: classify text as positive, neutral or negative.
classify_emotion: analyse text and classify it in different types of emotion: anger, disgust, fear, joy, sadness, and surprise.

Because I have a very raw data set coming out of the Twitter API it also means I have a lof of dimensions. However, I only need one dimension in this case, the TweetBody. This dimension contains the 140 characters of text. There are two ways of loading R expressions in Tableau, you can either add them to the Rserve config or you need to load the packages in your calculation. In the latter case you need to add “library(sentiment);” to the calculation.

I created a calculation called “Sentiment” and it calls classify_polarity:

calc

As you can see I call the R package from within Tableau and I use the classify_polarity to find positive, neutral or negative tweets and I only use one argument, arg1. This argument looks at my text attribute.

This is how the output looks:

output

This is as you might have gathered by now a basic sentiment analysis package that has several flaws. Some of the negative tweets are in fact not negative. However, this can be fixed by going in the lexicon of the Sentiment package. This R package is based on a lexicon, which is a technique that uses a dictionary of words to assess whether a bunch of text is positive, negative or neutral. You can access the lexicon of this package in your library folder under sentiment\data\subjectivity.csv.gz and change how the sentiment package assesses the polarity.

Tableau has no out of the box text analytics implemented but with this small and quick R package you can run your corpus analysis from within Tableau. You can also download other text analytic packages and the logic for applying them to Tableau calculations will be similar to what I described above.

Edit: When you encounter problems with an outdated sentiment package you can follow the steps in this post.


text:
# Installation
> `npm install --save @types/d3-graphviz`

# Summary
This package contains type definitions for d3-graphviz (https://github.com/magjac/d3-graphviz).

# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/d3-graphviz.

### Additional Details
 * Last updated: Thu, 08 Jul 2021 09:08:29 GMT
 * Dependencies: [@types/d3-selection](https://npmjs.com/package/@types/d3-selection), [@types/d3-transition](https://npmjs.com/package/@types/d3-transition), [@types/d3-zoom](https://npmjs.com/package/@types/d3-zoom)
 * Global values: none

# Credits
These definitions were written by [Dom Parfitt](https://github.com/DomParfitt).


text:
---
id: bridges-concept
title: Concept
---

To make use of any schema, uniforms have to create a _bridge_ of it - a unified schema mapper. A bridge is (preferably) a subclass of `Bridge`, implementing static `check(schema)` method and these instance methods:

- `getError(name, error)`
- `getErrorMessage(name, error)`
- `getErrorMessages(error)`
- `getField(name)`
- `getInitialValue(name, props)`
- `getProps(name, props)`
- `getSubfields(name)`
- `getType(name)`
- `getValidator(options)`

Currently available bridges:

- `GraphQLBridge` in `uniforms-bridge-graphql`
- `JSONSchemaBridge` in `uniforms-bridge-json-schema`
- `SimpleSchema2Bridge` in `uniforms-bridge-simple-schema-2`
- `SimpleSchemaBridge` in `uniforms-bridge-simple-schema`

repository: delyanr/uniforms

repo_name: delyanr/uniforms


text:
# Building and Installing IPMCTL on Microsoft Windows from Source

Step 1) Install Visual Studio 2017 (or newer). Install these optional components:

* Workloads -> Desktop Development with C++
* Individual Components -> Compilers, build tools, and runtimes -> Visual C++ tools for CMake

Step 2) Download the [ipmctl source code from GitHub](https://github.com/intel/ipmctl)

Step 3) Open the ipmctl folder as a CMake project. See: [https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio](https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio)

Step 4) Begin the build process

Step 5) Once installed, go to the [Basic Usage](../basic-usage.md) section of this user guide for more information.

repository: pmem/docs

repo_name: pmem/docs


license: Unlicense

repository: tanacchi/tanacchi

repo_name: tanacchi/tanacchi


text:
## What is it?

The Runewizard lets you check easily what runewords you can make with the runes you have found.

Click on the runes to mark which ones you have found. The available runewords will be highlighted automatically.

The table can be sorted : try clicking on the table headings, you may find it useful!

## Runes

The runes are listed in order of rarity, from top to bottom, and left to right. Each vertical group of rune represents roughly **Common**, **Semi-Rare**, and **Extremely Rare** runes. Note that the order is consistent with the [rune upgrade formulas](http://classic.battle.net/diablo2exp/items/cube.shtml) for the Horadric Cube. For example: 3 x Tal = 1 x Ral rune.

## Runewords

**Ladder-only runewords** have a small L icon next to the name.

## Note about storage

Your selection of runes is saved in the browser's _local storage_. Keep in mind that manually clearing your browser cache may reset the selected runes.


text:
# ZeroBot
**Trying to make a Raspberry Pi Zero robot**

Original idea:
- https://hackaday.io/project/25092-zerobot-raspberry-pi-zero-fpv-robot
- https://github.com/CoretechR/ZeroBot

Extended idea:
- http://www.mauroalfieri.it/elettronica/zerobot-rpi-zero-w-model.html

Shopping list:
- [Raspberry Pi Zero W](https://www.amazon.it/Raspberry-Pi-Zero-Starter-Kit/dp/B072LWBL37/)
- [Raspberry Camera Module](https://www.amazon.it/Raspberry-Official-Camera-Module-8Mp/dp/B01ER2SKFS/)
- [Dual DC Motor Driver](https://www.amazon.it/L298N-Bridge-Stepper-Controller-Arduino/dp/B013QTC18K/)
- [DFRobot Devastator Tank](https://www.amazon.it/DFRobot-Devastator-Tank-Mobile-Platform/dp/B014L1CF1K/) (do not have access to 3D printer)
- [Power Bank](https://www.amazon.it/EasyAcc-10000-BO-portatile-Smartphones-Arancione/dp/B00XTXY0JW/)

Software list:
- [Raspbian Lite](http://www.raspberrypi.org/downloads/raspbian/)
- [Node.js](http://nodejs.org/)
- [Express.js](http://expressjs.com)
- [Socket.io](http://socket.io/)
- [Pi-Gpio](http://github.com/fivdi/pigpio)
- [MultiTouch](http://seb.ly/2011/04/multi-touch-game-controller-in-javascripthtml5-for-ipad/)
- [MJpg-Streamer](http://github.com/jacksonliam/mjpg-streamer) to be replaced by [UV4L](http://www.linux-projects.org/uv4l/)

## Installation

### Raspberry Pi Zero W WiFi Client and Access Point Configuration
[Here](https://raspberrypi.stackexchange.com/questions/63841/rpi-zero-w-as-both-wifi-client-and-access-point/64172)
[Here](http://imti.co/post/145442415333/raspberry-pi-3-wifi-station-ap)

## License
This project is licensed under the terms of the MIT license.

repository: ramael/ZeroBot

gha_language: HTML

repo_name: ramael/ZeroBot


text:
# Orchestration > Manage swarm service network

[Back](./ReadMe.md)

A Docker swarm generates two different kinds of traffic:

* Control and management plane traffic: This includes swarm management messages, such as requests to join or leave the swarm. This traffic is always encrypted.
* Application data plane traffic: This includes container traffic and traffic to and from external clients.

The following three network concepts are important to swarm services::

* Overlay networks manage communications among the Docker daemons participating in the swarm. You can create overlay networks, in the same way as user-defined networks for standalone containers. You can attach a service to one or more existing overlay networks as well, to enable service-to-service communication. Overlay networks are Docker networks that use the overlay network driver.

* The ingress network is a special overlay network that facilitates load balancing among a service’s nodes. When any swarm node receives a request on a published port, it hands that request off to a module called IPVS. IPVS keeps track of all the IP addresses participating in that service, selects one of them, and routes the request to it, over the ingress network.

The ingress network is created automatically when you initialize or join a swarm. Most users do not need to customize its configuration, but Docker 17.05 and higher allows you to do so.

* The docker_gwbridge is a bridge network that connects the overlay networks (including the ingress network) to an individual Docker daemon’s physical network. By default, each container a service is running is connected to its local Docker daemon host’s docker_gwbridge network.

The docker_gwbridge network is created automatically when you initialize or join a swarm. Most users do not need to customize its configuration, but Docker allows you to do so.

## Firewall considerations

Docker daemons participating in a swarm need the ability to communicate with each other over the following ports:

* Port 7946 TCP/UDP for container network discovery.
* Port 4789 UDP for the container overlay network.

## Create an overlay network
To create an overlay network, specify the overlay driver when using the docker network create command:

```
docker network create \
  --driver overlay \
  my-network
```

You can see information about the network using:
```
docker network inspect
```

```
$ docker network inspect my-network
[
    {
        "Name": "my-network",
        "Id": "fsf1dmx3i9q75an49z36jycxd",
        "Created": "0001-01-01T00:00:00Z",
        "Scope": "swarm",
        "Driver": "overlay",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": []
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "Containers": null,
        "Options": {
            "com.docker.network.driver.overlay.vxlanid_list": "4097"
        },
        "Labels": null
    }
]
```

In the above output, notice that the driver is overlay and that the scope is swarm, rather than local, host, or global scopes you might see in other types of Docker networks. This scope indicates that only hosts which are participating in the swarm can access this network.

The network’s subnet and gateway are dynamically configured when a service connects to the network for the first time. The following example shows the same network as above, but with three containers of a redis service connected to it.

```
$ docker network inspect my-network
[
    {
        "Name": "my-network",
        "Id": "fsf1dmx3i9q75an49z36jycxd",
        "Created": "2017-05-31T18:35:58.877628262Z",
        "Scope": "swarm",
        "Driver": "overlay",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "<IP_ADDRESS>/24",
                    "Gateway": "<IP_ADDRESS>"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "Containers": {
            "0e08442918814c2275c31321f877a47569ba3447498db10e25d234e47773756d": {
                "Name": "my-redis.1.ka6oo5cfmxbe6mq8qat2djgyj",
                "EndpointID": "950ce63a3ace13fe7ef40724afbdb297a50642b6d47f83a5ca8636d44039e1dd",
                "MacAddress": "02:42:0a:00:00:03",
                "IPv4Address": "<IP_ADDRESS>/24",
                "IPv6Address": ""
            },
            "88d55505c2a02632c1e0e42930bcde7e2fa6e3cce074507908dc4b827016b833": {
                "Name": "my-redis.2.s7vlybipal9xlmjfqnt6qwz5e",
                "EndpointID": "dd822cb68bcd4ae172e29c321ced70b731b9994eee5a4ad1d807d9ae80ecc365",
                "MacAddress": "02:42:0a:00:00:05",
                "IPv4Address": "<IP_ADDRESS>/24",
                "IPv6Address": ""
            },
            "9ed165407384f1276e5cfb0e065e7914adbf2658794fd861cfb9b991eddca754": {
                "Name": "my-redis.3.hbz3uk3hi5gb61xhxol27hl7d",
                "EndpointID": "f62c686a34c9f4d70a47b869576c37dffe5200732e1dd6609b488581634cf5d2",
                "MacAddress": "02:42:0a:00:00:04",
                "IPv4Address": "<IP_ADDRESS>/24",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.driver.overlay.vxlanid_list": "4097"
        },
        "Labels": {},
        "Peers": [
            {
                "Name": "moby-e57c567e25e2",
                "IP": "<IP_ADDRESS>"
            }
        ]
    }
]
```

## Customize an overlay network
There may be situations where you don’t want to use the default configuration for an overlay network. For a full list of configurable options, run the command docker network create --help. The following are some of the most common options to change.

### CONFIGURE THE SUBNET AND GATEWAY

By default, the network’s subnet and gateway are configured automatically when the first service is connected to the network. You can configure these when creating a network using the --subnet and --gateway flags. The following example extends the previous one by configuring the subnet and gateway.

```
docker network create \
  --driver overlay \
  --subnet <IP_ADDRESS>/24 \
  --gateway <IP_ADDRESS> \
  my-network
```

### Overlay network size limitations

You should create overlay networks with /24 blocks (the default), which limits you to 256 IP addresses, when you create networks using the default VIP-based endpoint-mode. This recommendation addresses limitations with swarm mode. If you need more than 256 IP addresses, do not increase the IP block size. You can either use dnsrr endpoint mode with an external load balancer, or use multiple smaller overlay networks. See Configure service discovery for more information about different endpoint modes.

### CONFIGURE ENCRYPTION OF APPLICATION DATA

Management and control plane data related to a swarm is always encrypted. For more details about the encryption mechanisms, see the [Docker swarm mode overlay network security model](https://docs.docker.com/v17.09/engine/userguide/networking/overlay-security-model/).

Application data among swarm nodes is not encrypted by default. To encrypt this traffic on a given overlay network, use the --opt encrypted flag on docker network create. This enables IPSEC encryption at the level of the vxlan. This encryption imposes a non-negligible performance penalty, so you should test this option before using it in production.

### Attach a service to an overlay network
To attach a service to an existing overlay network, pass the --network flag to docker service create, or the --network-add flag to docker service update.

```
docker service create \
  --replicas 3 \
  --name my-web \
  --network my-network \
  nginx
```

Service containers connected to an overlay network can communicate with each other across it.

To see which networks a service is connected to, use
```
docker service ls
```
to find the name of the service, then
```
docker service ps <service-name>
```
to list the networks. Alternately, to see which services’ containers are connected to a network, use
```
docker network inspect <network-name>
```

You can run these commands from any swarm node which is joined to the swarm and is in a running state.

## Configure service discovery
Service discovery is the mechanism Docker uses to route a request from your service’s external clients to an individual swarm node, without the client needing to know how many nodes are participating in the service or their IP addresses or ports. You don’t need to publish ports which are used between services on the same network. For instance, if you have a WordPress service that stores its data in a MySQL service, and they are connected to the same overlay network, you do not need to publish the MySQL port to the client, only the WordPress HTTP port.

Service discovery can work in two different ways: internal connection-based load-balancing at Layers 3 and 4 using the embedded DNS and a virtual IP (VIP), or external and customized request-based load-balancing at Layer 7 using DNS round robin (DNSRR). You can configure this per service.

* By default, when you attach a service to a network and that service publishes one or more ports, Docker assigns the service a virtual IP (VIP), which is the “front end” for clients to reach the service. Docker keeps a list of all worker nodes in the service, and routes requests between the client and one of the nodes. Each request from the client might be routed to a different node.

* If you configure a service to use DNS round-robin (DNSRR) service discovery, there is not a single virtual IP. Instead, Docker sets up DNS entries for the service such that a DNS query for the service name returns a list of IP addresses, and the client connects directly to one of these.

* DNS round-robin is useful in cases where you want to use your own load balancer, such as HAProxy. To configure a service to use DNSRR, use the flag --endpoint-mode dnsrr when creating a new service or updating an existing one.

## Customize the ingress network
Most users never need to configure the ingress network, but Docker 17.05 and higher allow you to do so. This can be useful if the automatically-chosen subnet conflicts with one that already exists on your network, or you need to customize other low-level network settings such as the MTU.

Customizing the ingress network involves removing and recreating it. This is usually done before you create any services in the swarm. If you have existing services which publish ports, those services need to be removed before you can remove the ingress network.

During the time that no ingress network exists, existing services which do not publish ports will continue to function but are not load-balanced. This affects services which publish ports, such as a WordPress service which publishes port 80.

* Inspect the ingress network using docker network inspect ingress, and remove any services whose containers are connected to it. These are services that publish ports, such as a WordPress service which publishes port 80. If all such services are not stopped, the next step will fail.

* Remove the existing ingress network
```
docker network rm ingress

WARNING! Before removing the routing-mesh network, make sure all the nodes
in your swarm run the same docker engine version. Otherwise, removal may not
be effective and functionality of newly create ingress networks will be
impaired.
Are you sure you want to continue? [y/N]
```

* Create a new overlay network using the --ingress flag, along with the custom options you want to set. This example sets the MTU to 1200, sets the subnet to <IP_ADDRESS>/16, and sets the gateway to <IP_ADDRESS>.

```
docker network create \
  --driver overlay \
  --ingress \
  --subnet=<IP_ADDRESS>/16 \
  --gateway=<IP_ADDRESS> \
  --opt com.docker.network.mtu=1200 \
  my-ingress
```

* start the services that you stopped in the first step

## Customize the docker_gwbridge
The docker_gwbridge is a virtual bridge that connects the overlay networks (including the ingress network) to an individual Docker daemon’s physical network. Docker creates it automatically when you initialize a swarm or join a Docker host to a swarm, but it is not a Docker device. It exists in the kernel of the Docker host. If you need to customize its settings, you must do so before joining the Docker host to the swarm, or after temporarily removing the host from the swarm.

You need to have the brctl application installed on your operating system in order to delete an existing bridge. The package name is bridge-utils.

1. Stop Docker.
2. Use the brctl show docker_gwbridge command to check whether a bridge device exists called docker_gwbridge. If so, remove it using brctl delbr docker_gwbridge.
3. Start Docker. Do not join or initialize the swarm
4. Create or re-create the docker_gwbridge bridge with your custom settings. This example uses the subnet <IP_ADDRESS>/16. For a full list of customizable options, see Bridge driver options.
```
docker network create \
--subnet <IP_ADDRESS>/16 \
--opt com.docker.network.bridge.name=docker_gwbridge \
--opt com.docker.network.bridge.enable_icc=false \
--opt com.docker.network.bridge.enable_ip_masquerade=true \
docker_gwbridge
```
5. Initialize or join the swarm

## Use a separate interface for control and data traffic
By default, all swarm traffic is sent over the same interface, including control and management traffic for maintaining the swarm itself and data traffic to and from the service containers.

In Docker 17.06 and higher, it is possible to separate this traffic by passing the --data-path-addr flag when initializing or joining the swarm. If there are multiple interfaces, --advertise-addr must be specified explicitly, and --data-path-addr defaults to --advertise-addr if not specified. Traffic about joining, leaving, and managing the swarm will be sent over the --advertise-addr interface, and traffic among a service’s containers will be sent over the --data-path-addr interface. These flags can take an IP address or a network device name, such as eth0.

This example initializes a swarm with a separate --data-path-addr. It assumes that your Docker host has two different network interfaces: <IP_ADDRESS> should be used for control and management traffic and <IP_ADDRESS> should be used for traffic relating to services.

```
docker swarm init --advertise-addr <IP_ADDRESS> --data-path-addr <IP_ADDRESS>
```

This example joins the swarm managed by host <IP_ADDRESS>:2377 and sets the --advertise-addr flag to eth0 and the --data-path-addr flag to eth1.

```
docker swarm join \
  --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2d7c \
  --advertise-addr eth0 \
  --data-path-addr eth1 \
  <IP_ADDRESS>:2377
```

repository: giulianoquites/docker-certification

path: /01 Orchestration/networking.md

repo_name: giulianoquites/docker-certification


text:
# PunKt - Kotlin Punk
![Bintray](https://img.shields.io/bintray/v/punkt/punkt/punkt)
![GitHub Workflow Status](https://img.shields.io/github/workflow/status/pjagielski/punkt/CI)

A live coding music library/environment for Kotlin. For software developers who want to dive into live coding music.

"Punkt" is "point" in Polish.

[![Punkt demo](screen.png)](https://youtu.be/94xzNW6hxR8?t=120)

Demos:
* [Shape Of You Remix](https://youtu.be/TBDG_34yKys?t=182)
* [Da Funk Remix](https://youtu.be/OdQQJPpL6Lo?t=136)
* [Shape Of You inspired track](https://youtu.be/94xzNW6hxR8?t=80)

## Rationale
* **minimal** - just a sequencer playing samples and synths designed in SuperCollider
* **easy to install** - a library + template project, just `git clone`, run and enjoy
* **no custom IDE** - could be started directly from IntelliJ IDEA or command line with any Kotlin-aware editor
* **data-oriented** - patterns and melodies represented as data structure, making it easy to test and visualize

### How to start
0. Install [SuperCollider](https://supercollider.github.io/download) (at least 3.10) and [sc3-plugins](https://supercollider.github.io/sc3-plugins/)
1. Clone [template project](https://github.com/pjagielski/punkt-template) `git clone https://github.com/pjagielski/punkt-template.git`
2. Start SuperCollider, boot server (Server->Boot Server) and run [punkt-synths.scd](https://raw.githubusercontent.com/pjagielski/punkt/master/src/main/resources/punkt-synths.scd)
(in case of "Memory allocation problems": clone [punkt project](https://github.com/pjagielski/punkt) and run `src/main/resources/punkt.scd` in SuperCollider.)
3. Run `Main.kt` in `punkt-template`
4. Profit! Just edit `src/main/kotlin/live.kts` in your favourite editor for live-coding

### Why Kotlin?
* **statically typed, compiled** - you get code completion and compile-time errors for free
* **sequence API** - great standard library with lazy immutable sequences for making patterns
* **DSL builders** - extension methods and operator overloading makes it easy to create powerful DSLs
* **scripting** - a file watcher and API for compiling/evaluating script whenever it changes
* **coroutines** - makes trivial to trigger an asynchronous event from anywhere in your code
* **mainstream** - it's great to learn Clojure or Haskell, but it's even better that your project uses technology that reaches lots of potential users ;)

### Minimal example

```kotlin
    patterns(beats = 8) {
        + repeat(1).sample("bd_haus")
    }
```
Plays "bd_haus" sample every beat.

What happened here? `punkt` highly relies on durations to create patterns. If we want to play "bd_haus" sample every
beat, we could specify this by a list of beats, like `listOf(0, 1, 2, 3, ...)`. We could use `rangeTo` function (e.g. `0..7`) to
create a fixed range of beats. In `punkt` instead, you specify the durations *between* the beats, and a
*starting point* - which defaults to 0 by this `repeat` function (which is not `repeat` from Kotlin standard library).
This has some advantages:
 1. in simple cases, you repeat single value or cycle through small series of values
 2. this creates infinite sequence of beats, which is helpful if you don't know upfront how many beats you need ;)
 that's why we need to narrow the resulting collection to fixes number of beats with this `patterns(beats = 8) {..}`
 function.

 Another example: 4 on the floor beat:
 ```kotlin
     patterns(beats = 8) {
         + repeat(1).sample("bd_haus") // every beat starting from 0
         + repeat(2).sample("claps", at = 1.0) // every even beat, starting from 1
         + repeat(1).sample("hat_2", at = 0.5, amp = 0.5f) // every beat, starting from 0.5
     }
 ```
Evaluates to:

| sample    | played at beats               |
|-----------|-------------------------------|
| "bd_haus" | [0,1,2,3,4,5,6,7]             |
| "claps"   | [1,3,5,7]                     |
| "hat_2"   | [0.5,1.5,2.5,3.5,4.5,5.5,6.5] |

### Melody phrases
`punkt` also uses similar technique to create melodies. But melodies, apart from time when the sound should play,
require a note (pitch), which should play. To make it more musically correct, these notes should be part
of some musical scale. That's why we start by creating a `scale` object using DSL from `scale` package:

```kotlin
    val scale = Scale(C.sharp(), minor)
```
*The notes of C# minor are: C#,D#,E,F#,G#,A,B (https://en.wikipedia.org/wiki/C-sharp_minor)*

Then we can use `phrase` function, which takes sequence of degrees of given scale and sequence of durations to create a melody:
```kotlin
    patterns(beats = 8) {
        + scale.low()
            .phrase(
                degrees(listOf(0,-4,-2,-1).flatMap { listOf(it,it,it) }),
                cycle(0.75, 0.75, 0.5))
            .synth("tr808", amp = 0.2f)
    }
```
This creates following notes:

| beats        | note | degree |
|--------------|------|--------|
| 0, 0.75, 1.5 | C#   |     0  |
| 2, 2.75, 3.5 | F#   |    -4  |
| 4, 4.75, 5.5 | A    |    -2  |
| 6, 6.75, 7.5 | B    |    -1  |

Which is the "Shape of you" bassline ;)

### More examples
TB-303 pentatonic arpeggio with LFO
```kotlin
    val pentatonic = Scale(C.sharp(), pentatonic)
    val lfo = LFO(1000, 3200, length = 1.5)

    patterns(beats = 8) {
        + pentatonic.low()
            .phrase(degrees(cycle(cycle((0..4)).take(10).toList())), cycle(0.25))
            .synth("tb303", amp = 0.2f)
            .params("sus" to 0.3, "dec" to 0.2, "start" to 100)
            .params("cutoff" to lfo)
    }
```

4-step chord progression with lead synth
```kotlin
    val scale = Scale(C.sharp(), minor)
    val progression = listOf(Chord.I, Chord.IV, Chord.VI, Chord.VII)

    patterns(beats = 8) {
        + scale
            .phrase(
                progression.flatMap { listOf(it, null, it) }.toDegrees(),
                cycle(1.0, 0.25, 0.75)
            )
            .synth("lead", amp = 0.25f)
            .params("cutoff" to 1500)
    }
```

### Inspirations
* **[ORCΛ](https://github.com/hundredrabbits/Orca)** - simplicity (just a sequencer)
* **[openRNDR](https://github.com/openrndr/openrndr)** - kotlin script-driven live coding
* **[Leipzig](https://github.com/ctford/leipzig)** - music as data
* **[FoxDot](https://github.com/Qirky/FoxDot)** - synth design, OSC implementation
* **[Tidal](https://github.com/tidalcycles/Tidal)** - patterns, SuperDirt
* **[Sonic-Pi](https://github.com/samaaron/sonic-pi)** - live loops, script-driven live coding

### Changelog

### 0.3.0 - 09.09.2020
* introduced separate tracks with global effects
* new global effects: `reverb`, `delay`, `djf`
* new effects: `djf`, `waveDist`, `squiz`
* new synths: `piano`, `bass8`
* new note methods: `amp`, `track`
* fluent API for effects

#### 0.2.0 - 17.05.2020
* introduced effects
* new effects: `lpf`, `hpf`, `delay`, `dist`, `chop`
* new synth: `lead`
* **BREAKING**: synth params API cleanup
* events logging

#### 0.1.0 - 20.04.2020
* initial version ;)
* `sample` and `loop` support
* new synths: `tb303`, `tr808`, `plucklead`, `da-funk`

### Roadmap
* OSC/MIDI out
* OSC/MIDI in
* ~~add effects on separate channels~~ (0.3.0)
* pattern randomization
* visualization

### License
Copyright © 2020- Piotr Jagielski

Punkt is licensed under the Apache License, Version 2.0. See LICENSE for the full license text.

repository: MarcinMoskala/punkt

repo_name: MarcinMoskala/punkt


text:
# Before/After Hooks Example

This example demonstrates how to run common code before or after executing any
command.

This example was generated with:

```bash
$ bashly init
# ... now edit src/bashly.yml to match the example ...
$ bashly add hooks
$ bashly generate
```

-----

## `bashly.yml`

````yaml
name: hooks
help: Sample application that uses before/after hooks
version: 0.1.0

flags:
- long: --debug
  short: -d
  help: Enable debug mode
````

## Output

### `$ ./hooks`

````shell
==[ Before Hook Called ]==
args: none
# this file is located in 'src/root_command.sh'
# you can edit it freely and regenerate (it will not be overwritten)
args: none
==[ After Hook Called ]==

````

### `$ ./hooks --debug`

````shell
==[ Before Hook Called ]==
args:
- ${args[--debug]} = 1
# this file is located in 'src/root_command.sh'
# you can edit it freely and regenerate (it will not be overwritten)
args:
- ${args[--debug]} = 1
==[ After Hook Called ]==

````

repository: DannyBen/bashly

gha_language: Ruby

repo_name: DannyBen/bashly


text:
# Blueprint examples for DICE deployment tool

This repository contains various working examples of OASIS TOSCA
blueprints. To test and run them, use the [DICE Deployment Service][dds].

[dds]: https://github.com/dice-project/DICE-Deployment-Service

# Deploying samples

In this section, we get our hands dirty and demonstrate how to deploy
different kinds of blueprints. We will assume that `dice-deploy-cli` tool is
in your search path. If this is not true, execute

    $ export PATH=/path/to/dice-tools:$PATH

This should take care of that. We will also assume that `dice-deploy-cli` is
already configured for usage. If not, execute

    $ dice-deploy-cli use ...
    $ dice-deploy-cli authenticate ...

You need to replace `...` with proper data. For more information on what data
commands expect, consult built-in help.

## Deploying standalone blueprints

Standalone blueprints have no bundled resources. Deploying such blueprints is
really easy, because all we need is blueprint YAML file.

Example of standalone blueprint would be `spark`. When we want to deploy it,
we execute

    $ dice-deploy-cli create "Apache Storm deployment"
    $ dice-deploy-cli deploy UUID storm/storm.yaml

Replace UUID placeholder in second command with output of the first command.

## Deploying blueprint with bundled resources

Deploying such blueprints is a bit more complicated, because we need to
prepare gzipped tarball that contains blueprint and resources. We will
demonstrate steps that are needed to deploy such blueprint on `script`
example.

First, we will move ourselves to `script`folder and then create new temporary
folder that will hold contents of tarball.

    $ cd script
    $ TMP_FOLDER=$(mktemp -d)
    $ chmod 755 $TMP_FOLDER
    $ echo $TMP_FOLDER
    /tmp/tmp.M5XxPuDt4M

Next, we will copy the YAML file and all resources that blueprint references
to this temporary folder, making sure that we place all resources into proper
subfolders to make sure paths, that are used in blueprint, can be resolved
relative to blueprint location. Note that YAML file that contains main
blueprint, needs to be named `blueprint.yaml` in order for DICE Deployment
Service to know where to start.

    $ cp script.yaml $TMP_FOLDER/blueprint.yaml
    $ cp -r resources $TMP_FOLDER

The layout should look something like this:

    $ tree $TMP_FOLDER
    /tmp/tmp.M5XxPuDt4M
    ├── blueprint.yaml
    └── resources
        └── test-script.sh

Now, we need to create tarball.

    $ tar -cvzf blueprint.tar.gz \
          -C $(dirname $TMP_FOLDER) $(basename $TMP_FOLDER)
    tmp.M5XxPuDt4M/
    tmp.M5XxPuDt4M/scripts/
    tmp.M5XxPuDt4M/scripts/test-script.sh
    tmp.M5XxPuDt4M/blueprint.yaml

After all this is done, we can remove temporary folder and upload the tarball
exactly the same way that we uploaded standalone blueprint.

    $ rm -rf $TMP_FOLDER
    $ unset TMP_FOLDER
    $ dice-deploy-cli create "Bash script test"
    $ dice-deploy-cli deploy UUID blueprint.tar.gz

And finally, we clean after ourselves.

    $ rm blueprint.tar.gz

Example `script` folder already contains `create-tar.sh` script that performs
tarball creation. Simply run it and then perform deploy as described above.

# Acknowledgement

This work is a result of the [DICE] project, which has received funding from
the [European Union’s Horizon 2020][H2020] research and innovation programme
under grant agreement No. 644869.

[DICE]: http://dice-h2020.eu/
[H2020]: http://ec.europa.eu/programmes/horizon2020/

repository: dice-project/DICE-Deployment-Examples

repo_name: dice-project/DICE-Deployment-Examples


text:
Examples
========

1. EC2 instance with no ELB or ASG

  This configuration would be suitable for a db cluster

```
  - name: 'mongodb'
    instance:
      type: 'm3.medium'
      volumes:
        - encrypted: true
          volume_type: 'io1'
          volume_size: 50
          iops: 100
          device_name: '/dev/sdh'
          delete_on_termination: True
      count: 3
    sg: "{{ shared_security_groups + ['mongodb-client-' + opg_data.stack, 'mongodb-server-' + opg_data.stack] }}"
    server_sg:
      name: 'mongodb-server-{{ opg_data.stack }}'
      desc: 'mongodb server access'
      client_sg: "mongodb-client"
      ruleset:
        - proto: 'tcp'
          ports: '27017'
```

2. Scaling group with ELB

```
  - name: simple-node
    asg:
      instance_type: 't2.small'
      min: 1
      max: 1
      desired: 1
      subnets: "{{ private_subnets }}"
      sg: "{{ shared_security_groups }}"
```

3. Node with Scaling Group and ELB

```
  - name: full-example
    asg:
      instance_type: 't2.small'
      min: 1
      max: 1
      desired: 1
      subnets: "{{ private_subnets }}"
      sg: "{{ shared_security_groups + ['example-' + opg_data.stack, 'mongodb-client-' + opg_data.stack] }}"
      asg_sg:
        name: 'full-example' #Stack name is appended automatically at run time
        desc: 'full-example server access'
        client_sg: "full-example-elb"
        ruleset:
          - proto: 'tcp'
            ports: '443'
      scaling_policies:
        - name: scale_up
          adjustment_type: "Percent"
          min_adjustment_step: +1
          scaling_adjustment: 100
          cooldown: 180
          metric_alarms:
            - metric: "CPUUtilization"
              comparison: ">="
              threshold: 40
              statistic: "Average"
              period: 60
              evaluations: 3
              unit: Percent
        - name: scale_down
          adjustment_type: "Percent"
          min_adjustment_step: -1
          scaling_adjustment: 50
          cooldown: 300
          metric_alarms:
            - metric: "CPUUtilization"
              comparison: "<="
              threshold: 15
              statistic: "Average"
              period: 60
              evaluations: 5
              unit: Percent

    elb:
      subnets: "{{ private_subnets }}"
      private_dns: "full-example.{{ opg_data.stack }}"
      type: internal
      listeners:
        - protocol: https
          load_balancer_port: 443
          instance_port: 443
          ssl_certificate_id: "{{ vpc.ssl_cert_id }}"
          proxy_protocol: True
      health_check:
        ping_protocol: tcp
        ping_port: 443
        response_timeout: 5
        interval: 30
        unhealthy_threshold: 2
        healthy_threshold: 2
      sg:
        - "shared-services-{{ vpc_name }}"
        - "full-example-elb-{{ opg_data.stack }}"
      elb_sg:
        name: 'full-example-elb-{{ opg_data.stack }}'
        desc: 'full-example elb access'
        client_sg: "full-example-client"
        ruleset:
          - proto: 'tcp'
            ports: '443'
```

repository: ministryofjustice/opg-ansible-roles

gha_language: Python

repo_name: ministryofjustice/opg-ansible-roles


text:
# Pulse SMS for Franz
This is the Franz 5 Recipe for Pulse SMS

### For further informtion on Pulse SMS:
* [Visit the website](https://messenger.klinkerapps.com/overview/)

### How to create your own Franz recipes:
* [Read the documentation](https://github.com/meetfranz/plugins)

repository: KrisBataican/recipes

repo_name: KrisBataican/recipes


text:
runrightfast-sandbox
====================

Sandbox project used for experimentation and POC purposes

Project Structure:
==================
/node_modules
 - standard location where local npm modules are installed

/out
 - where output files are placed when running grunt tasks

/server
 - contains all server side code

/server/lib
 - contains server specific library modules

/server/routes
 - contains modules that define hapi routes
 - the routes files should reference handlers that are defined within modules - either in /server/lib or /node_modules

/test
 - contains test code

/routes.js
 - aggregates all routes that will be registered with hapi

/server.js
 - configures and starts up a hapi server


text:
---
title: "Terms and Privacy Policy"
permalink: /terms/
modified: 2016-11-03T11:57:46-04:00
redirect_from:
  - /license/
---

{% include toc %}

### Cookies and Web Beacons

When you visit this site "convenience" cookies are stored on your computer when you submit a comment to help you log in faster to [Disqus](https://disqus.com) the next time you leave a comment.

Third-party advertisers may also place and read cookies on your browser and/or use web beacons to collect information. This site has no access or control over these cookies. You should review the respective privacy policies on any and all third-party ad servers for more information regarding their practices and how to opt-out.

If you wish to disable cookies, you may do so through your web browser options. Instructions for doing so can be found on the specific web browsers' websites.

#### Google Analytics

Google Analytics is a web analytics tool I use to help understand how visitors engage with this website. It reports website trends using cookies and web beacons without identifying individual visitors. You can read [Google Analytics Privacy Policy](https://www.google.com/analytics/learn/privacy.html).

#### Google Adsense

Google Adsense, a third party affiliate marketing network, uses cookies to help make sure I get a commission when you buy a product after clicking on a link or ad banner that takes you to the site of one of their merchants. You can read [Google Adsense Privacy Policy](https://support.google.com/adsense/bin/answer.py?hl=en&answer=48182).