text:
# HTML & Forms

REST framework is suitable for returning both API style responses, and regular HTML pages. Additionally, serializers can be used as HTML forms and rendered in templates.

## Rendering HTML

In order to return HTML responses you'll need to use either `TemplateHTMLRenderer`, or `StaticHTMLRenderer`.

The `TemplateHTMLRenderer` class expects the response to contain a dictionary of context data, and renders an HTML page based on a template that must be specified either in the view or on the response.

The `StaticHTMLRender` class expects the response to contain a string of the pre-rendered HTML content.

Because static HTML pages typically have different behavior from API responses you'll probably need to write any HTML views explicitly, rather than relying on the built-in generic views.

Here's an example of a view that returns a list of "Profile" instances, rendered in an HTML template:

**views.py**:

    from my_project.example.models import Profile
    from rest_framework.renderers import TemplateHTMLRenderer
    from rest_framework.response import Response
    from rest_framework.views import APIView

    class ProfileList(APIView):
        renderer_classes = [TemplateHTMLRenderer]
        template_name = 'profile_list.html'

        def get(self, request):
            queryset = Profile.objects.all()
            return Response({'profiles': queryset})

**profile_list.html**:

Profiles

        {% for profile in profiles %}

{{ profile.name }}

        {% endfor %}

## Rendering Forms

Serializers may be rendered as forms by using the `render_form` template tag, and including the serializer instance as context to the template.

The following view demonstrates an example of using a serializer in a template for viewing and updating a model instance:

**views.py**:

    from django.shortcuts import get_object_or_404
    from my_project.example.models import Profile
    from rest_framework.renderers import TemplateHTMLRenderer
    from rest_framework.views import APIView

    class ProfileDetail(APIView):
        renderer_classes = [TemplateHTMLRenderer]
        template_name = 'profile_detail.html'

        def get(self, request, pk):
            profile = get_object_or_404(Profile, pk=pk)
            serializer = ProfileSerializer(profile)
            return Response({'serializer': serializer, 'profile': profile})

        def post(self, request, pk):
            profile = get_object_or_404(Profile, pk=pk)
            serializer = ProfileSerializer(profile, data=request.data)
            if not serializer.is_valid():
                return Response({'serializer': serializer, 'profile': profile})
            serializer.save()
            return redirect('profile-list')

**profile_detail.html**:

    {% load rest_framework %}

Profile - {{ profile.name }}

    <form action="{% url 'profile-detail' pk=profile.pk %}" method="POST">
        {% csrf_token %}
        {% render_form serializer %}
        <input type="submit" value="Save">
    </form>

### Using template packs

The `render_form` tag takes an optional `template_pack` argument, that specifies which template directory should be used for rendering the form and form fields.

REST framework includes three built-in template packs, all based on Bootstrap 3. The built-in styles are `horizontal`, `vertical`, and `inline`. The default style is `horizontal`. To use any of these template packs you'll want to also include the Bootstrap 3 CSS.

The following HTML will link to a CDN hosted version of the Bootstrap 3 CSS:

        …
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">

Third party packages may include alternate template packs, by bundling a template directory containing the necessary form and field templates.

Let's take a look at how to render each of the three available template packs. For these examples we'll use a single serializer class to present a "Login" form.

    class LoginSerializer(serializers.Serializer):
        email = serializers.EmailField(
            max_length=100,
            style={'placeholder': 'Email', 'autofocus': True}
        )
        password = serializers.CharField(
            max_length=100,
            style={'input_type': 'password', 'placeholder': 'Password'}
        )
        remember_me = serializers.BooleanField()

---

#### `rest_framework/vertical`

Presents form labels above their corresponding control inputs, using the standard Bootstrap layout.

*This is the default template pack.*

    {% load rest_framework %}

    ...

    <form action="{% url 'login' %}" method="post" novalidate>
        {% csrf_token %}
        {% render_form serializer template_pack='rest_framework/vertical' %}
        <button type="submit" class="btn btn-default">Sign in</button>
    </form>

![Vertical form example](../img/vertical.png)

---

#### `rest_framework/horizontal`

Presents labels and controls alongside each other, using a 2/10 column split.

*This is the form style used in the browsable API and admin renderers.*

    {% load rest_framework %}

    ...

    <form class="form-horizontal" action="{% url 'login' %}" method="post" novalidate>
        {% csrf_token %}
        {% render_form serializer %}

                <button type="submit" class="btn btn-default">Sign in</button>

    </form>

![Horizontal form example](../img/horizontal.png)

---

#### `rest_framework/inline`

A compact form style that presents all the controls inline.

    {% load rest_framework %}

    ...

    <form class="form-inline" action="{% url 'login' %}" method="post" novalidate>
        {% csrf_token %}
        {% render_form serializer template_pack='rest_framework/inline' %}
        <button type="submit" class="btn btn-default">Sign in</button>
    </form>

![Inline form example](../img/inline.png)

## Field styles

Serializer fields can have their rendering style customized by using the `style` keyword argument. This argument is a dictionary of options that control the template and layout used.

The most common way to customize the field style is to use the `base_template` style keyword argument to select which template in the template pack should be use.

For example, to render a `CharField` as an HTML textarea rather than the default HTML input, you would use something like this:

    details = serializers.CharField(
        max_length=1000,
        style={'base_template': 'textarea.html'}
    )

If you instead want a field to be rendered using a custom template that is *not part of an included template pack*, you can instead use the `template` style option, to fully specify a template name:

    details = serializers.CharField(
        max_length=1000,
        style={'template': 'my-field-templates/custom-input.html'}
    )

Field templates can also use additional style properties, depending on their type. For example, the `textarea.html` template also accepts a `rows` property that can be used to affect the sizing of the control.

    details = serializers.CharField(
        max_length=1000,
        style={'base_template': 'textarea.html', 'rows': 10}
    )

The complete list of `base_template` options and their associated style options is listed below.

base_template          | Valid field types                                           | Additional style options
-----------------------|-------------------------------------------------------------|-----------------------------------------------
input.html             | Any string, numeric or date/time field                      | input_type, placeholder, hide_label, autofocus
textarea.html          | `CharField`                                                 | rows, placeholder, hide_label
select.html            | `ChoiceField` or relational field types                     | hide_label
radio.html             | `ChoiceField` or relational field types                     | inline, hide_label
select_multiple.html   | `MultipleChoiceField` or relational fields with `many=True` | hide_label
checkbox_multiple.html | `MultipleChoiceField` or relational fields with `many=True` | inline, hide_label
checkbox.html          | `BooleanField`                                              | hide_label
fieldset.html          | Nested serializer                                           | hide_label
list_fieldset.html     | `ListField` or nested serializer with `many=True`           | hide_label

gha_language: Python


text:
---
published: true
title: Atomic Number
tags: atomic cpu c++ java
---
> Traditional multi-threading approaches use locks to protect shared resources. Synchronization objects like Semaphores provide mechanisms for the programmer to write code that doesn't modify a shared resource concurrently. The synchronization approaches block other threads when one of the thread is modifying a shared resource. Obviously blocked threads are not doing meaningful work waiting for the lock to be released.
**Atomic operations on the contrast are based on non-blocking algorithms in which threads waiting for shared resources don't get postponed.** Atomic operations are implemented using hardware primitives like compare and swap (CAS) which are atomic instructions used in multi-threading for synchronization. - [SO](https://stackoverflow.com/questions/26816313/java-what-is-an-atomic-number/26817146#26817146)

## C++
- [std::atomic](https://en.cppreference.com/w/cpp/atomic/atomic)

## Others
- [java](https://stackoverflow.com/questions/26816313/java-what-is-an-atomic-number#26816340)

- [Number of protons](https://en.wikipedia.org/wiki/Atomic_number)

license: MIT

branch_name: refs/heads/master

extension: md

license_type: permissive


text:
# λοίδορος, ον.

<!-- Status: S3=Needs2ndReview -->
<!-- Lexica used for edits: BDAG, FFM, LN, A-S -->

## Word data

* Strongs: G30600.

* Alternate spellings:

* Principle Parts:

* Part of speech:

[Noun](http://ugg.readthedocs.io/en/latest/noun.html).

* Instances in the New Testament: 2.

* All Scriptures cited: Yes.

## Etymology:

* LXX/Hebrew glosses:

in LXX: [Prov 25:24](pro 25:24), [Prov 26:21](pro 26:21), [Prov 27:15](pro 27:15), ([מִדְיָן](//en-uhl/H4079)), [Sir 23:8](sir 23.8).

* Time Period/Ancient Authors:

* Related words:

* Antonyms for all senses:

* Synonyms for all senses:

## Senses:

### Sense  1.0:

#### Definition:

a person who talks abusively to other people or about other people, a person who slanders others with their words

#### Glosses:

slanderer, verbal abuser, abusive person

#### Explanation:

When used as a substantive λοίδορος means "a reviler," "slanderer," or "an abusive person." When a word functions as an adjective it is functioning like a noun in a sentence

#### Citations:

[1Cor 5:11](1co 5:11), [1Cor 6:10](1co 6:10).

repository: mandolyte/uw-obsidian

branch_name: refs/heads/main

repo_name: mandolyte/uw-obsidian


text:
---
layout: post
title: "Linear Algebra for Machine Learning - Notes"
excerpt: "Intro to Deep Learning - Linear Algebra"
tags: [Deep Learning, ML, Linear Algebra]
comments: true
---
At some point last year, I had taken some notes refresh minimal amounts of
linear algebra to dive into traditional ``Machine Learning``. Earlier this week,
I risked losing all my notes. No, it was not a backup that was deleted, it was
the main notes. Unforunately, I prefer taking physical notes which were on the
verge of being trashed. So, I have decided to embarass myself and post them
publicly until I get around to translating them into a traditional post.

## Raw Notes
### Part 1
![](/images/LinAlg1.jpg)

### Part 2
![](/images/LinAlg2.jpg)

### Part 3
![](/images/LinAlg3.jpg)

gha_language: JavaScript

gha_license_id: MIT


text:
# File-Organizer
A script that sorts files into folders.

## Why?
The main reason is to save your time. Instead of having to manually create folders and sort files, you can just create a mapping of folders and extensions and let this script do it for you.

## How?
The folders and extensions need to be mapped in a **JSON** file. The folders will be the keys, and the value will be a list of extensions.
* Example:
```json
{
    "Images": [
        ".jpg",
        ".png"
    ],
    "Documents": [
        ".txt",
        ".pdf"
    ],
    "Books": [
        ".epub",
        ".mobi"
    ]
}
```

This means the script will create a folder called **Images** and move all **.jpg** and **.png** file into it.
* Note: Files without extensions will not be moved. If you want to move them, add an entry into your **JSON** file.
```json
{
    "Images": [
        ".jpg",
        ".png"
    ],
    "Documents": [
        ".txt",
        ".pdf"
    ],
    "Books": [
        ".epub",
        ".mobi"
    ],
    "Others": [
        ""
    ]
}
```
* Note 2: In Linux, files don't need to have an extension. This means the chosen folder can contain Appimages, Executables, Text files and etc.

## Dependencies
You only need to install PySide2. It is used to show the directory dialog.
```bash
pip install pyside2
```

## Usage
1. Clone the repository
```sh
git clone https://github.com/lucasc-silva/File-Organizer.git
```

2. Go to the repository folder.
```sh
cd File-Organizer/
```

3. Edit **mapping.json** to fit your needs. This is the default one:
```json
{
    "Images": [
        ".png",
        ".jpg"
    ],
    "Documents": [
        ".txt",
        ".pdf"
    ],
    "Books": [
        ".epub",
        ".mobi"
    ],
    "Executables": [
        ".exe"
    ],
    "Videos": [
        ".mp4",
        ".mkv"
    ],
    "Music": [
        ".mp3"
    ]
}
```

4. Run the script.
```sh
python3 src/main.py
```
* When you run the program, a directory dialog will appear, allowing you to choose a directory to sort.

## Preview
![Gif showing how the script works](file-organizer.gif)
* Note: Files are only moved if their extensions are in **mapping.json**

repository: lucasshiva/File-Organizer

repo_name: lucasshiva/File-Organizer


text:
---
title: "Debugging SwiftUI: Trials and Tribulations"
date: 2020-10-30T12:00+01:00
category: programming
audience: people interested SwiftUI or UI programming in general
tags:
  - Swift
  - SwiftUI
draft: false
---

I have been using [SwiftUI](https://developer.apple.com/xcode/swiftui/) since day one, on both client and side projects. It's an incredibly refreshing way of coding interfaces for Apple devices, but it's far from being wrinkle-free. The framework's bold ambitions are sometimes hampered by subpar debugging tools and arcane, seemingly random limitations.

I previously [wrote](https://redalemeden.com/blog/2020/this-week-i-learned-24#programming) about a SwiftUI bug that gave me quite a run for my money:

> The stack trace isn’t of much help and no amount of view hierarchy tweaks got rid of it entirely. Initially I was under the impression that either my code or one of my external dependencies were doing something horribly wrong, but [this post](https://steipete.com/posts/state-of-swiftui/) from Peter Steinberger made me realize that it is a rather widespread issue.

Since I didn’t manage to reproduce it on a particular test device at the time, I assumed it’s yet another simulator quirk.  Fun times!

The app in question uses tab navigation where the first tab is always accessible, while the second tab shows different content depending on whether the user is signed in to their account or not. The view code looked roughly like this:

```swift
TabView {
  Home()
    .tabItem { /* ... */ }
    .tag { /* ... */ }

  if isSignedIn {
    Profile()
      .tabItem { /* ... */ }
      .tag { /* ... */ }
  } else {
    SignIn()
      .tabItem { /* ... */ }
      .tag { /* ... */ }
  }
}
```

To avoid the `isSignedIn` boolean check in multiple modifiers, I opted for an `if-else` block with separate views and `tabItem` modifiers.[^1] Except that didn’t seem to sit right with SwiftUI for some reason. The app launches and displays the content of the first tab exactly as intended. But when I switch tabs—or god forbid, sign in or out—the app crashes with this cryptic error message:

```
[error] precondition failure: invalid size for indirect attribute: <number> vs <number>
```

The call stack points exclusively to SwiftUI internals, with the last call referring to a certain `AG::Graph`—[responsible](https://steipete.com/posts/state-of-swiftui/#swiftui-attributegraph-crashes) for holding the view tree and diffing it. As far as debugging goes, this is very, *very* little to work with.

With my hands tied, I briefly considered resurrecting the `UITabBarController` wrapper I used prior to WWDC, especially since I didn’t manage to make a reproducible test case or submit a feedback to Apple. At first, I spent an inordinate amount of time tweaking the view hierarchies of the profile and sign-in screens themselves, with varying—and rather inconsistent—levels of success. I ran out of both time and patience, so I moved on to other things to not stall the project any further. Weeks later, I came back to the problematic screen—pitchfork in hand—ready to gut the entire tab navigation and replace it with a custom-made solution. I had had enough.

But then came the proverbial aha moment: what if the conditional check took place *inside* the second tab, instead of *around* it?

```swift
TabView {
  Home()
    .tabItem { /* ... */ }
    .tag { /* ... */ }

  ProfileOrSignIn(isSignedIn: $isSignedIn)
    .tabItem { /* ... */ }
    .tag { /* ... */ }
}
```

And *just* like that, the crasher was gone. Squashed into oblivion.

If this sounds dumb, it’s because it is. At no point did the compiler chastise me for doing something I wasn't supposed to do. And to make matters worse, the documentation doesn't mention anything related to... wait, what documentation?

It’s a bittersweet feeling when you fix a bug in a non-deterministic, haphazard way. On one hand you are elated you’ve managed to fix it at all. On the other, you feel somewhat powerless and insecure about your ability to handle similar situations in the future. I adore SwiftUI, but moments like these give me a good dose of anticipatory anxiety—the kind that erodes trust and dampen the thrill of being at the bleeding edge.

[^1]: As an aside, apps that greet users with a sign up screen are generally trash. You don't ask prospective tenants to sign the contract at the door before they've even seen the apartment.


text:
---
title: Initial Setup for Enablement
seo-title: Initial Setup
description: Initial Setup for Enablement
seo-description: Initial Setup for Enablement
uuid: 873ec41d-c088-41d9-a535-de5300661de6
contentOwner: Janice Kendall
products: SG_EXPERIENCEMANAGER/6.4/COMMUNITIES
topic-tags: introduction
content-type: reference
discoiquuid: f2ac3d66-cc79-498f-83fb-dd96feb88de2
exl-id: 92c95cb5-fdbf-4200-89a8-10c768e4bc25
---
# Initial Setup for Enablement {#initial-setup-for-enablement}

>[!CAUTION]
>
>AEM 6.4 has reached the end of extended support and this documentation is no longer updated. For further details, see our [technical support periods](https://helpx.adobe.com/support/programs/eol-matrix.html). Find the supported versions [here](https://experienceleague.adobe.com/docs/).

## Start Author and Publish Instances {#start-author-and-publish-instances}

For development and demonstration purposes, it will be necessry to run one author and one publish instance.

Follow the basic AEM [Getting Started](../../help/sites-deploying/deploy.md#getting-started) instructions which will result in

* author environment on [localhost:4502](http://localhost:4502/)
* publish environment on [localhost:4503](http://localhost:4503/)

For AEM Communities,

* The author environment is for

    * Development of sites, templates, components, enablement resources and learning paths
    * Assignment of members and groups of members to enablement resources and learning paths
    * Generating reports on assignments, views, and posts
    * Administrative and configuration tasks

* The publish environment is for

    * Learning/training based on topics managed by the Enablement Manager
    * Commenting and rating enablement resources and learning paths
    * Getting in touch with the resource contacts

>[!NOTE]
>
>If not familiar with AEM, view the documentation on [basic handling](../../help/sites-authoring/basic-handling.md) and a [quick guide to authoring pages](../../help/sites-authoring/qg-page-authoring.md).

## Install Latest Communities Release {#install-latest-communities-release}

This tutorial creates an [enablement community site](overview.md#enablement-community). To ensure the latest feature pack is installed, visit:

* [Latest Releases](deploy-communities.md#latest-releases)

For a tutorial that creates an [engagement community site](overview.md#engagement-community), visit [Getting Started with AEM Communities](getting-started.md).

## Configure Enablement Features {#configure-enablement-features}

To follow this tutorial, it is necessary to correctly install and [configure enablement](enablement.md), which requires third-party products, such as MySQL and FFmpeg.

## Configure Analytics {#configure-analytics}

When [Adobe Analytics is configured for the community site](analytics.md), more information is available in the [reports](reports.md) generated on enablement resources and learning paths assigned to community members (learners).

## Configure Email for Notifications {#configure-email-for-notifications}

The notifications feature, available by default for all sites created using the `Communities Sites` console, provides an email channel for notifications.

What is necessary is for email to be properly configured for the site.

See [Configuring Email](email.md).

## Enable the Tunnel Service {#enable-the-tunnel-service}

When creating a community site in the author environment, the tunnel service makes possible the ability to create and manage users and user groups registered in the publish environment (members), assign roles to trusted community members, and assign content to learners.

For more information see [Managing Users and User Groups](users.md).

For simple instructions to enable the tunnel service, see [Tunnel Service](deploy-communities.md#tunnel-service-on-author).

## Create Tutorial Tags {#create-tutorial-tags}

Create tags to use for the engage and enablement tutorials, using the tag namespace of `Tutorial`.

Use the [Tagging console](../../help/sites-administering/tags.md#tagging-console) to create the following tags:

* `Tutorial: Sports / Baseball`
* `Tutorial: Sports / Gymnastics`
* `Tutorial: Sports / Skiing`
* `Tutorial: Arts / Visual`
* `Tutorial: Arts / Auditory`
* `Tutorial: Arts / History`

![chlimage_1-417](assets/chlimage_1-417.png)

Then follow the instructions to

1. [Set the tag permissions](../../help/sites-administering/tags.md#setting-tag-permissions)
1. [Publish the tags](../../help/sites-administering/tags.md#publishing-tags)

Sample package of tags created for the AEM Communities Getting Started Tutorials

[Get File](assets/communities_tutorialtags-10.zip)

## Create Enablement Members and Groups {#create-enablement-members-and-groups}

For an enablement community site, site visitors should not be able to [self-register nor use social login](sites-console.md#user-management).

Instead, with the [tunnel service](#enable-the-tunnel-service) enabled, the [Members console](members.md) is used to register new members in the publish environment.

In this tutorial, three members are created in the publish environment. Two members will be become members of a user group that is assigned to a learning path, while the third member will become an enablement resource contact.

A fourth user is created in the author environment and assigned the roles of Communities Administrator and Community Enablement Manager.

>[!NOTE]
>
>These members are being created prior to creation of the *Enablement Tutorial* community site.
>
>If they were created afterwards, they could be added as members of the *Enablement Tutorial members group* during member creation.
>
>Instead, later, they'll be [assigned to the members group](enablement-create-site.md#assignuserstocommunityenablemembersgroup).

### Riley Taylor - Enrollee {#riley-taylor-enrollee}

[Create a member](members.md#create-new-member) who will be added to a group of Learners - the Community Ski Class group.

* **ID**: riley
* **Email**<EMAIL_ADDRESS>* **Password**: password
* **Confirm Password**: password
* **First Name**: Riley
* **Last Name**: Taylor

### Sidney Croft - Enrollee {#sidney-croft-enrollee}

[Create a second member](members.md#create-new-member) who will be added to the Community Ski Class group.

* **ID**: sidney
* **Email**<EMAIL_ADDRESS>* **Password**: password
* **Confirm Password**: password
* **First Name**: Sidney
* **Last Name**: Croft

### Quinn Harper - Enablement Resource Contact and Moderator {#quinn-harper-enablement-resource-contact-and-moderator}

[Create a member](members.md#create-new-member) who will be added to the Community Site's member group once the site has been created. This membership will allow the member to be assigned as the enablement [Resource Contact](resources.md#settings) when an enablement resource is created for the site.

* **ID**: quinn
* **Email**<EMAIL_ADDRESS>* **Password**: password
* **Confirm Password**: password
* **First Name**: Quinn
* **Last Name**: Harper

### Add a User Group - Community Ski Class {#add-a-user-group-community-ski-class}

[Add a new group](members.md#create-new-group) named Community Ski Class.

* **ID**: community-ski-class
* **Name**: Community Ski Class
* **Description**: a sample group for assigning enablement resources
* **Add Members To Group** 'add':

    * riley
    * sidney

* Select **[!UICONTROL Save]**

### Community Ski Class properties {#community-ski-class-properties}

![chlimage_1-418](assets/chlimage_1-418.png)

>[!NOTE]
>
>During creation of the community site, existing members and groups may be added to the community site's members group.

## Community Administrator Role {#community-administrator-role}

Members of the Community Administrators group are able to create community sites, manage sites, manage members (they can ban members from the community), and moderate content.

### Create User {#create-user}

Create a user on *author*, who is assigned the role of Community Administrator:

* On the author instance

    * For example, [http://localhost:4502/](http://localhost:4503/)

* Sign in with administrator privileges

    * For example, username 'admin' / password 'admin'

* From the main console, navigate to **[!UICONTROL Tools, Operations > Security > Users]**
* From the **[!UICONTROL Edit]** menu, select **[!UICONTROL Add User]**

* In the `Create New User` dialog enter

    * **ID***: sirius
    * **Emai Address**<EMAIL_ADDRESS>    * **Password***: password
    * **Confirm Password***: password
    * **First Name**: Sirius
    * **Last Name***: Nilson

### Assign Sirius to Community Administrators Group {#assign-sirius-to-community-administrators-group}

Scroll down to `Add User to Groups`:

* Enter 'C' to search

    * Select `Community Administrators`
    * Select `Community Enablement Managers`

* Select **[!UICONTROL Save]**

![chlimage_1-419](assets/chlimage_1-419.png)

gha_language: Groovy


text:
# AmazonSimpleNotificationService

```text
aws-20210730/Architecture/AppIntegration/AmazonSimpleNotificationService
```

```text
include('aws-20210730/Architecture/AppIntegration/AmazonSimpleNotificationService')
```

| Illustration | AmazonSimpleNotificationService | AmazonSimpleNotificationServiceCard | AmazonSimpleNotificationServiceGroup |
| :---: | :---: | :---: | :---: |
| ![illustration for Illustration](../../../aws-20210730/Architecture/AppIntegration/AmazonSimpleNotificationService.png) | ![illustration for AmazonSimpleNotificationService](../../../aws-20210730/Architecture/AppIntegration/AmazonSimpleNotificationService.Local.png) | ![illustration for AmazonSimpleNotificationServiceCard](../../../aws-20210730/Architecture/AppIntegration/AmazonSimpleNotificationServiceCard.Local.png) | ![illustration for AmazonSimpleNotificationServiceGroup](../../../aws-20210730/Architecture/AppIntegration/AmazonSimpleNotificationServiceGroup.Local.png) |

## AmazonSimpleNotificationService

### Load remotely
```plantuml
@startuml
' configures the library
!global $LIB_BASE_LOCATION="https://github.com/tmorin/plantuml-libs/distribution"

' loads the library's bootstrap
!include $LIB_BASE_LOCATION/bootstrap.puml

' loads the package bootstrap
include('aws-20210730/bootstrap')

' loads the Item which embeds the element AmazonSimpleNotificationService
include('aws-20210730/Architecture/AppIntegration/AmazonSimpleNotificationService')

' renders the element
AmazonSimpleNotificationService('AmazonSimpleNotificationService', 'Amazon Simple Notification Service', 'an optional tech label')
@enduml
```

### Load locally
```plantuml
@startuml
' configures the library
!global $INCLUSION_MODE="local"
!global $LIB_BASE_LOCATION="../../.."

' loads the library's bootstrap
!include $LIB_BASE_LOCATION/bootstrap.puml

' loads the package bootstrap
include('aws-20210730/bootstrap')

' loads the Item which embeds the element AmazonSimpleNotificationService
include('aws-20210730/Architecture/AppIntegration/AmazonSimpleNotificationService')

' renders the element
AmazonSimpleNotificationService('AmazonSimpleNotificationService', 'Amazon Simple Notification Service', 'an optional tech label')
@enduml
```

## AmazonSimpleNotificationServiceCard

### Load remotely
```plantuml
@startuml
' configures the library
!global $LIB_BASE_LOCATION="https://github.com/tmorin/plantuml-libs/distribution"

' loads the library's bootstrap
!include $LIB_BASE_LOCATION/bootstrap.puml

' loads the package bootstrap
include('aws-20210730/bootstrap')

' loads the Item which embeds the element AmazonSimpleNotificationServiceCard
include('aws-20210730/Architecture/AppIntegration/AmazonSimpleNotificationService')

' renders the element
AmazonSimpleNotificationServiceCard('AmazonSimpleNotificationServiceCard', 'Amazon Simple Notification Service Card', 'an optional description')
@enduml
```

### Load locally
```plantuml
@startuml
' configures the library
!global $INCLUSION_MODE="local"
!global $LIB_BASE_LOCATION="../../.."

' loads the library's bootstrap
!include $LIB_BASE_LOCATION/bootstrap.puml

' loads the package bootstrap
include('aws-20210730/bootstrap')

' loads the Item which embeds the element AmazonSimpleNotificationServiceCard
include('aws-20210730/Architecture/AppIntegration/AmazonSimpleNotificationService')

' renders the element
AmazonSimpleNotificationServiceCard('AmazonSimpleNotificationServiceCard', 'Amazon Simple Notification Service Card', 'an optional description')
@enduml
```

## AmazonSimpleNotificationServiceGroup

### Load remotely
```plantuml
@startuml
' configures the library
!global $LIB_BASE_LOCATION="https://github.com/tmorin/plantuml-libs/distribution"

' loads the library's bootstrap
!include $LIB_BASE_LOCATION/bootstrap.puml

' loads the package bootstrap
include('aws-20210730/bootstrap')

' loads the Item which embeds the element AmazonSimpleNotificationServiceGroup
include('aws-20210730/Architecture/AppIntegration/AmazonSimpleNotificationService')

' renders the element
AmazonSimpleNotificationServiceGroup('AmazonSimpleNotificationServiceGroup', 'Amazon Simple Notification Service Group', 'an optional tech label') {
    note as note
        the content of the group
    end note
}
@enduml
```

### Load locally
```plantuml
@startuml
' configures the library
!global $INCLUSION_MODE="local"
!global $LIB_BASE_LOCATION="../../.."

' loads the library's bootstrap
!include $LIB_BASE_LOCATION/bootstrap.puml

' loads the package bootstrap
include('aws-20210730/bootstrap')

' loads the Item which embeds the element AmazonSimpleNotificationServiceGroup
include('aws-20210730/Architecture/AppIntegration/AmazonSimpleNotificationService')

' renders the element
AmazonSimpleNotificationServiceGroup('AmazonSimpleNotificationServiceGroup', 'Amazon Simple Notification Service Group', 'an optional tech label') {
    note as note
        the content of the group
    end note
}
@enduml
```

repository: VinayaSathyanarayana/plantuml-libs

repo_name: VinayaSathyanarayana/plantuml-libs


text:
# 1. Introduction
[kryo](https://github.com/EsotericSoftware/kryo) is a fast and efficient object graph serialization framework for Java.
You can use the Kryo library to serialize objects quickly, but it does require the object layout to be the same
on both serialization and deserialization sides. Generally, this prerequisite is unrealistic in real application scenarios.
For example, the applications in the distribution system rely on an object model for communication across the nodes.
Along with the system's evolution, the developers have to add new fields to the object model to meet new business requirements.
In this typical case, it is challenging for the developers to simultaneously upgrade all the applications to use the same object
layout for fast performance, which usually requires tremendous work.

If using kryo's CompatibleFieldSerializer will incur performance degradation.This project, session-compatible-fast-serializer(SCFS),
try to keep a balance between compatibility and performance.

We perform JMH test with the following conditions:
- OS: Linux 64 bit
- JDK: Dragonwell 8 - 64bits
- Hardware: Aliyun ECS with 4vCPU+8GB

The following test results are divide into groups according to the complexity of the test object.
```
Benchmark                                                      Mode  Cnt        Score                Error  Units
SerializerBenchmark.Kryo_Upstream_Compatible_DiffLayout1.run  thrpt   15   370660.262 ±  2967.346           ops/s
SerializerBenchmark.SCFS_DiffLayout1.run                      thrpt   15  1237834.811 ± 14960.798           ops/s

SerializerBenchmark.Kryo_Upstream_Compatible_Small1.run       thrpt   15   371108.770 ±  1509.108           ops/s
SerializerBenchmark.Kryo_Upstream_NotCompatible_Small1.run    thrpt   15   556920.706 ±  7405.588           ops/s
SerializerBenchmark.SCFS_Small1.run                           thrpt   15   904877.294 ±  8731.215           ops/s

SerializerBenchmark.Kryo_Upstream_Compatible_Small2.run       thrpt   15   284163.019 ±  2834.764           ops/s
SerializerBenchmark.Kryo_Upstream_NotCompatible_Small2.run    thrpt   15   392914.210 ±  3365.496           ops/s
SerializerBenchmark.SCFS_Small2.run                           thrpt   15   571458.927 ±  7719.183           ops/s

SerializerBenchmark.Kryo_Upstream_Compatible_Small3.run       thrpt   15   568131.324 ±  3588.822           ops/s
SerializerBenchmark.Kryo_Upstream_NotCompatible_Small3.run    thrpt   15   817075.307 ±  5256.913           ops/s
SerializerBenchmark.SCFS_Small3.run                           thrpt   15  1623851.291 ± 14505.581           ops/s

SerializerBenchmark.Kryo_Upstream_Compatible_Medium1.run      thrpt   15    67248.623 ±  1557.259           ops/s
SerializerBenchmark.Kryo_Upstream_NotCompatible_Medium1.run   thrpt   15   141754.221 ±   765.331           ops/s
SerializerBenchmark.SCFS_Medium1.run                          thrpt   15   176203.113 ±  1621.590           ops/s

SerializerBenchmark.Kryo_Upstream_Compatible_Large1.run       thrpt   15    18341.364 ±    97.690           ops/s
SerializerBenchmark.Kryo_Upstream_NotCompatible_Large1.run    thrpt   15    22221.829 ±   545.190           ops/s
SerializerBenchmark.SCFS_Large1.run                           thrpt   15    24012.446 ±   280.637           ops/s
```
We also test SCFS with the following JDKs:
- Dragonwell 8 - 64bits
- Dragonwell 11 - 64bits
- AdoptOpenJDK 8 - 64bits
- AdoptOpenJDK 11 - 64bits
- OpenJ9 JDK8 - 64bits
- OpenJ9 JDK11 - 64bits

# 2. Quickstart
## 2.1 Add Dependency
**Note:** SCFS requires JDK 1.8 and kryo 5 or later.
```xml
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>session-compatible-fast-serializer</artifactId>
    <version>1.0.0</version>
</dependency>
```
If not, you can download JAR in [Maven Center Repository](https://mvnrepository.com/artifact/com.alibaba/session-compatible-fast-serializer).
## 2.2 Hello SessionKryo
```java
public class HelloSessionKryo {
    public static void main(String[] args) {
        SessionKryo sessionKryo = SessionKryoService.newSingletonSessionKryoFactory(new ReadWriteSessionDataLocator() {
            private ReadWriteSessionData readWriteSessionData;

            public ReadWriteSessionData find(Object locateKey) {
                return readWriteSessionData;
            }

            public void newCreated(Object locateKey, ReadWriteSessionData newReadWriteSessionData) {
                readWriteSessionData = newReadWriteSessionData;
            }
        }, CreateOption.of()).get();

        FooData fooData = new FooData();
        fooData.a = "this is a test";
        fooData.b = 199;
        fooData.c = 121313L;

        byte[] b = sessionKryo.writeClassAndObject(null, fooData);
        System.out.println("Write Foo: " + fooData);
        FooData fooDataRead = (FooData) sessionKryo.readClassAndObject(null, b);
        System.out.println("Read Foo:" + fooDataRead);
    }

    private static class FooData {
        String a;
        int b;
        long c;

        public String toString() {
            return "FooData{" + "a='" + a + '\'' + ", b=" + b + ", c=" + c + '}';
        }
    }
}
```

## 2.3 Integration Guide
What's the difference between SCFS and kryo? SCFS is a stateful serializer, it defines a session between writer and reader,
and the session must be unique between writer and reader. For example, a socket connection can regard as a session identifier.
So using SCFS requires doing some mapping between some unique identifiers in your application to SCFS's session.
### 2.3.1 Implement ReadWriteSessionDataLocator
The performance improvement comes from the abstraction of the Session. The metadata of the object can transmit only once in the compatible mode in one session.
During each serialization, SCFS need to get the current session by a unique identifier. In a distributed system, a session can bind to a socket connection.

Pay attention to the following points when implementing ReadWriteSessionDataLocator:
1. Session is not thread-safe, make sure ReadWriteSessionData cannot be used by multiple threads simultaneously.
2. Cached ReadWriteSessionData should consider when to destroy, such as ReadWriteSessionData associated with the socket, it should be cleared when the socket closed.
An example of implementation is as follows(SocketLifecycle is a sample,not a real interface):
```java
public class SocketReadWriteSessionDataLocator implements ReadWriteSessionDataLocator,SocketLifecycle {
    private Map<String,ReadWriteSessionData> sessionDataMap = new ConcurrentHashMap<>();

    @Override
    public ReadWriteSessionData find(String locateKey) {
        return sessionDataMap.get(locateKey);
    }

    @Override
    public void newCreated(String locateKey, ReadWriteSessionData newReadWriteSessionData) {
        sessionDataMap.put(locateKey,newReadWriteSessionData);
    }

    @Override
    public void socketClose(String channelId){
        sessionDataMap.remove(channelId);
    }
}
```

### 2.3.2 Instance SessionKryoFactory
SessionKryo is a memory consumed object in runtime, and it's not thread-safe. So SessionKryo should be cached.
SessionKryoFactory is that factory for reusing SessionKryo instances. SessionKryoFactory should be initialized only once.
#### <IP_ADDRESS> Singleton SessionKryo
Applicable to only one thread uses the Kryo.
```java
SessionKryoFactory sessionKryoFactory = SessionKryoService.newSingletonSessionKryoFactory(sessionDataLocator, CreateOption.of());
```
#### <IP_ADDRESS> ThreadLocal SessionKryo
In a distributed framework, there is usually a special IO thread pool to process serialization, so in this scenario,
binding a SessionKryo to each IO thread can reduce the number of SessionKryo instances.
```java
 SessionKryoFactory sessionKryoFactory = SessionKryoService.newThreadLocalSessionKryoFactory(readWriteSessionDataLocator, CreateOption.of());
```
#### <IP_ADDRESS> Custom SessionKryoFactory
If the above two situations do not meet requirements, you can customize them. For example,
```java
SessionKryoFactory sessionKryoFactory = SessionKryoService.newCachedSessionKryoFactory(new CacheSessionKryoPolicy<String>() {
    @Override
    public SessionKryo get(String locateKey) {
        if ("writeKryo".equals(locateKey)) {
            return writeKryo;
        } else if ("readKryo".equals(locateKey)) {
            return readKryo;
        } else {
            return null;
        }
    }

    @Override
    public void put(String locateKey, SessionKryo sessionKryo) {
        if ("writeKryo".equals(locateKey)) {
            writeKryo = sessionKryo;
        } else if ("readKryo".equals(locateKey)) {
            readKryo = sessionKryo;
        }
    }
}, sessionDataLocator, CreateOption.of());
```
## 2.3.4 Use SessionKryo's API to serialize and deserialize
```
SessionKryo sessionKryo = sessionKryoFactory.get();
byte[] b = kryo.writeClassAndObject(sessionKey, objToSerialize);
Object object = kryo.readClassAndObject(sessionKey, b);
```
# 3. How it works
## 3.1 Compatible
Kryo uses chunked encoding to support compatibility. Chucked encoding incurs some extra memory copy which leads to performance degradation.
However, in some cases, the serialization process writes the result to a byte array instead of java.io.OutputStream. In the same way,
deserialization reads from the byte array instead of java.io.InputStream.
Because byte array can be randomly read and write, we don't using chunked encoding but also support serialization compatibility.
### 3.1.1  Type encoding for known types
The key to compatibility is how to skip an unrecognized field. If each field encode with a length, the overhead will be large, but
some known types, such as int, long, String, etc., even if it didn't know the length, it also knows how to decode.
Therefore, SCFS encode type information into the data for the first time. The deserializer caches the type information of the object for later use.
### 3.1.2 Encode variable-length fields
```
|length block|larger field pointer|field 1| field 2| ... |larger field num|larger field 1 size|larger field 2 size| ...
```
* length block: fixed-length byte array. If the length of a field is less than or equal to 255, marked the length here directly. Otherwise, the length will be written in the larger field.
* larger field pointer: if the length of a field exceeds 255 characters, point to the beginning of larger field num.
* field 1: the data area of a specific field
* larger field number: the number of larger fields.
* larger field 1 size: the size of a larger field.
The main purpose is to reduce the number of additional bytes :
1. For known types, no need to encode field length.
2. Otherwise, If the field length ≤ 255, need one byte.
3. For length> 255 need a variable-length block. Considering such fields is relatively small, so the overhead is relatively small.

### 3.1.3 Quickly skip unrecognized fields based on encoding information.
By the type and field length information in the byte stream, the deserialization side knows how to skip an unrecognized field.
## 3.2 Performance
### 3.2.1 Object metadata sent only once
The metadata of an object is sent only once in a session. The metadata of an object includes the name and type information of the fields.
### 3.2.2 Traverse object by memory offsets in the JVM to make the Cache more friendly
Kryo traverses fields by field name, but the JVM internal does not layout the fields by the name.
If an object traverse according to the offset of the field in JVM internal, this will give the chance to hit L1 cache.
### 3.2.3 Remember object output size after serialization
During the test, we found there is a call hotspot on System.arrayCopy function.
For the large object, the output buffer needs to expand many times to fulfil the final serialize requirements.
If the output buffer initial size same as the previous serialization, it can reduce some unnecessary calls to System.arrayCopy.
### 3.2.4 Cache layout compare the result for deserialization
If the object layout is the same, cache the result avoid comparing each time.
If the object layout is not the same, cache the mapping between the fields avoid comparing each time.
### 3.2.5 Divide cached data into the global area, thread area, and session area
Put the major memory consumed part into the global area, the other area reference to the global area. In this way, when the number of sessions reaches tens of thousands,
the memory overhead is relatively small.


text:
# Error cause

Ballerina facilitates having a cause in an error value. It can be passed as a positional argument to the error constructor. The cause argument is optional in the error constructor.

::: code error_cause.bal :::

::: out error_cause.out :::

gha_language: Java


text:
---
title: Repository guidelines
label: internal
---

Repository guidelines include:

- The [instruction](#new-repository-settings-new-repository-settings) that lists recommended settings for a new repository in the `kyma-project` and `kyma-incubator` organizations.
- The content description of the [`repository-template`](https://github.com/kyma-project/community/blob/main/docs/guidelines/repository-guidelines/02-repository-template.md) folder that provides the structure of an exemplary Kyma repository. Use it whenever you create a new repository within Kyma.

repository: kyma-project/community

gha_language: Go

repo_name: kyma-project/community


text:
# Protocol Overall concepts

Several message types will be present, each will be wrapped in a SpaceMessage.

# SpaceMessage
The `messagetype` field will be a string that states the type of the object that is being wrapped
The `o` field will be the object itself. As this is JSON, it will be a dictionary (object) with keys / values as-per its type.

```
SpaceMessage =
{
 messagetype: ("SpaceObject" | "SpaceControl" | "SpaceID"),
 o: (SpaceObject | SpaceControl | SpaceID)
}
```

# SpaceObject
The SpaceObject is based on the space game's SpaceObject so they can be directly ported between.
Today that makes this object as follows:

```
SpaceObject =
{
  uuid: String,
  owner: String,
  type: String,
  global: [ Float64 ... ],
  velocity: [ Float64 ... ],
  angle: Float64,
  angle_velocity: Float64,
  boost: Int64,
  thrusters: [ { type: String, firing: Int64 } ... ]
}
```

# SpaceControl

# SpaceID

repository: zgiles/ctuniverse

repo_name: zgiles/ctuniverse


text:
---
title: Bio
layout: home
has_toc: false
nav_order: 6
---

## Bio

Ce is an Associate Professor in Computer Science at ETH Zurich. The mission of his research is to make machine learning techniques widely accessible---while being cost-efficient and trustworthy---to everyone who wants to use them to make our world a better place. He believes in a system approach to enabling this goal, and his current research focuses on building next-generation machine learning platforms and systems that are data-centric, human-centric, and declaratively scalable. Before joining ETH, Ce finished his PhD at the University of Wisconsin-Madison and spent another year as a postdoctoral researcher at Stanford, both advised by Christopher Ré. His work has received recognitions such as the SIGMOD Best Paper Award, SIGMOD Research Highlight Award, Google Focused Research Award, an ERC Starting Grant, and has been featured and reported by Science, Nature, the Communications of the ACM, and a various media outlets such as Atlantic, WIRED, Quanta Magazine, etc.

<img src="../assets/imgs/ce_2022.png" width="150px" style="margin:10px 10px"/>


text:
# Auditing Exercise

- Speed

1. Optimize Images (they are relatively large and take a lot of space)
2. Gzip text
3. Minify Javascript
4. Remove unused JS (lodash and jquery)
5. Use HTTP/2
6. Set long cache policy for static assets
7. Reduce number of network requests

- Accessibility

1. Increase foregroudn and background contrast ratio
2. Put title for frame and iframe
3. Put alt tags for images

- Best Practices

1. Uses JS libraries with known vulnrabilities
2. Console.log errors

repository: phatnguyenuit/FrontEnd-Masters

repo_name: phatnguyenuit/FrontEnd-Masters


text:
TCButton
========

A UIButton that, given custom assets, functions like iOS 7 style buttons.

Features
--------

-   A TCButton UIButton that is configurable

-   Easy to use properties to change animation options and fade speed

-   Light weight, Clean, Easy to read, self explaining code you will enjoy using
    in your projects.

![](<https://raw.github.com/crizzwald/TCButton/master/Screenshot.png>)

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

-   iOS 6.0 or later

-   ARC memory management.

Usage
-----

Add the dependency to your Podfile:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
platform :iOS, '6.0'
pod 'TCButton', '~> 1.0.0'
...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Or copy the following to your project:

-   TCButton.h

-   TCButton.m

Initialize an instance of a TCButton and set the assets accord to state config
(Default/Highlighted).

Use the TCButton instance in your code as you would use any other UIButton.

Configuration Properties:

-   TCButtonAnimationOptions animationOptions;

-   CGFloat fadeToHighlightDuration;

Other methods are documented in the TCButton.h header file.

License
-------

Copyright (c) 2013 Todd Crown<EMAIL_ADDRESS>
[1]<EMAIL_ADDRESS>

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: The above copyright notice and this
permission notice shall be included in all copies or substantial portions of the
Software.

 IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

repository: crizzwald/TCButton

repo_name: crizzwald/TCButton


text:
# Note, Under heavy development use on your own risk

# iDigitalOcean
Improves the management panel usability and experience of DigitalOcean contol panel

# Current Features
- Remove pagination and bring all droplets to one view
- Sort droplets by name
- Get all the ip addresses of all the servers as a string
- Get all the ip addresses of all the servers prepended by user@ as a string

# Planned features
- Command center, triggered by a shortcut opens a terminal like window to type and get responses
- Remove current search and add a realtime JS search
- IP Addresses manipulation, get them in any specific format.
- Get all Local IP addresses and add them to the main table.

repository: bhappyz/iDigitalOcean

repo_name: bhappyz/iDigitalOcean


text:
##Description:

The program calls a function that can never be guaranteed to work safely.

Certain functions behave in dangerous ways regardless of how they are used. Functions in this category were often implemented without taking security concerns into account. The gets() function is unsafe because it does not perform bounds checking on the size of its input. An attacker can easily send arbitrarily-sized input to gets() and overflow the destination buffer. Similarly, the >> operator is unsafe to use when reading into a statically-allocated character array because it does not perform bounds checking on the size of its input. An attacker can easily send arbitrarily-sized input to the >> operator and overflow the destination buffer.

##Mitigation:

PHASE:Implementation Requirements:
Ban the use of dangerous functions. Use their safe equivalent.

PHASE:Testing:
Use grep or static analysis tools to spot usage of dangerous functions.

gha_language: HTML


text:
# miniapp builder

Miniapp build cli tool.
Support sfc and mp type

## Install

```bash
npm install miniapp-builder -g
```

## dev server

```bash
miniapp start
```

## build

```bash
miniapp build
```

## args

- `-p` port of dev server
- `-d` path of app source directory

gha_license_id: NOASSERTION


text:
# Notifications Overview

Adaptive Live Tiles and interactive Toasts are key engagement components of a UWP Application on Windows 10.
Instead of having to deal with XML, you can now use UWP Community toolkit and its notification extensions to work with Tiles and notifications using a complete object model.

## Tiles

| Documentation |
| --- |
| [Adaptive Tile Notifications](https://blogs.msdn.microsoft.com/tiles_and_toasts/2015/06/30/adaptive-tile-templates-schema-and-documentation/) |
| [Quickstart: Sending a local Tile notification](https://blogs.msdn.microsoft.com/tiles_and_toasts/2015/10/05/quickstart-sending-a-local-tile-notification-in-windows-10/) |

## Example Image

![LiveTile](../resources/images/Notifications-LiveTile.gif "LiveTile")

## Toasts

| Documentation |
| --- |
| [Interactive Toast Notifications](https://blogs.msdn.microsoft.com/tiles_and_toasts/2015/07/02/adaptive-and-interactive-toast-notifications-for-windows-10/) |
| [Quickstart: Sending a local Toast notification](https://blogs.msdn.microsoft.com/tiles_and_toasts/2015/07/08/quickstart-sending-a-local-toast-notification-and-handling-activations-from-it-windows-10/) |

## Example Image

![Toast](../resources/images/Notifications-PopToast.gif "Toast")

## Requirements (Windows 10 Device Family)

| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.10586.0 or higher |
| --- | --- |
| Namespace for C# | Microsoft.Toolkit.Uwp.Notifications |
| Namespace for JavaScript | Microsoft.Toolkit.Uwp.Notifications.Javascript |

## API

* [Notifications source code](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Notifications/Microsoft.Toolkit.Uwp.Notifications.UWP)

repository: michael-hawker/UWPCommunityToolkit

branch_name: refs/heads/dev

gha_language: C#

repo_name: michael-hawker/UWPCommunityToolkit


text:
# ProxiCMS - ContentBundle

[![Latest Stable Version](https://poser.pugx.org/proxilog/proxicms-content-bundle/v)](https://packagist.org/packages/proxilog/proxicms-content-bundle)

***/!\  WARNING, Be aware until the version 1.0.0, some breaking changes can be introduce***

This bundle allow you to manage the content for the ProxiCMS.

## TODO

* Create the [Recipes](https://github.com/symfony/recipes-contrib) installation
* better use of migration? (any idea?)
* Create the tests in the bundle (instead of the app side)

## Usage

### EasyAdmin

It will provide a Content to manage with the possibility to enable the text editor.

### Twig

When you get the Content with twig, it will create or get the current one by its identifier.

* Get the [Content](src/Entity/Content.php) object with identifier `proxicms_content_obj('identifier')`
* Get the value with identifier `proxicms_content_val('identifier')`

## Installation

This bundle requires PHP 8.1 or higher and Symfony 6.1 or higher.

### Step 1: Install the bundle using composer

```bash
$ composer require proxilog/proxicms-content-bundle
```

### Step 2: Add the bundle to your bundles.php

```php
// config/bundles.php
return [
    //..
    ProxiCMS\ContentBundle\ProxiCMSContentBundle::class => ['all' => true],
];
```

### Step 3: Add the MenuItem in your Dashboard EasyAdmin

```php
// src/Controller/Admin/DashboardController.php
public function configureMenuItems(): iterable
    {
        //...
        yield MenuItem::linkToCrud('Contenus', 'fas fa-pager', Content::class)
                    ->setController(ContentCrudController::class);
    }
```

or you can create your own `ContentCrudController` and extends this controller.

### Step 4: Add the migrations in your app

```yaml
# config/doctrine_migrations.yaml
doctrine_migrations:
    migrations:
        - 'ProxiCMS\ContentBundle\Migrations\MySQL0100'
```

repository: Proxilog/proxicms-content-bundle

repo_name: Proxilog/proxicms-content-bundle


text:
---
layout: post
title: "Towards lightweight convolutional neural networks for object detection"
date: 2017-10-05 12:08:49
categories: arXiv_CV
tags: arXiv_CV Object_Detection CNN Inference Detection
author: Dmitriy Anisimov, Tatiana Khanova
mathjax: true
---

* content
{:toc}

##### Abstract
We propose model with larger spatial size of feature maps and evaluate it on object detection task. With the goal to choose the best feature extraction network for our model we compare several popular lightweight networks. After that we conduct a set of experiments with channels reduction algorithms in order to accelerate execution. Our vehicle detection models are accurate, fast and therefore suit for embedded visual applications. With only 1.5 GFLOPs our best model gives 93.39 AP on validation subset of challenging DETRAC dataset. The smallest of our models is the first to achieve real-time inference speed on CPU with reasonable accuracy drop to 91.43 AP.

##### Abstract (translated by Google)

##### URL
[https://arxiv.org/abs/1707.01395](https://arxiv.org/abs/1707.01395)

##### PDF
[https://arxiv.org/pdf/1707.01395](https://arxiv.org/pdf/1707.01395)


text:
# Storybook-AEM-Confluence
> Integrate Confluence and JIRA with your Storybook stories

Storybook-AEM-Confluence is an addon that enables you to pull content from the Confluence API into storybook. For example, you can add the content from your wiki page about your component in an addon panel. Additionally, Storybook-AEM-Confluence supports multiple content ID's so you can have more than one page from Confluence per component.

## Install Storybook-AEM-Confluence:

```npm i storybook-aem-confluence```

## Usage
Open or create your storybook addons file and add:
```
// .storybook/addons.js
import 'storybook-aem-confluence/register';
```

Next open or create the storybook middleware file and add:
```
// .storybook/middleware.js
const proxy = require('http-proxy-middleware');
const ConfluenceMiddleware = require('storybook-aem-confluence/middleware');

module.exports = router => {
    // any other code

    router.use(
        '/confluence/:id',
        ConfluenceMiddleware({
            baseUrl: 'https://[confluenceDomain].atlassian.net/wiki',
            username: process.env.confluenceUser,
            password: process.env.confluencePassword
        })
    );
}
```

> It is suggested to use [dotenv](https://www.npmjs.com/package/dotenv) or some other mechanism to get your username and password, and not have them stored in code.

Next, in your storybook config, add this:
```
// .storybook/config.js
import { withConfluence } from 'storybook-aem-confluence';

addDecorator(withConfluence);
```

And finally, in your stories you can use the confluence panel like so:

```
// path/to/your/story.js
// You may also add the confluence parameter on individual stories as well
// This id is the content id from confluence, often found in the URL of the page
export default {
    parameters: {
        confluence: {
            tabs: [
                {
                    title: 'Tab 1',
                    id: '123456789'
                },
                {
                    title: 'Tab 2',
                    id: '987654321'
                }

            ]
        }
    }
};
```

repository: icfnext/storybook-aem

gha_language: CSS

repo_name: icfnext/storybook-aem


text:
# Chapter 8a: Two One-of Types

## Cross product table

In this lecture, I learned how to prepare tests for functions involving two One-of data types using the cross product table.

I also learned the importance of preparing a "model" for programming before reaching out for the code. Using the model, I was able to simplify tests and combine test cases which is incredibly helpful especially when I'm forming conditions on a function consuming two one-of data types.

## Cross Product Code

In this lecture, I learned how to code using the type comments prepared in the previous video of cross product table.

By making the cross product table, and putting pseudo-code type comments, I was able to "simplify at the model level".By using the type comments, I am able to predict the structure of the template, and produce an even simpler function.


text:
  Python optimization library for mathematical programming.

Introduction
------------
Pytimize is a python library for
- Formulating and solving complex linear, integer, and nonlinear programs.
- Performing combinatorial optimization with directed/undirected graphs and flows.
- Visualizing polyhedrons and displaying computation process.

Install using `pip install pytimize`!

Documentation
-------------
Coming soon!

Example
-------
The following shows a code snippet for constructing a linear program and solving
it with two phase simplex. For more detailed examples, please see `pytimize/examples`.
```python
>>> from pytimize.formulations.linear import variables, minimize
>>> a, b, c, d, e = variables(5)
>>> p = minimize(4*c - 11*d - e + 17).subject_to(
        a + 2*c + 7*d <= 2 + e,
        b - 4*c - 5*d >= 1 - 3*e
    ).where(
        a >= 0,
        b >= 0,
        c >= 0,
        d <= 0,
        e <= 0
    )
>>> p
Min [0. 0. 4. -11. -1.]x + 17.
Subject To:

[1.  0.   2.   7.  -1.]     ≤   [2.]
[0.  1.  -4.  -5.   3.]x    ≥   [1.]
x₄, x₅ ≤ 0
x₁, x₂, x₃ ≥ 0

>>> p.dual()
Max [2. 1.]x
Subject To:

[ 1.   0.]     ≤   [  0.]
[ 0.   1.]     ≤   [  0.]
[ 2.  -4.]x    ≤   [  4.]
[ 7.  -5.]     ≥   [-11.]
[-1.   3.]     ≥   [ -1.]
x₁ ≤ 0
x₂ ≥ 0

>>> p.to_sef(in_place=True)
Max [0. 0. -4. -11. -1. 0. 0.]x + 17.
Subject To:

[1.  0.   2.  -7.   1.  1.   0.]     =   [2.]
[0.  1.  -4.   5.  -3.  0.  -1.]x    =   [1.]
x ≥ 0

>>> solution, optimal_basis, certificate = p.two_phase_simplex()
>>> solution, optimal_basis, certificate
(array([2., 1., 0., 0., 0., 0., 0.]), [1, 2], array([0., 0.])
>>> p.verify_optimality(certificate)
True
>>> p.optimal_value()
17.0
```

You can also formulate the exact same program by specifying the objective
function and constraints in matrix form:
```python
>>> from pytimize.programs import LinearProgram
>>> import numpy as np
>>> A = np.array([
      [1, 0, 2, 7, -1],
      [0, 1, -4, -5, 3]
    ])
>>> b = np.array([2, 1])
>>> c = np.array([0, 0, 4, -11, -1])
>>> z = 17
>>> p = LinearProgram(A, b, c, z, "min", ["<=", ">="], negative_variables=[4, 5])
>>> p
Min [0. 0. 4. -11. -1.]x + 17
Subject To:

[1.  0.   2.   7.  -1.]     ≤   [2.]
[0.  1.  -4.  -5.   3.]x    ≥   [1.]
x₄, x₅ ≤ 0
x₁, x₂, x₃ ≥ 0
```

Contributing
------------
Pytimize is a work in progress project. Contributions are welcome on a pull request basis.

Credits
-------
Pytimize is created and maintained by Terry Zheng, Jonathan Wang, and Colin He.
Logo is designed by Kayla Estacio.

repository: TerrayTM/pytimize

repo_name: TerrayTM/pytimize


text:
---
date:   2015-02-05
categories:
- tutorials
authors:
- Jack Reed
---

# Using GeoCombine to harvest and index OpenGeoMetadata

A quick tutorial on how to harvest and index OpenGeoMetadata for your GeoBlacklight installation.

!!! warning

	This tutorial from **2015** may be outdated. Please refer to the [GeoCombine repo](https://github.com/OpenGeoMetadata/GeoCombine) for up to date instructions.

Sharing, collaborating, and harvesting geospatial metadata is not really easy. A recent development in the world of geospatial metadata sharing is the new project [OpenGeoMetadata](https://github.com/OpenGeoMetadata). OpenGeoMetadata aims to be a shared repository for institutions looking to share, collaborate, and harvest geospatial metadata. For more details on how the project is structured and why we think this is really cool, [see this readme](https://github.com/OpenGeoMetadata/metadatarepository/blob/master/README.md).

We started work on software focused on harvesting, converting, and indexing this metadata called [GeoCombine](https://github.com/OpenGeoMetadata/GeoCombine).

## GeoCombine - A ruby toolkit for geospatial metadata

GeoCombine is envisioned as an easy to use toolkit for metadata conversions with integration into applications and projects like [GeoBlacklight](https://github.com/geoblacklight/geoblacklight), [GeoMonitor](https://github.com/geoblacklight/geomonitor), and OpenGeoMetadata.

Currently (as of 2015-02-05), GeoCombine really just does three things:

 - Clones OpenGeoMetadata repositories
 - Updates the local cloned repositories (using `git pull`)
 - Indexes into Solr `geoblacklight.xml` files from the cloned repositories

### Getting started

This guide assumes a few things already.

 - You have [Git](https://gorails.com/setup/#git) installed
 - You have [Ruby](https://gorails.com/setup/#ruby) installed
 - You have Solr running locally on port 8983 (default Solr port) and it is configured with [GeoBlacklight-Schema](https://github.com/geoblacklight/geoblacklight-schema/tree/master/conf) configuration

### Install GeoCombine

If you have already have a GeoBlacklight application, skip steps 1 and 2. You can just add gem 'geo_combine' to your GeoBlacklight application's Gemfile
{: .flash-notice}

  1. To get started, first clone the GeoCombine repository

     ```sh
     $ git clone https://github.com/OpenGeoMetadata/GeoCombine.git
     ```

  1. Switch to its folder

     ```sh
     $ cd GeoCombine
     ```

  1. Install GeoCombine's dependencies

     ```sh
     $ bundle install
     ```

  1. Create a `tmp` directory (if it doesn't already exist)

     ```sh
     $ mkdir tmp
     ```

  1. Clone all of the 'edu.*' repositories to tmp.

     ```sh
     $ rake geocombine:clone
     ```

     Since other software projects live in OpenGeoMetadata we only want to clone the metadata repositories. All of these are currently namespaced with "edu.institution.subdomain".
     {: .flash-notice}

  1. Index all of the `geoblacklight.xml` documents located in cloned repositories.

     ```sh
     $ rake geocombine:index
     ```

     Go grab a coffee or lunch, because this might take a while! But afterwards your index should have +30,000 new records in it.

extension: markdown


text:
---
layout: chapter
title: "Parser Combinators"
---

## Learning Outcomes

- Understand that a parser is a program which extracts information from structured text
- Apply what we have learned about Haskell typeclasses and other functional programming concepts to create solutions to real-world problems
- In particular, we learn to use parser combinators and see how they are put together

## Introduction

In this section we will see how the various Haskell language features we have explored allow us to solve real-world problems.  In particular, we will develop a simple but powerful library for building *parsers* that is compositional through [Functor](/haskell3/#functor), [Applicative](/haskell3/#applicative) and [Monad](/monad) interfaces.  Before this, though, we will learn the basics of parsing text, including a high-level understanding that parsers are *state-machines* which realise a *context-free grammar* over a textual language.

Previously, [we glimpsed a very simplistic Applicative parser](/haskell3/#a-simple-applicative-functor-for-parsing).
In this chapter, a *parser* is still simply a function which takes a string as input and produces some structure or computation as output, but now we extend the parser with monadic 'bind' definitions, richer error handling and the ability to handle non-trivial grammars with alternative inputs.

Parsing has a long history and *parser combinators* are a relatively recent approach made popular by modern functional programming techniques.
A *parser combinator* is a [higher-order function](/higherorderfunctions) that accepts parsers as input and combines them somehow into a new parser.

More traditional approaches to parsing typically involve special purpose programs called *parser generators*, which take as input a grammar defined in a special language (usually some derivation of BNF as described below) and generate the partial program in the desired programming language which must then be completed by the programmer to parse such input.  Parser combinators have the advantage that they are entirely written in the one language.  Parser combinators written in Haskell take advantage of the expressiveness of the Haskell language such that the finished parser can look a lot like a BNF grammar definition, as we shall see.

The parser combinator discussed here is based on one developed by Tony Morris and Mark Hibberd as part of their ["System F" Functional Programming Course](https://github.com/system-f/fp-course), which in turn is a simplified version of official Haskell parser combinators such as [parsec](https://hackage.haskell.org/package/parsec) by Daan Leijen.

You can play with the example and the various parser bits and pieces in [this on-line playground](https://replit.com/@tgdwyer/Parser-Examples).

## Context-free Grammars and BNF

Fundamental to analysis of human natural language but also to the design of programming languages is the idea of a *grammar*, or a set of rules for how elements of the language may be composed.  A context-free grammar (CFG) is one in which the set of rules for what is produced for a given input (*production rules*) completely cover the set of possible input symbols (i.e. there is no additional context required to parse the input).  Backus-Naur Form (or BNF) is a notation that has become standard for writing CFGs since the 1960s.  We will use BNF notation from now on.  There are two types of symbols in a CFG: *terminal* and *non-terminal*.  In BNF non-terminal symbols are `<nameInsideAngleBrackets>` and can be converted into a mixture of terminals and/or nonterminals by production rules:

```
<nonterminal> ::= a mixture of terminals and <nonterminal>s, alternatives separated by |
```

Thus, *terminals* may only appear on the right-hand side of a production rule, *non-terminals* on either side.  In BNF each *non-terminal* symbol appears on the left-hand side of exactly one production rule, and there may be several possible alternatives for each *non-terminal* specified on the right-hand side.  These are separated by a "`|`" (in this regard they look a bit like the syntax for [algebraic data type definitions](/haskell2#algebraic-data-types)).

Note that production rules of the form above are for context-free grammars.  As a definition by counter-example, *context sensitive grammars* allow terminals and more than one non-terminal on the left hand side.

Here's an example BNF grammar for parsing Australian land-line phone numbers, which may optionally include a two-digit area code in brackets, and then two groups of four digits, with an arbitrary number of spaces separating each of these, e.g.:

> (03) 9583 1762
> 9583 1762

Here's the BNF grammar:

```
<phoneNumber> ::= <fullNumber> | <basicNumber>
<fullNumber> ::= <areaCode> <basicNumber>
<basicNumber> ::= <spaces> <fourDigits> <spaces> <fourDigits>
<fourDigits> ::= <digit> <digit> <digit> <digit>
<areaCode> ::= "(" <digit> <digit> ")"
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<spaces> ::= " " <spaces> | ""
```

So `"0"`-`"9"`, `"("`, `")"`, and `" "` are the full set of terminals.

Now here's a sneak peak at a simple parser for such phone numbers.  It succeeds for any input string which satisfies the above grammar, returning a 10-digit string for the full number without spaces and assumes "03" for the area code for numbers with none specified (i.e. it assumes they are local to Victoria).  Our [`Parser` type](/parsercombinators/#parser-type) provides a function `parse` which we call like so:

```haskell
GHCi> parse phoneNumber "(02)9583 1762"
Result >< "0295831762"

GHCi> parse phoneNumber "9583  1762"
Result >< "0395831762"

GHCi> parse phoneNumber "9583-1762"
Unexpected character: "-"
```

We haven't bothered to show the types for each of the functions in the code below, as they are all `::Parser [Char]` - meaning a Parser that returns a string.  We'll explain all the types and functions used in due course.  For now, just notice how similar the code is to the BNF grammar definition:

```haskell
phoneNumber = fullNumber ||| (("03"++) <$> basicNumber)

fullNumber = do
   ac <- areaCode
   n <- basicNumber
   pure (ac ++ n)

basicNumber = do
   spaces
   first <- fourDigits
   spaces
   second <- fourDigits
   pure (first ++ second)

fourDigits = do
  a <- digit
  b <- digit
  c <- digit
  d <- digit
  pure [a,b,c,d]

areaCode = do
  is '('
  a <- digit
  b <- digit
  is ')'
  pure [a,b]
```

## Parser Type

In essence, our parser is going to be summed up by a couple of types:

```haskell
type Input = String
newtype Parser a = P { parse :: Input -> ParseResult a}
```

We assume all `Input` is a `String`, i.e. Haskell's basic builtin `String` which is a list of `Char`.

Then the `Parser` type has one field `parse` which is a function of type `Input -> ParseResult a`.  So it parses strings and produces parse results, where a Parse result is:

```haskell
 data ParseResult a = Error ParseError
                    | Result Input a
  deriving Eq
```

We'll come back to the `ParseError` type - which will be returned in the case of unexpected input, but we can see that a successful Parse is going to produce a `Result` which has two fields -- more `Input` (the part of the input remaining after we took a bit off and parsed it), and an `a`, a type parameter that we may specify for concrete `Parser` instances.

The `Parser` and the `ParseResult` types are pretty abstract.  They say nothing about what precise `Input` string we are going to parse, or what type `a` we are going to return in the result.  This is the strength of the parser, allowing us to build up sophisticated parsers for different input grammars through composition using [instances of Function, Applicative and Monad](/parsercombinators/#instances), and the `ParseResult` parameter `a` allows us to produce whatever we want from the parsers we create.

## Error Handling

Error handling is a very important part of any real-world parser.  Decent error reporting allows us to quickly diagnose problems in our input.
As we saw above a `ParseResult` may be either a successful `Result` or an `Error`, the latter containing information in a `ParseError` data structure about the nature of the error.

```haskell
data ParseError =
    UnexpectedEof -- hit end of file when we expected more input
  | ExpectedEof Input -- should have successfully parsed everything but there's more!
  | UnexpectedChar Char
  | UnexpectedString String
  deriving (Eq, Show)
```

Naturally it needs to be `Show`able, and we'll throw in an `Eq` for good measure.
<!-- was "but also `Eq`uality testable so that we can pattern match `ParseResult` to handle particular types of errors.". This may be misleading because pattern matching works even without Eq! -->

## Instances

First an instance of `Show` to pretty print the `ParseResult`s:

```haskell
instance Show a => Show (ParseResult a) where
  show (Result i a)                 = "Result >" ++ i ++ "< " ++ show a
  show (Error UnexpectedEof)        = "Unexpected end of stream"
  show (Error (UnexpectedChar c))   = "Unexpected character: " ++ show [c]
  show (Error (UnexpectedString s)) = "Unexpected string: " ++ show s
  show (Error (ExpectedEof i))      =
    "Expected end of stream, but got >" ++ show i ++ "<"
```

And `ParseResult` is also an instance of `Functor` so that we can map functions over the output of a successful parse -- or do nothing if the result is an `Error`:

```haskell
instance Functor ParseResult where
  fmap f (Result i a) = Result i (f a)
  fmap _ (Error e)    = Error e
```

A `Parser` itself is also a `Functor`.  This allows us to create a new `Parser` by composing functionality onto the `parse` function for a given `Parser`:

```haskell
instance Functor Parser where
  fmap :: (a -> b) -> Parser a -> Parser b
  fmap f (P p) = P (fmap f . p)
```

The applicative `pure` creates a `Parser` that always succeeds with the given input, and thus forms a basis for composition.  We saw it being used in the above example to return the results of a parse back into the `Parser` at the end of a `do` block.

The `(<*>)` allows us to map functions in the `Parser` over another `Parser`.  As with other `Applicative` instances, a common use case would be composition with a `Parser` that returns a data constructor as we will see in [the next example](/parsercombinators/#creating-a-parse-tree).

```haskell
instance Applicative Parser where
  pure :: a -> Parser a
  pure x = P (`Result` x)

  (<*>) :: Parser (a -> b) -> Parser a -> Parser b
  (<*>) p q = p >>= (<$> q)
```

The `Monad` instance's bind function `(>>=)` we have already seen in use in the example above, allowing us to sequence `Parser`s in `do`-blocks to build up the implementation of the BNF grammar.

```haskell
instance Monad Parser where
  (>>=) :: Parser a -> (a -> Parser b) -> Parser b
  (>>=) (P p) f = P (
    \i -> case p i of
      Result rest x -> parse (f x) rest
      Error e -> Error e)
```

## Parser Combinators

The most atomic function for a parser of `String` is to pull a single character off the input.  The only thing that could go wrong is to find our input is empty.

```haskell
character :: Parser Char
character = P parseit
  where parseit "" = Error UnexpectedEof
        parseit (c:s) = Result s c
```

The following is how we will report an error when we encounter a character we didn't expect.  This is not the logic for recognising a character, that's already happened and failed and the unrecognised character is now the parameter.  This is just error reporting, and since we have to do it from within the context of a `Parser`, we create one using the `P` constructor.  Then we set up the one field common to any `Parser`, a function which returns a `ParseResult` no matter the input, hence `const`.  The rest creates the right type of `Error` for the given `Char`.

```haskell
unexpectedCharParser :: Char -> Parser a
unexpectedCharParser = P . const . Error . UnexpectedChar
```

Now a parser that insists on a certain character being the next one on the input.  It's using the `Parser` instance of `Monad`'s bind function (implicitly in [a `do` block](/monad/#do-notation)) to sequence first the `character` `Parser`, then either return the correct character in the `Parser`, or the `Error` parser.

```haskell
is :: Char -> Parser Char
is c = do
  v <- character
  let next = if v == c
             then pure
             else const $ unexpectedCharParser v
  next c
```

And finally our `Parser` for trying to apply a first `Parser`, and then an alternate `Parser` if the first fails.  This allows us to encode the alternatives in our BNF grammar rules.

```haskell
(|||) :: Parser a -> Parser a -> Parser a
p1 ||| p2 = P (\i -> let f (Error _) = parse p2 i
                         f r = r
                     in f $ parse p1 i)
```

## Nitty gritty

The last two pieces of our Phone Numbers grammar we also implement fairly straightforwardly from the BNF.  In a real parser combinator library you'd do it differently, as per our exercises below.

```
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<spaces> ::= " " <spaces> | ""
```

Here's a trivial adaptation of `digit`:
```haskell
digit :: Parser Char
digit = is '0' ||| is '1' ||| is '2' ||| is '3' ||| is '4' ||| is '5' ||| is '6' ||| is '7' ||| is '8' ||| is '9'
```

Spaces is a bit more interesting because it's recursive, but still almost identical to the BNF:

```haskell
spaces :: Parser ()
spaces = (is ' ' >> spaces) ||| pure ()
```

### Exercises

- make a less repetitive `digit` parser by creating a function `satisfy :: (Char -> Bool) -> Parser Char` which returns a parser that produces a character but fails if the input is empty or the character does not satisfy the given predicate. You can use the `isDigit` function from `Data.Char` as the predicate.

- change the type of `spaces` to `Parser [Char]` and have it return the appropriately sized string of only spaces.

## A Parser that returns an ADT

The return type of the phone number parser above was `[Char]` (equivalent to `String`).  A more typical use case for a parser though is to generate some data structure that we can then process in other ways.  In Haskell, this usually means a parser which returns an [Algebraic Data Type (ADT)](/haskell2#algebraic-data-types).  Here is a very simple example.

Let's imagine we need to parse records from a vets office.  It treats only three types of animals.  As always, lets start with the BNF:

```
<Animal> ::= "cat" | "dog" | "camel"
```

So our simple grammar consists of three terminals, each of which is a straightforward string *token* (a constant string that makes up a primitive word in our language).  To parse such a token, we'll need a parser which succeeds if it finds the specified string next in its input.  We'll use our `is` parser from above (which simply confirms a given character is next in its input).  The type of is was `Char -> Parser Char`.  Since `Parser` is an instance of `Applicative`, we can simply `traverse` the `is` parser across the given `String` (list of `Char`) to produce another `String` in the `Parser` applicative context.

```haskell
string :: String -> Parser String
string = traverse is
```

Now let's define an ADT for animals:

```haskell
data Animal = Cat | Dog | Camel
  deriving Show
```

A parser for "cat" is rather simple.  If we find the string `"cat"` we produce a `Cat`
```haskell
cat :: Parser Animal
cat = string "cat" >> pure Cat
```
Let's test it:
```haskell
> parse cat "cat"
Result >< Cat
```

Ditto dogs and camels:

```haskell
dog, camel :: Parser Animal
dog = string "dog" >> pure Dog
camel = string "camel" >> pure Camel
```

And now a parser for our full grammar:

```haskell
animal :: Parser Animal
animal = cat ||| dog ||| camel
```
Some tests:
```haskell
> parse animal "cat"
Result >< Cat
> parse animal "dog"
Result >< Dog
> parse animal "camel"
Result >< Camel
```
What's really cool about this is that obviously the strings "cat" and "camel" overlap at the start.  Our alternative parser `(|||)` effectively backtracks when the `cat` parser fails before eventually succeeding with the `camel` parser.  In an imperative style program this kind of logic would result in much messier code.

**Exercises**

- Write some messy imperative-style JavaScript (no higher-order functions allowed) to parse cat, dog or camel and construct a different class instance for each.
- Now add "dolphin" to the grammar, and use a stopwatch to time yourself extending your messy imperative code.  I bet it takes longer than extending the `animal` parser combinator.
- Make a parser `stringTok` which uses the `string` parser to parse a given string, but ignores any `spaces` before or after the token.
- Modify the grammar and the ADT to have some extra data fields for each of the animal types, e.g. `humpCount`, `remainingLives`, `barkstyle`, etc.
- Extend your parser to produce these records.

## Creating a Parse Tree

Programs are usually parsed into a tree structure called an *Abstract Syntax Tree* (AST), more generally known as a *parse tree*.  Further processing ultimately into an object file in the appropriate format (whether it's some sort of machine code directly executable on the machine architecture or some sort of intermediate format -- e.g. Java bytecode) then essentially boils down to traversal of this tree to evaluate the statements and expressions there in the appropriate order.

We will not implement a parser for a full programming language, but to at least demonstrate what this concept looks like in Haskell we will create a simple parser for simple arithetic expressions.  The parser generates a tree structure capturing the order of operations, which we may then traverse to perform a calculation.

To start with, here is a BNF grammar for a simple calculator with three operations `*`, `+` and `-`, with `*` having higher precedence than `+` or `-`:

```
<expr> ::= <term> | <expr> <addop> <term>
<term> ::= <number> | <number> "*" <number>
<addop> ::= "+" | "-"
```

An expression `<expr>` consists of one or more `<term>`s that may be combined with an `<addop>` (an addition operation, either `"+"` or `"-"`).  A `<term>` involves one or more numbers, multiplied together.

The dependencies between the non-terminal expressions makes explicit the precedence of multiply operations needing to occur before add (and subtract).

The data structure we will create uses the following Algebraic Datatype:

```haskell
data Expr = Plus Expr Expr
          | Minus Expr Expr
          | Times Expr Expr
          | Number Integer
  deriving Show
```

Our top-level function will be called `parseCalc`:

```haskell
parseCalc :: String -> ParseResult Expr
parseCalc = parse expr
```

And an example use might look like:

```haskell
> parseCalc " 6 *4 + 3- 8 *  2"
Result >< Minus (Plus (Times (Number 6) (Number 4)) (Number 3)) (Times (Number 8) (Number 2))
```

Here's some ASCII art to make the tree structure of the `ParseResult Expr` more clear:

```
Minus
 ├──Plus
 |   ├──Times
 |   |   ├──Number 6
 |   |   └──Number 4
 |   └──Number 3
 └──Times
     ├──Number 8
     └──Number 2
```

**Exercises**

- make an instance of `show` for `Expr` which pretty prints such trees
- Make a function which performs the calculation specified in an `Expr` tree like the one above.

Obviously we are going to need to parse numbers, so let's start with a simple parser which creates a `Number`.
Note that whereas our previous parser had type `phoneNumber :: Parser [Char]` -- i.e. it produced strings -- this, and most of the parsers below, produces an `Expr`.

```haskell
number :: Parser Expr
number = spaces >> Number . read . (:[]) <$> digit
```

We keep things simple for now, make use of our existing `digit` parser, and limit our input to only single digit numbers.
The expression `Number . read . (:[])` is fmapped over the `Parser Char` returned by `digit`.
We use the Prelude function `read :: Read a => String -> a` to create the `Int` expected by `Number`.  Since `read` expects a string, we apply `(:[])` to turn the `Char` into `[Char]`, i.e. a `String`.

Next, we'll need a parser for the various operators (`*`,`+` and `-`).  There's enough of them that we'll make it a general purpose `Parser Char` parameterised by the character we expect:

```haskell
op :: Char -> Parser Char -- parse a single char operator
op c = do
   spaces
   is c
   pure c
```

As before, `spaces` ignores any number of `' '` characters.

Here's how we use `op` for `*`; note that it returns only the `Times` constructor.  Thus, our return type is an as-yet unapplied binary function (and we see now why `(<*>)` is going to be useful).

```haskell
times :: Parser (Expr -> Expr -> Expr)
times = op '*' >> pure Times
```

And for `+` and `-` a straightforward implementation of the `<addop>` non-terminal from our grammar:

```haskell
addop :: Parser (Expr -> Expr -> Expr)
addop = (op '+' >> pure Plus) ||| (op '-' >> pure Minus)
```

And some more non-terminals:

```haskell
expr :: Parser Expr
expr = chain term addop

term :: Parser Expr
term = chain number times
```

These use the `chain` function to handle repeated chains of operators (`*`, `-`, `+`) of unknown length.  We could make each of these functions recursive with a `|||` to provide an alternative for the base case end-of-chain (as we did for `spaces`, above), but we can factor the pattern out into a reusable function, like so:

```haskell
chain :: Parser a -> Parser (a->a->a) -> Parser a
chain p op = p >>= rest
   where
   rest a = (do
               f <- op
               b <- p
               rest (f a b)
            ) ||| pure a
```

**Exercises**

- Similar to `chain`, factor out the recursion of `spaces` into a function which returns a parser that continues producing a list of values from a given parser, i.e.
 `list :: Parser a -> Parser [a]`.

## Parsing Rock-Paper-Scissors

A common use-case for parsing is deserialising data stored as a string.
Of course, there are general data interchange formats such as JSON and XML for which most languages have parsers available.  However, sometimes you want to store data in your own format for compactness or readability, and when you do, deserialising the data requires a custom parser
(this example is contributed by [Arthur Maheo](https://arthur.maheo.net/)).

We will explore a small game of Rock-Paper-Scissors using a memory.
The play function will have the following type:

``` haskell
data RockPaperScissors = Rock | Paper | Scissors

-- | Play a round of RPS given the result of the previous round.
play
  :: Maybe (RockPaperScissors, RockPaperScissors, String)
  -- ^ Result of the previous round as: (your choice, opponent choice, your memory)
  -> (RockPaperScissors, String) -- ^ (Choice, new memory)
```

We will build a simple player which will keep track of the opponent's previous choices and try to counter the most common one.

### How to build a memory

We will convert to string using a simple `Show` instance:

``` haskell
instance Show RockPaperScissors where
  show :: RockPaperScissors -> String
  show Rock = "R"
  show Paper = "P"
  show Scissors = "S"
```

(Note, we could also define a `Read` instance to deserialise such a simple type but we are going to define a `ParserCombinator` for interest and extensibility to much more complex scenarios).

The straightforward way to create the memory is to just store a list of all the choices made by the opponent.
So, for example, if the results from the previous three rounds were:
``` haskell
(Rock, Paper), (Rock, Scissors), (Paper, Scissors)
```
Then, a compact memory representation will be: `"PSS"`.

*Note*: We only store single characters, so we do not need separators, but if you have more complex data, you will want separators.

### Reading the memory

Now, we want to define a `Parser RockPaperScissors` which will turn a string into a choice.
First, we will define a parser for each of the three choices:

``` haskell
rock :: Parser RockPaperScissors
rock = is 'R' >> pure Rock

scissors :: Parser RockPaperScissors
scissors = is 'S' >> pure Scissors

paper :: Parser RockPaperScissors
paper = is 'P' >> pure Paper
```

This will give:

```
>>> parse rock "R"
Result >< R
>>> parse rock "RR"
Result >R< R
>>> parse rock "P"
Unexpected character: "P"
```

To combine those parsers, we will use the *option parser* `(|||)`.

```
choice :: Parser RockPaperScissors
choice = rock ||| paper ||| scissors
```

And, to be able to read a list of choices, we need to use the `list` parser:

```
>>> parse choice "PSS"
Result >SS< P
>>> parse (list choice) "PSCS"
Result >CS< [P,S]
>>> parse (list choice) "PSS"
Result >< [P,S,S]
```

### Playing the game

Our decision function will take a list of `RockPaperScissors` and return the move that would win against most of them.
One question remains: how do we get the memory *out* of the parser?
The answer is: pattern-matching.

``` haskell
getMem :: ParseResult a -> a
getMem (Result _ cs) = cs
getMem (Error _) = error "You should not do that!"
```

Obviously, in a longer program you want to be handling this case better.

*Hint*: If your parser returns a list of elements, the empty list `[]` is a good default case.

### Putting it all together

The first round, our player will just pick a choice at random and return an empty memory.

``` haskell
play Nothing = (Scissors, "") -- Chosen at random!
```

Now, we need to write a couple functions:

1. `winAgainst` that determines which choice wins against a given one.
2. `mostCommon` which finds the most common occurrence in a list.

With that, we have a full `play` function:

``` haskell
play (Just (_, opponent, mem)) = (winning whole, concatMap convert whole)
  where
    -- Convert the memory to a list of different choices
    as_choices = getMem . parse (list choice)
    -- Get the whole set of moves -- all the prev. rounds + last one
    whole = opponent: as_choices mem
    winning = winAgainst . mostCommon
```

``` haskell
>>> play Nothing
(S,"")
>>> play (Just (Scissors, Scissors, ""))
(R,"S")
>>> play (Just (Scissors, Scissors, "RRP"))
(P,"SRRP")
```

*Note*: Here we can see the results directly because `RockPaperScissors` has an instance of `Show`.
If you want to do the same with a datatype without `Show`, you would need to call `convert`.

### Going further

Now, this is a simplistic view of storing information.
We are only concatenating characters because our data is so small.
However, there are better ways to store that data.

One issue with this approach is that we need to process the memory sequentially at each round.
Instead, we could keep track of the number of occurrences of each choice.

**Exercise**: Implement a memory for the following datatype.

``` haskell
data Played = Played {rocks, papers, scissors :: Int}

-- | Store a @Played@ as a string in format: @nC@, with @n@ the number of
-- occurrences and @C@ the choice.
convert' :: Played -> String
convert' Played{rocks, papers, scissors} =
  show rocks ++ "R" ++ show papers ++ "P" ++ show scissors ++ "S"
```

```
>>> play Nothing
(S,"0R0P0S")
>>> play (Just (Scissors, Scissors, "0R0P0S"))
(R,"0R0P1S")
>>> play (Just (Scissors, Scissors, "2R1P0S"))
(P,"2R1P1S")
```


text:
#  <img src="skill_icon" alt="Poetry icon" width="36"> [Poetry](http://alexa.amazon.com/#skills/amzn1.echo-sdk-ams.app.bd5aafa2-54cb-495c-9c98-fe48a618ff5f)
![3.5 stars](../../images/ic_star_black_18dp_1x.png)![3.5 stars](../../images/ic_star_black_18dp_1x.png)![3.5 stars](../../images/ic_star_black_18dp_1x.png)![3.5 stars](../../images/ic_star_half_black_18dp_1x.png)![3.5 stars](../../images/ic_star_border_black_18dp_1x.png) 2

To use the Poetry skill, try saying...

* *Alexa, ask any poet about love*

* *Alexa, ask any poet about life*

* *Alexa, ask any poet about snow*

Get inspired by an increasing number of poems about love, life and everything else.

***

### Skill Details

* **Invocation Name:** any poet
* **Category:** null
* **ID:** amzn1.echo-sdk-ams.app.bd5aafa2-54cb-495c-9c98-fe48a618ff5f
* **ASIN:** B01GZ3K5CI
* **Author:** Matthias Koller
* **Release Date:** June 22, 2016 @ 00:15:32
* **In-App Purchasing:** No

repository: pragatidev/alexa-skills-list

repo_name: pragatidev/alexa-skills-list