public abstract class Game extends java.lang.Object implements Level.LevelObserver
| Modifier | Constructor and Description |
|---|---|
protected |
Game()
Creates a new game.
|
| Modifier and Type | Method and Description |
|---|---|
void |
continousMovement(IdentifiedPlayer player,
Direction direction)
Moves the specified player until the next cross in the given direction.
|
protected int |
getCurrentLevel()
Simple getter for currentLevel.
|
abstract AILevel |
getLevel() |
abstract java.util.List<IdentifiedPlayer> |
getPlayers() |
boolean |
isInProgress() |
void |
levelLost()
The level has been lost.
|
void |
levelWon()
The level has been won.
|
protected AILevel |
makeLevel(int id)
Creates a new level.
|
void |
move(IdentifiedPlayer player,
Direction direction)
Moves the specified player one square in the given direction.
|
AILevel |
nextLevel()
Returns the next level and increments the currentLevel field.
|
abstract void |
reset()
Forces subclasses to provide a method allowing to
reset the score and the number of lives the player has.
|
protected abstract void |
setLevel(AILevel level)
Forces subclasses to provide a method to switch to the given Level.
|
void |
setLevel(int levelIndex)
Sets the level to the one that has the given id (calls #Game.setLevel).
|
void |
setStrategy(PacmanStrategy strategy)
Set the strategy.
|
void |
start()
Starts or resumes the game.
|
void |
stop()
Pauses the game.
|
public void start()
public void stop()
public boolean isInProgress()
true
iff the game is started and in progress.public abstract java.util.List<IdentifiedPlayer> getPlayers()
public abstract AILevel getLevel()
public void setLevel(int levelIndex)
levelIndex
- The id of the level we want to switch toprotected abstract void setLevel(AILevel level)
level
- The Level we want to switch topublic void continousMovement(IdentifiedPlayer player, Direction direction)
player
- The player to move.direction
- The direction to move in.public void move(IdentifiedPlayer player, Direction direction)
player
- The player to move.direction
- The direction to move in.public void levelWon()
Level.LevelObserver
levelWon
in interface Level.LevelObserver
public void levelLost()
Level.LevelObserver
levelLost
in interface Level.LevelObserver
public abstract void reset()
protected AILevel makeLevel(int id)
id
- The id of the level we want to load.public AILevel nextLevel()
protected int getCurrentLevel()
public void setStrategy(PacmanStrategy strategy)
strategy
- chosen by the player.


Dear Sir or Madam {{user}},
You have just requested to submit the code for authentication in the {{site.name}} page.
Go to {{ url }} and enter the code {{code}}.
Sincerely, Administrator


Setting
@objc
public protocol Setting : NSCopying, NSObjectProtocol
Objects conforming to this protocol can be used as Settings. This a.o. means they have a value that can be set and get, and that the NoiseTagging framework can provide the user with UI to edit the setting.
The easiest way to conform to Setting
is to subclass Setting_abstract
.
See also
Settings can be grouped together in aSetOfSettings
.
-
The setting’s title, as displayed in the UI.
Declaration
Swift
var title: String { get }
-
Whether the settings is editable by the user.
Declaration
Swift
var isEditable: Bool { get set }
-
Whether the setting allows to be undefined.
Important
we do not use optionals for representing specific setting type values. Instead in most cases the concept of ‘undefined’ is irrelevant. This property, as well asallowsUndefined
, is only used for implementing the ‘Feedback Screen’, where ‘undefined’ should be the default for all ‘settings’. But these ‘settings’ are only used for logging purposes.Declaration
Swift
var allowsUndefined: Bool { get set }
-
If the setting is part of a
SetOfSettings
and UI is displayed to edit that set, this determines whether the setting is also visible in the UI.Declaration
Swift
var isVisibleInUI: Bool { get set }
-
An explanation for the user about what the setting exactly is about.
Declaration
Swift
var help: String? { get set }
-
A closure which checks whether a certain value is a valid value for the setting.
This closure gets a ‘candidate’ for the setting’s new value and should return nil if that candidate is ‘valid’. If it is not valid, the closure should return an explanation for the user why the value is not valid.
Attention
Classes that implement theSetting
protocol should perform thevalidityCheck
before they actually change their setting value. They should also not forget to copy thevalidityCheck
in their copy function.Declaration
Swift
var validityCheck: ((Any) -> ResultValidityCheck)? { get set }
-
Settings always have a default value, which is their initial value. This default value can easily be restored by the user using the standard UI for editing settings provided by the NoiseTagging framework.
Declaration
Swift
var valueEqualsDefaultValue: Bool { get }
-
Whether the setting’s value is ‘undefined’. Only relevant if
allowsUndefined
istrue
.See also
SeeAlsoallowsUndefined
.Declaration
Swift
var valueIsUndefined: Bool { get set }
-
Sets the receiver’s setting value to the setting value of
newSetting
.Declaration
Swift
func updateValueToMatch(newSetting: Setting)
-
Set the setting value to the default value.
See also
hasDefaultValue
Declaration
Swift
func resetToDefault()
-
Set the setting value to
undefined
.See also
allowsUndefined
.Declaration
Swift
func setToUndefined()
-
An optional closures that is executed just before changing the setting’s value:
Declaration
Swift
var actionBeforeChange: (() -> ())? { get set }
-
An optional closures that is executed just after changing the setting’s value:
Declaration
Swift
var actionAfterChange: (() -> ())? { get set }
-
A setting’s observers are informed whenever the setting’s value changes.
Declaration
Swift
var observers: [SettingObserver] { get set }
-
Add a new observer, which is informed whenever the setting’s value changes.
Declaration
Swift
func add(observer: SettingObserver)
-
Remove an observer, so it is no longer informed whenever the setting’s value changes.
Declaration
Swift
func remove(observer: SettingObserver)
-
The setting’s value described using JSON. Used for logging purposes.
Declaration
Swift
@objc optional var valueAsJson: Any { get }
-
A description of the setting’s value, assuming a value is defined. Used for logging purposes.
Declaration
Swift
var descriptionValueIfDefined: String { get }
-
A description of the setting’s value, be it defined or undefined. Used for logging purposes.
Declaration
Swift
var descriptionValue: String { get }
-
The name of the nib used for generating UI for editing the setting.
Declaration
Swift
var cellNibName: String { get }
-
The NoiseTagging framework provides standard UI for editing settings. This UI consists of a table view, where each cell is used for one setting. The
cellReuseIdentifier
makes it possible to reuse these cells per setting type.Declaration
Swift
var cellReuseIdentifier: String { get }


Forbes, Monocle and Trusted Media Brands on how to transform a publishing business
by Forbes In The NewsMike Federle is quoted at length in this FIPP article discussing the importance of our journalism at the center of everything we do and stand for; how our digital transformation became the playbook for other publishers, and the consistent moves we make to get closer to our audience. Mike also will be keynoting at the upcoming FIPP conference in mid-November.


Classes, interfaces and traits
Collection¶
A Collection represents a bunch of "things" in the database.
The Collection's items all have to be instances of the same Model class.
If you try to add a different Model from the previous ones, you will receive
an Exception in return.
« More »
CSVConnector¶
A CSV file based data store.
« More »
Model¶
A Model represents a "thing" in the database, and provides
methods to read and write "things".
« More »
PDOConnector¶
A PDO Database connection. (MySQL, MariaDB, Postgres…)
« More »
Route¶
Represents a Route, matching a URL regex to a callback function / Controller method.
« More »
Router¶
The Router maps URLs to Controllers.
Singleton.
« More »
Schema¶
Describes what kind of information a Model contains.
« More »
Template¶
The Template class translates our custom MineTemplate syntax to PHP.
To display values in MineTemplates, you use `{{key}}`. If you need to go down a path
into arrays or objects, separate your key names with dots, like so:
`{{key.subkey.i.need.to.go.deeper}}`. To pass something to a block helper, use
{{#helpername arguments}}
content
{{/helpername}}
By default, two block helpers are defined: #each and #if.
{{#each user in users}}
<li> {{user.name}} </li>
{{/each}}
{{#if sale}}
Today: 10% OFF on every single thing!
{{/if}}
To pass something to an inline helper, use
{{@helpername arguments}}
By default, one inline helper is defined, namely @raw:
{{@raw keyWithHtml}}
This will output a value without first escaping HTML. Use with caution ;)
To define your own helpers, use `Template::addHelper`. See relevant documentation.
« More »
View¶
A View renders something to the browser.
« More »


This process is automatic. Your browser will redirect to your requested content shortly.
Please wait a few seconds.


Nutrition Facts
Serving Size 1bag 7 oz 198g(198g)
Amount Per Serving
Calories
972
Calories from Fat 558
%
Daily Value*
Total Fat
64g
99%
Saturated Fat 16g
80%
Trans Fat
Cholesterol
0mg
0%
Sodium
1485mg
62%
Dietary Fiber 9g
35%
Sugars
Protein
15g
Vitamin A
9%
• Vitamin C
112%
Calcium
10%
• Iron
21%
*Percent Daily Values are based on a 2,000 Calorie Diet. Your daily values may be higher or lower depending on your calorie needs


Press n or j to go to the next uncovered block, b, p or k for the previous block.
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| Interfaces/rest/barbermans/v1/barbermans |
|
87.18% | 34/39 | 100% | 0/0 | 85.71% | 6/7 | 86.11% | 31/36 |
| Interfaces/rest/barbermans/v1/barbermans/docs |
|
84.62% | 22/26 | 100% | 0/0 | 0% | 0/4 | 84.62% | 22/26 |
| Interfaces/rest/barbermans/v1/barbermans/dto |
|
100% | 35/35 | 100% | 0/0 | 100% | 0/0 | 100% | 35/35 |
| Interfaces/rest/shared/docs |
|
100% | 5/5 | 100% | 0/0 | 100% | 0/0 | 100% | 5/5 |
| Interfaces/rest/shared/docs/decorator-compose |
|
100% | 9/9 | 75% | 3/4 | 100% | 1/1 | 100% | 9/9 |
| Interfaces/rest/shared/docs/error-docs |
|
100% | 30/30 | 100% | 0/0 | 100% | 0/0 | 100% | 30/30 |
| Interfaces/rest/shared/dto |
|
87.5% | 14/16 | 100% | 0/0 | 0% | 0/2 | 87.5% | 14/16 |
| application/use-cases/barbermans/v1 |
|
16% | 8/50 | 0% | 0/38 | 50% | 2/4 | 12.5% | 6/48 |
| infrastructure/constants |
|
100% | 13/13 | 100% | 0/0 | 100% | 0/0 | 100% | 13/13 |
| infrastructure/database/postgres/medea-db/services |
|
31.58% | 6/19 | 0% | 0/2 | 0% | 0/5 | 23.53% | 4/17 |
| infrastructure/helper |
|
100% | 2/2 | 100% | 0/0 | 100% | 1/1 | 100% | 2/2 |
| infrastructure/middleware |
|
21.74% | 5/23 | 5.26% | 1/19 | 100% | 1/1 | 21.74% | 5/23 |


RESUME
John Henry Thompson
objective
To create interactive art using real time video processing; to create the next generation scripting language that integrates design methodologies; to study and create new computer game forms that integrate history and culture; to teach courses that help realize these objectives.
academic employment
1989 - 1997: New York University,
Interactive Telecommunications Program
Adjunct Assistant Professor (part time)
Developed and taught three graduate courses: "The Lingo Workshop", "Interactive Video", and "Advanced Computational Media". Supervised graduate theses.
1988 - 1989: New York University,
Interactive Telecommunications Program
Assistant Professor of Communications (full time)
Developed and taught three graduate courses: "Animation on Macintosh Computer", "Introduction to Computational Media", "Advanced Computational Media". Supervised graduate theses.
Nov 1983 - Apr 1984: MIT Visible Language
Workshop
Technical Instructor
Supervised undergraduate students theses in computer assisted graphic design. Designed and programmed prototype full-color page layout system.
presentations and workshops
Sep 2000: The Lingo Club, Eastmont Computing Center, Oakland CA.
Created and taught workshop on game programming for teens using Macromedia Director and Lingo. Workshop meet twice a week for six weeks.
Jun 1999: "Hard Fun", New York University, NYU.
Presented my ideas on computer games and
learning.
Sponsored by Black Students in New Media (BINMA).
Feb 1998: Digital Freedom Panel, New York University, NYU.
Lead panel discussion on race in the digital age.
Sponsored by Black Students in New Media (BINMA).
Jul 1998: National Black Arts Festival, Atlanta, GA.
Presented overview of the Multimedia Industry, and Macromedia products.
Jan 1997: "Tools for Art, Multimedia, and Learning", MIT Media Lab, Cambridge, MA.
Presented a retrospective of my work. Lead two day workshop on Lingo programming.
1996: Small Computers in the Arts Conference. Philadelphia, PA.
Presented an overview of the Multimedia Industry.
1995: Apple Developer Conference, San Jose, CA.
Lead session on cross-platform code development.
Aug 1994: Multi-Jam Expo, Jamaica, West Indies.
Designed and lead two week training session on Macromedia products and presentation on multimedia. Sponsored by Isadra Ltd, a Jamaican based Internet startup.
1990 - 1998: Macromedia User Conference, SF CA, and Australia.
Gave annual sessions on new features in the Lingo scripting language.
publications
1995, 1996: "Macromedia Director Lingo Workshop".
The complete resource to the Lingo scripting language. Translated into Japanese, German, and Italian languages.
art
Apr 1991: Le Primtemps De PRIM, Canada
Exhibited "Picture Piano", an interactive installation with computer, keyboard, and video disc.
Sep 1990: International Interactive Communications Society, NY USA
Exhibited "Picture Piano"
Oct 1988: American Film Institute, LA USA
Exhibited "Interactive Bed", an interactive installation using computer, video disc and image processing.
Jun 11 to 19, 1988: Hague Summer 88 Festival, Film Huis Netherlands
Exhibited "The Garden of Interactive Delights" an interactive art installation, created in collaboration with Benjamin Bergery. Included "Picture Piano", "Movie Machine", "Shadow Canvas", "Interactive Bed."
Sep 1977 - Jun 1983: Massachusetts Institute of Technology
Minor in Visual Arts and Design (Major in Computer Science). Drawing, print, video, film, art history.
Jan 1980 - Sep 1981: Art Student League of New York
Studied drawing and painting with Mr. Ernest Chrichlow
software engineering employment
Sep 1987 - Feb 2001: Macromedia. San Francisco CA.
Chief Scientist
The designer and inventor of Lingo and XObjects. Author of several major components of Macromedia Director. Original author of MacroMind Accelerator. Significant contributor to MediaMaker, Action MAC, Director Player for Windows 3.1, Director Player for 3DO, Director Player for Java, Shockwave, and Shockwave Multi User Server. At various times projector leader of up to five engineers.
Mar 1987 - Sep 1987: Island Graphics. San Rafael CA.
Software Engineer
Designed graphic system for medical imaging workstation.
Jun 1985 - Jan 1987: The DroidWorks Lucas Film Ltd. San Rafael CA
Software Projector Leader
Project leader of the machine interface group of the of EditDroid project, a video-disc based non-linear editing system.
Jan 1984 - Jun 1985: LCS/Telegraphics. Cambridge MA.
Principle Software Designer
Designed and implemented products for graphics and telecommunications.
Jun 1980 - Nov 1981: New York Psychiatric Institute. New York NY
Senior Programmer
Designed and implemented several packages for data management, analysis, and presentation for the research community.
Jan 1978 - Sep 1979: Computer Corporation of America, Cambridge MA
Systems Programmer
Member of the Spatial Database Management System research team. Programmed graphical access to large visual database.
Jan 1978 - Sep 1978: MIT Laboratory of Computer Science. Cambridge MA
Systems Programmer
Member of the Linguistic Memory System group. Re-structured large AI system for prototype LISP Machine.
education
1977 - 1983: Massachusetts Institute of Technology. Cambridge MA.
Bachelor of Science in Computer Science and Engineering. Minor in Visual Arts and Design
1980 - 1981: Art Student League of New York, New York.
Studied drawing and painting with Mr. Ernest Chrichlow
1975 - 1977: Bronx High School of Science. New York.


|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object javax.swing.table.AbstractTableModel de.iabg.mode.ModeTableModel
public class ModeTableModel
This implementation of a TableModel
provides a
table representation of a ModeMatrix
. This class bridges the
connection between a ModeMatrix
and a ModeModel
by simply
adding a table representation. Therefore, some of the methods of this class
wrap those in ModeMatrix
, while other methods are wrapped in
ModeModel
. Most of the descriptions of the methods in this class
can be found by refering to the API of either of those two classes. The
remaining methods generally implement or override those specified in
TableModel
. Refer to the API or tutorial for using
Table Models
for more details.
This TableModel
provides three columns to represent a
ModeMatrix
:
The first is called Selected
or On
, which selects the
corresponding mode shape. Selecting or deselecting this option can allow
later calculations, such as the Modal Assurance Criterion to only calculate
specified modes.
The second column is called Mode ID
, which displays the identifier of
the mode.
The third column is called Frequency [Hz]
, which displays the
frequency of the mode.
The rows of this table reflect the total number of modes that are currently
stored.
| Field Summary | |
|---|---|
protected static int |
MODE_FREQUENCY_INDEX
The column index of the mode frequency |
protected static int |
MODE_NAME_INDEX
The column index of the mode name |
protected static int |
MODE_SELECTED_INDEX
The column index of the mode selection |
protected ModeMatrix |
modes_
The ModeMatrix that this TableModel represents |
protected static int |
N_COLUMNS
The number of table columns |
protected boolean[] |
selectedModeKeys_
An array of the selected mode keys |
| Fields inherited from class javax.swing.table.AbstractTableModel |
|---|
listenerList |
| Constructor Summary | |
|---|---|
ModeTableModel()
Constructs a default ModeTableModel with no modes. |
| Method Summary | |
|---|---|
void |
deselectAllModeKeys()
Deselects all currently stored modes. |
java.lang.Class |
getColumnClass(int columnIndex)
|
int |
getColumnCount()
|
java.lang.String |
getColumnName(int columnIndex)
|
int |
getModeCount()
A convenience method which wraps ModeMatrix.getModeCount() . |
ModeMatrix |
getModes()
Returns the currently stored ModeMatrix . |
int |
getNodeCount()
A convenience method which wraps ModeMatrix.getNodeCount() . |
int |
getRowCount()
A convenience method which wraps AbstractMatrix.getRowCount() . |
KeyList |
getSelectedModeKeys()
Returns the KeyList of the currently selected modes. |
java.lang.Object |
getValueAt(int rowIndex,
int columnIndex)
|
boolean |
hasModeKeys()
Tests if this ModeTableModel has selected any modes. |
boolean |
hasModes()
Tests if this ModeTableModel is storing any modes. |
void |
importModes(java.io.File fileName)
Selects the appropriate ModeReader for the given file and imports
all modes contained in the file. |
boolean |
isCellEditable(int rowIndex,
int columnIndex)
|
void |
selectAllModeKeys()
Selects all currently stored modes. |
void |
setValueAt(java.lang.Object aValue,
int rowIndex,
int columnIndex)
|
| Methods inherited from class javax.swing.table.AbstractTableModel |
|---|
addTableModelListener, findColumn, fireTableCellUpdated, fireTableChanged, fireTableDataChanged, fireTableRowsDeleted, fireTableRowsInserted, fireTableRowsUpdated, fireTableStructureChanged, getListeners, getTableModelListeners, removeTableModelListener |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Methods inherited from interface javax.swing.table.TableModel |
|---|
addTableModelListener, removeTableModelListener |
| Field Detail |
|---|
protected static final int MODE_FREQUENCY_INDEX
protected static final int MODE_NAME_INDEX
protected static final int MODE_SELECTED_INDEX
protected ModeMatrix modes_
ModeMatrix
that this TableModel
represents
protected static final int N_COLUMNS
protected boolean[] selectedModeKeys_
| Constructor Detail |
|---|
public ModeTableModel()
ModeTableModel
with no modes.
| Method Detail |
|---|
public void deselectAllModeKeys()
public java.lang.Class getColumnClass(int columnIndex)
getColumnClass
in interface javax.swing.table.TableModel
getColumnClass
in class javax.swing.table.AbstractTableModel
public int getColumnCount()
getColumnCount
in interface javax.swing.table.TableModel
public java.lang.String getColumnName(int columnIndex)
getColumnName
in interface javax.swing.table.TableModel
getColumnName
in class javax.swing.table.AbstractTableModel
public int getModeCount()
ModeMatrix.getModeCount()
.
public ModeMatrix getModes()
ModeMatrix
.
ModeMatrix
public int getNodeCount()
ModeMatrix.getNodeCount()
.
public int getRowCount()
AbstractMatrix.getRowCount()
.
getRowCount
in interface javax.swing.table.TableModel
public KeyList getSelectedModeKeys()
KeyList
of the currently selected modes.
KeyList
of the currently selected modespublic java.lang.Object getValueAt(int rowIndex, int columnIndex)
getValueAt
in interface javax.swing.table.TableModel
public boolean hasModeKeys()
ModeTableModel
has selected any modes.
true
if this ModeTableModel
has selected any
modes; false
otherwisepublic boolean hasModes()
ModeTableModel
is storing any modes.
true
if this ModeTableModel
stores any modes;
false
otherwisepublic void importModes(java.io.File fileName) throws java.io.FileNotFoundException, java.io.IOException
ModeReader
for the given file and imports
all modes contained in the file.
fileName
- the file to be imported
java.io.FileNotFoundException
- if the file could not be found
java.io.IOException
- if the file could not be readpublic boolean isCellEditable(int rowIndex, int columnIndex)
isCellEditable
in interface javax.swing.table.TableModel
isCellEditable
in class javax.swing.table.AbstractTableModel
public void selectAllModeKeys()
public void setValueAt(java.lang.Object aValue, int rowIndex, int columnIndex)
setValueAt
in interface javax.swing.table.TableModel
setValueAt
in class javax.swing.table.AbstractTableModel
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |


-
-
PrimeBee
Built a smart assistant for Rakathon 2018 held at Bangalore. Rakathon is the annual hackathon conducted by Rakuten.
-
Multi-Lingual Offline Digit Recognizer
Currently working on a research project to perform speech recognition offline. The system is designed to help users (especially blind) dial phone numbers spoken in multiple languages
-
Driver Drowsiness Detection
Designed a plug and play module using Raspberry Pi, to prevent road accidents by monitoring the driver’s face & eyes and alerting him/her if they appear to be sleepy. The aim was to bring functionality found in expensive cars to any vehicle.
-
E-commerce Website
Built a fully functional E-commerce website as part of Database Management Systems Course using the SEAN(SQL Express AngularJS NodeJs) stack. The project involved making ER Diagrams to represent the different entities and their relationships and finally implementing them in SQL. A REST API was built using Express Framework to perform all the CRUD operations.
-
-
Askuspal
Lead a team, The Statesmen, to the finals of Finnovatica 2018, a FinTech Hackathon, where we built an interest free credit system for college students. Askuspal is an all-in-one assistant app that utilises the commissions the user generates to pay off the user's interest.
-
Gramophone
A music streaming website built as part of Web Technologies Course Project. This was my entry point into web technologies and was built from scratch using plain JavaScript, PHP, HTML and CSS.
-
Number Plate Recognition System
Developed a surveillance system that performs real time number plate detection and recognition from CCTV footage. The system was designed to work with Indian Number plates which have a huge variability in fonts, dimensions, position etc.
-
Gesture Remote
Developed a Python App that converts hand gestures to IR signals which can then be used to control any IR based device.
-
-
Signature Verification
Developed a Python app to curb down forgery by classifying a signature as forged or genuine. Extracted features from a scanned signature by various Image Processing Methods & calculated a similarity score for a given signature.
-
Fruit Harvester
Led a team to build a robot that harvests fruits based on their colour as part of the final project of JED-i. The robot was to decide which fruits were ripe and which weren't and pluck only those that were ripe.


name: main-template layout: true class: left, top, inverse --- class: center
# Composing an App with # Free Monads (using Cats)
## © 2018 Hermann Hueck
https://github.com/hermannhueck/free-monad-app --- # Abstract
In this talk I will explain what Free Monads are and how to use them (using the Cats implementation). After having shown the basics I build a small app by composing several Free Monads to a small program. I discuss the pros and cons of this technique. Finally I will demonstrate how to avoid some boilerplate with the *FreeK* library. --- # Agenda
1. Free Monads - what they are. 2. Free Monad Recipe 3. Extending your DSL 4. *FunctionK* and Natural Transformation 5. More Interpreters 6. Partial Lifting with *Free.inject* 7. Composing two DSLs and two Interpreters 8. Composing three DSLs and three Interpreters 9. Routing the workflow through DSLs 10. Pros & Cons 11. The *FreeK* library 12. Resources --- class: middle, center # 1. Free Monad - What is it?
--- ## Free Monad - What is it?
A free monad is a construction which allows you to build a monad from any ADT with a type parameter. Like other monads, it is a pure way to represent and manipulate computations. In particular, free monads provide a practical way to: - represent stateful computations as data, and run them - run recursive computations in a stack-safe way - build an embedded DSL (domain-specific language) - retarget a computation to another interpreter using natural transformations (https://typelevel.org/cats/datatypes/freemonad.html) --- class: middle, center # 2. Free Monad Recipe
.footnote[ See: *app1.MyApp* ] --- ## Recipe, how to proceed ...
1. Study your topic/domain/use case. Which operations do you need? 2. Create an ADT (algebraic data type) for the operations (computions as data) 3. "Lift" your ADT into the Free Monad, i.e. use the Free Monad to implement a smart constructor (lowercased function) for each element of your ADT. This is your DSL. 4. Write one or more interpreters for your DSL (using natural transformation) 5. Build a program using the DSL (typically a for comprehension). The program is not executable. 6. Execute the program with one of your interpreters. --- ## Step 1: Study your topic / domain / use case.
Which operations do you need? In this very simple exmaple we want to interact with a user at a terminal. We want to print an output string to the terminal or get a string of user input from the terminal. Operations: - PRINT LINE: displays an output string to the user and returns nothing - GET LINE: returns an input string entered by the user --- ## Step 2: Create an ADT for the operations
```scala // Algebra as an ADT - one type param for the return type trait Inout[A] final case class Printline(out: String) extends Inout[Unit] case object Getline extends Inout[String] ````
Note:
The trait's type parameter represents the return type of an operation.
The *Printline* operation returns nothing, hence it extends *Inout[Unit]*.
The *Getline* operation returns a String, hence it extends *Inout[String]*. The ADT is just
__computations as data__
. You cannot use them for program execution, you cannot invoke them. --- ## Step 3: "Lift" your ADT into the Free Monad
```scala // DSL def printline(out: String): Free[Inout, Unit] = Free.liftF(Printline(out)) def getline: Free[Inout, String] = Free.liftF(Getline) ``` Implement a smart constructor (lowercased function) for each element of your ADT. This is your DSL. Later we will also use *Free.inject* instead of *Free.liftF*. --- ## Step 4: Write an interpreter for the DSL
```scala // interpreter object ConsoleInterpreter extends (Inout ~> Id) { override def apply[A](fa: Inout[A]): Id[A] = fa match { case Printline(out) => println(out) () : Id[Unit] case Getline => val in = scala.io.StdIn.readLine() in : Id[String] } } ``` Every interpreter is/extends a natural transformation from your DSL monad (Inout) to a target monad (Id). The squiggly arrow is a shortcut for the natural transformation *FunctionK*. (More on that later in this presentation) An Interpreter must implement the apply method and is typically a pattern match over the case classes of the ADT. You can write more than one interpreter for the same ADT. --- ## Step 5: Build a program using the DSL
```scala // program definition (does nothing) def prog: Free[Inout, (String, Int)] = for { _ <- printline("What's your name?") name <- getline _ <- printline("What's your age?") age <- getline _ <- printline(s"Hello $name! Your age is $age!") } yield (name, age.toInt) ```` The program is not executable. The program can be written with map and flatMap, but is typically a for comprehension written in your DSL. The programs return type is a *Free[MyADT, RESULT]*. --- ## Step 6: Execute the program
```scala // Execute program with ConsoleInterpreter val result: Id[(String, Int)] = prog.foldMap(ConsoleInterpreter) println(s"result = $result") ```` Use *Free.foldMap(...)* to execute the program with a specific intrpreter.
Note:
*Free.foldMap* internally uses a technique called Tranpolining. Trampolining makes the Free Monads stack-safe. No *StackOverflowError*! --- class: middle, center # 3. Extending your DSL
.footnote[ See: *app2.MyApp* ] --- ## Extending your DSL
Write a small function as a for comprehension or with map/flatMap. ```scala def printline(out: String): Free[Inout, Unit] = Free.liftF(Printline(out)) def getline: Free[Inout, String] = Free.liftF(Getline) def ask(prompt: String): Free[Inout, String] = for { _ <- printline(prompt) input <- getline } yield input def ask2(prompt: String): Free[Inout, String] = // same with flatMap printline(prompt).flatMap(_ => getline) ```
This allows you to simplify programs written in this DSL. ```scala def prog: Free[Inout, (String, Int)] = for { name <- ask("What's your name?") age <- ask("What's your age?") _ <- printline(s"Hello $name! Your age is $age!") } yield (name, age.toInt) ``` --- class: middle, center # 4. *FunctionK* and # Natural Transformation
--- ## FunctionK See also: https://typelevel.org/cats/datatypes/functionk.html
*Function1[-A, +B]* takes an *A* and returns a *B*.
Shortcut: *A => B*
```scala trait Function1[-A, +B] { def apply(a: A): B } ``` *FunctionK[F[\_], G[\_]]* takes an *F[A]* and returns a *G[A]*.
Shortcut: *F ~> G*
```scala trait FunctionK[F[_], G[_]] { def apply[A](fa: F[A]): G[A] } ``` --- ## FunctionK
__Function1:__ A --> [A => B] --> B
"hello" --> _.length --> 5
A *Function1* changes a value.
__FunctionK:__ F[A] --> [F ~> G] --> G[B]
List(1, 2) --> _.headOption --> Some(1)
A *FunctionK* changes the context. --- ## Natural Transformation
If the contexts *F* and *G* are Functors, the context conversion is called
__Natural Transformation__
or
__Functor Transformation__
. --- name: FunctionK_4 ## FunctionK In analogy to *Function1* *FunctionK* also provides methods *compose* and *andThen*. It also provides a method 'or' which allows to compose two *FunctionK*s, i.e. two interpreters. (We will use them later.) ```scala trait FunctionK[F[_], G[_]] { self => // Applies this functor transformation from `F` to `G` def apply[A](fa: F[A]): G[A] // Composes two instances of FunctionK into a new FunctionK with this // transformation applied last. def compose[E[_]](f: FunctionK[E, F]): FunctionK[E, G] = ??? // Composes two instances of FunctionK into a new FunctionK with this // transformation applied first. def andThen[H[_]](f: FunctionK[G, H]): FunctionK[F, H] = f.compose(self) // Composes two instances of FunctionK into a new FunctionK that transforms // a [[cats.data.EitherK]] to a single functor. // This transformation will be used to transform left `F` values while // `h` will be used to transform right `H` values. def or[H[_]](h: FunctionK[H, G]): FunctionK[EitherK[F, H, ?], G] = ??? } ``` See: [Usage of *FunctionK.or*](#ComposeDSLs_4)
See: [Usage of *FunctionK.andThen*](#Routing_1) --- class: middle, center # 5. More Interpreters
.footnote[ See: *app3.MyApp* ] --- ## More Interpreters
We can provide several interpreters for the same ADT / DSL. We can execute a programm written in a DSL with different interpreters for that DSL. --- ## More Interpreters
```scala object ConsoleInterpreter extends (Inout ~> Id) { override def apply[A](fa: Inout[A]): Id[A] = ??? } object AsyncInterpreter extends (Inout ~> Future) { override def apply[A](fa: Inout[A]): Future[A] = ??? } class TestInterpreter(inputs: ListBuffer[String], outputs: ListBuffer[String]) extends (Inout ~> Id) { override def apply[A](fa: Inout[A]): Id[A] = ??? } def prog: Free[Inout, (String, Int)] = for { name <- ask("What's your name?") age <- ask("What's your age?") _ <- printline(s"Hello $name! Your age is $age!") } yield (name, age.toInt) val result: Id[(String, Int)] = prog.foldMap(ConsoleInterpreter) val futureResult: Future[(String, Int)] = prog.foldMap(AsyncInterpreter) val testResult: Id[(String, Int)] = prog.foldMap(new TestInterpreter(inputs, outputs)) ``` --- class: middle, center # 6. Partial Lifting # with *Free.inject*
.footnote[ See: *app3a.MyApp* ] --- ## *Free.inject* instead of *Free.liftF* (1/4)
DSL lifted with *Free.liftF* ```scala def printline(out: String): Free[Inout, Unit] = Free.liftF(Printline(out)) def getline: Free[Inout, String] = Free.liftF(Getline) def ask(prompt: String): Free[Inout, String] = printline(prompt).flatMap(_ => getline) ``` DSL partially lifted with *Free.inject* ```scala class IoOps[F[_]](implicit IO: InjectK[Inout, F]) { def printline(out: String): Free[F, Unit] = Free.inject[Inout, F](Printline(out)) def getline: Free[F, String] = Free.inject[Inout, F](Getline) def ask(prompt: String): Free[F, String] = printline(prompt).flatMap(_ => getline) } object IoOps { // provides an instance of IoOps in implicit scope implicit def ioOps[F[_]]( implicit IO: InjectK[Inout, F]): IoOps[F] = new IoOps[F] } ``` *F[_]* is a place holder for another DSL, into which Inout will be injected. --- ## *Free.inject* instead of *Free.liftF* (2/4)
- Instead of providing the DSL functions directly, pack them into a class. - In the class constructor provide an implicit *InjectK[YourDSL, F]*. (*F[_]* is a place holder for some DSL that we provide later.) - Implement the DSL functions inside the class with *Free.inject*. - Implement the DSL extension function (*ask*) also inside the new class. - Provide an implicit instance of this class inside the companion object of the class (= implicit scope). This is a bit more boilerplate than before.
But it gives us
more flexibility for DSL composition
, as we will see later. --- ## *Free.inject* instead of *Free.liftF* (3/4)
Program for DSL with *Free.liftF*: ```scala def prog: Free[Inout, (String, Int)] = for { name <- ask("What's your name?") age <- ask("What's your age?") _ <- printline(s"Hello $name! Your age is $age!") } yield (name, age.toInt) ```
Program for DSL with *Free.inject*: ```scala def prog(implicit io: IoOps[Inout]): Free[Inout, (String, Int)] = for { name <- io.ask("What's your name?") age <- io.ask("What's your age?") _ <- io.printline(s"Hello $name! Your age is $age!") } yield (name, age.toInt) ``` --- ## *Free.inject* instead of *Free.liftF* (4/4)
In the definition of *IoOps* we already defined an *Inout* as the first type parameter of *InjectK[Inout, F]*. Here in the program definition we replace the place holder DSL *F* with the higher kinded type of another DSL, which in this case is also Inout. We have composed *Inout* with another *Inout*. The benefit of this technique becomes obvious shortly.
We will create one composed DSL out of two different component DSLs. --- class: middle, center # 7. Composing two DSLs # and two Interpreters
.footnote[ See: *app4.MyApp* ] --- ## Two DSLs .left-column-50[ ### Inout ```scala trait Inout[A] final case class Printline(out: String) extends Inout[Unit] final case object Getline extends Inout[String] class IoOps[F[_]]( implicit IO: InjectK[Inout, F]) { def printline(out: String) = Free.inject(Printline(out)) def getline = Free.inject(Getline) def ask(prompt: String) = printline(prompt) .flatMap(_ => getline) } object IoOps { implicit def ioOps[F[_]]( implicit IO: InjectK[Inout, F]) = new IoOps[F] } ``` ] .right-column-50[ ### KVStore ```scala trait KVStore[A] final case class Put(key: String, value: Int) extends KVStore[Unit] final case class Get(key: String ) extends KVStore[Option[Int]] final case class Delete(key: String ) extends KVStore[Option[Int]] class KVSOps[F[_]]( implicit KV: InjectK[KVStore, F]) { def put(key: String, value: Int) = Free.inject(Put(key: String, value: Int)) def get(key: String) = Free.inject(Get(key: String)) def delete(key: String) = Free.inject(Delete(key: String)) } object KVSOps { implicit def kvsOps[F[_]]( implicit IO: InjectK[KVStore, F]) = new KVSOps[F] } ``` ] --- ## Two Interpreters .left-column-50[ ### Inout ```scala object ConsoleInterpreter extends (Inout ~> Id) { override def apply[A](fa: Inout[A] ): Id[A] = fa match { case Printline(out) => println(out) (): Id[Unit] case Getline => val in = scala.io.StdIn.readLine() in: Id[String] } } ``` ] .right-column-50[ ### KVStore ```scala object KVSInterpreter extends (dsl.KVStore ~> Id) { var kvs: Map[String, Int] = Map.empty override def apply[A](fa: KVStore[A] ): Id[A] = fa match { case Put(key, value) => kvs = kvs.updated(key, value) (): Id[Unit] case Get(key) => kvs.get(key): Id[Option[Int]] case Delete(key) => val value = kvs.get(key) kvs = kvs - key value: Id[Option[Int]] } } ``` ]
Note:
Both interpreters have the same target type: *Id* --- name: ComposeDSLs_4 ## Composing DSLs and interpreters ```scala type AppDSL[A] = EitherK[Inout, KVStore, A] def prog(implicit io: IoOps[AppDSL], kvs: KVSOps[AppDSL]): Free[AppDSL, (String, Option[Int])] = { for { name <- io.ask("What's your name?") age <- io.ask("What's your age?") _ <- kvs.put(name, age.toInt) _ <- io.printline(s"Hello $name! Your age is $age!") optAge <- kvs.get(name) } yield (name, optAge) } val composedInterpreter: AppDSL ~> Id = (ConsoleInterpreter: Inout ~> Id) or (KVSInterpreter: KVStore ~> Id) val result: Id[(String, Option[Int])] = prog.foldMap(composedInterpreter) ``` - Define a type alias for an *EitherK* with two ADTs - Provide DSLs as implicit parameters to your program - The two component interpreters must have the same target type as the composed interpreter (*Id* in our case). - The composition order of interpreters must be the same as the composition order of the DSLS.
See: [Definition of *FunctionK*](#FunctionK_4) --- ## EitherK (= Coproduct)
*Either* is parameterized with two types *A* and *B*.
*A* is the type of the *Left*, *B* the type of the *Right*. ```scala sealed abstract class Either[+A, +B] ... { ... } ``` *EitherK* is parameterized with two type constructors *F[\_]* and *G[\_]* and a regular type *A*. It's a case class wrapping a value called *run* of type *Either[F[A], G[A]]*. ```scala final case class EitherK[F[_], G[_], A](run: Either[F[A], G[A]]) { // ... } ``` *EitherK* is used to define a composed DSL. In our example we define *AppDSL* as an *EitherK*: ```scala type AppDSL[A] = EitherK[Inout, KVStore, A] ``` --- ## Partial Lifting with *InjectK* (1/2)
*InjectK* is used for partial lifting into a Free Monad for the composed DSL. In class IoOps *Free.inject* internally injects the *Inout* into *InjectK[Inout, F]*, where the place holder F will be replaced by *AppDSL*. In class *KVSOps* *Free.inject* internally injects the *KVStore* into *InjectK[KVStore, F]*, where the place holder *F* will be replaced by *AppDSL*. ```scala // simplified def of inject object Free { def inject[F[_], G[_], A](fa: F[A])(implicit I: InjectK[F, G]): Free[G, A] = liftF(I.inj(fa)) } ``` --- ## Partial Lifting with *InjectK* (2/2)
```scala class IoOps[F[_]](implicit IO: InjectK[Inout, F]) { def printline(out: String): Free[F, Unit] = Free.inject[Inout, F](Printline(out)) // ... } class KVSOps[F[_]](implicit KV: InjectK[KVStore, F]) { def get(key: String): Free[F, Option[Int]] = Free.inject[KVStore, F](Get(key: String)) // ... } type AppDSL[A] = EitherK[Inout, KVStore, A] def prog(implicit io: IoOps[AppDSL], kvs: KVSOps[AppDSL]): Free[AppDSL, (String, Option[Int])] = ??? ``` In the implicit parameters we fill the place holder *F* with the concrete type *AppDSL* ( = *EitherK[Inout, KVStore, ?]* ). .note[ For more details see: *app4a.MyApp* ] --- class: middle, center # 8. Composing three DSLs # and three Interpreters
.footnote[ See: *app5.MyApp* ] --- ## Third DSL and Interpreter
Our 3rd DSL and corresponding interpreter(s) is for monotonic sequence number generation.
```scala sealed trait Sequence[A] case object NextId extends Sequence[Long] class SeqOps[F[_]](implicit KV: InjectK[Sequence, F]) { def nextId: Free[F, Long] = Free.inject[Sequence, F](NextId) def nextStringId: Free[F, String] = nextId.map(_.toString) } object SeqOps { implicit def seqOps[F[_]](implicit IO: InjectK[Sequence, F]): SeqOps[F] = new SeqOps[F] } ``` --- ## Composing three DSLs and three Interpreters - Compose 3 DSLs with 2 type aliases. - Compose interpreters in the same order as the DSLs. - All component interpreters must have the same target type as the composed interpreter (*Id* in our case). ```scala type AppDSL0[A] = EitherK[Inout, KVStore, A] type AppDSL[A] = EitherK[Sequence, AppDSL0, A] def prog(implicit io: IoOps[AppDSL], kvs: KVSOps[AppDSL], seq: SeqOps[AppDSL]): Free[AppDSL, (String, Option[Cat])] = { for { name <- io.ask("What's your name?") age <- io.ask("What's your age?") id <- seq.nextId.map(_.toString) _ <- kvs.put(id, Cat(id, name, age.toInt)) _ <- io.printline(s"Hello cat $name! Your age is $age!") optCat <- kvs.get(id) } yield (id, optCat) } // compose interpreters in the same order as DSLs val appInterpreter: AppDSL ~> Id = SeqInterpreter or (ConsoleInterpreter or KVSInterpreter) val result: Id[(String, Option[Cat])] = prog.foldMap(appInterpreter) println(s"result = $result") ``` --- class: middle, center # 9. Routing the workflow # through DSLs
.footnote[ See: *app6.MyApp* ] --- ## Logging DSL
In the next evolution step of the program we create a new DSL for logging and the corresponding interpreters(s). (interpreter code not shown here)
```scala sealed trait Log[A] extends Product with Serializable final case class Info(msg: String) extends Log[Unit] final case class Warn(msg: String) extends Log[Unit] final case class Error(msg: String) extends Log[Unit] class LogOps[F[_]](implicit LG: InjectK[Log, F]) { def info(msg: String): Free[F, Unit] = Free.inject[Log, F](Info(msg)) def warn(msg: String): Free[F, Unit] = Free.inject[Log, F](Warn(msg)) def error(msg: String): Free[F, Unit] = Free.inject[Log, F](Error(msg)) } object LogOps { implicit def logOps[F[_]](implicit LG: InjectK[Log, F]): LogOps[F] = new LogOps[F] } ``` --- ## Routing the workflow through DSLs (1/2)
- We create a composed DSL from *KVStore*, *Sequence* and *Logging*. - We create new DSL *CatManagement* (cats management business logic). - The *CatManagement* interpreter is implemented with the above composed interpreter. It routes requests to the other interpreters. - The main program is implemented in a DSL composed of *Inout* and *CatManagement*.
--- ## Routing the workflow through DSLs (2/2)
----------------
| AppDSL |
----------------
|
---------------------------- Composition
| |
------------ -----------------------------
| Inout | | CatManagement |
------------ -----------------------------
| Routing
--------------------------
| ComposedDSL |
--------------------------
|
------------------------------------------------ Composition
| | |
---------------- ---------------- ------------------
| Logging | | KVStore | | Sequence |
---------------- ---------------- ------------------
--- ## Composing a DSL from *KVStore*, *Sequence* and *Logging*
We compose DSLs and interpreters as we did before.
Component and composed interpreters again with same target type: *Id*
```scala // component interpreters, all having target type Id object LogInterpreter extends (Log ~> Id) { ... } object SeqInterpreter extends (Sequence ~> Id) { ... } object KvsInterpreter extends (KVStore ~> Id) { ... } // compose DSLs type ComposedDSL0[A] = EitherK[Sequence, KVStore, A] type ComposedDSL[A] = EitherK[Log, ComposedDSL0, A] // composed interpreter also with target type Id val ComposedLogSeqKvsInterpreter: ComposedDSL ~> Id = LogInterpreter or (SeqInterpreter or KvsInterpreter) ``` --- ## Lifting the composed DSL into a Free Monad
We need a monad for the natural transformation from the composed DSL to *Id*. By creating a type alias we lift *ComposedDSL* into the Free Monad. Then we define a new interpreter that translates from *FreeComposed ~> Id* by *foldMap*ping the interpreter we composed before.
```scala // type alias for the Free Monad of the composed DSL type FreeComposed[A] = Free[ComposedDSL, A] // interpreter that translated from the composed Free Monad to the Id Monad object FreeComposedLogSeqKvsInterpreter extends (FreeComposed ~> Id) { override def apply[A](fa: FreeComposed[A]): Id[A] = fa.foldMap(ComposedLogSeqKvsInterpreter) } ``` --- ## CatManagement DSL
```scala sealed trait CatManagement[A] extends Product with Serializable final case class Create(cat: Cat) extends CatManagement[Cat] final case class UpdateById(cat: Cat) extends CatManagement[Cat] final case class DeleteById(id: String) extends CatManagement[Boolean] final case class FindById(id: String) extends CatManagement[Option[Cat]] final case class FindByName(name: String) extends CatManagement[List[Cat]] case object FindAll extends CatManagement[List[Cat]] class CatOps[F[_]](implicit KV: InjectK[CatManagement, F]) { def create(cat: Cat): Free[F, Cat] = Free.inject[CatManagement, F](Create(cat)) def updateById(cat: Cat): Free[F, Cat] = Free.inject[CatManagement, F](UpdateById(cat)) def deleteById(id: String): Free[F, Boolean] = Free.inject[CatManagement, F](DeleteById(id)) def findById(id: String): Free[F, Option[Cat]] = Free.inject[CatManagement, F](FindById(id)) def findByName(name: String): Free[F, List[Cat]] = Free.inject[CatManagement, F](FindByName(name)) def findAll: Free[F, List[Cat]] = Free.inject[CatManagement, F](FindAll) } object CatOps { implicit def catOps[F[_]](implicit CM: InjectK[CatManagement, F]): CatOps[F] = new CatOps[F] } ``` --- ## CatLogicInterpreter (1/2)
*CatLogicInterpreter* transforms from *CatManagement ~> FreeComposed* and is implemented with the DSL composed from *Logging*, *Sequence* and *KVStore*.
```scala class CatLogicInterpreter(implicit log: LogOps[ComposedDSL], seq: SeqOps[ComposedDSL], kvs: KVSOps[ComposedDSL]) extends (CatManagement ~> FreeComposed) { override def apply[A](fa: CatManagement[A]): FreeComposed[A] = fa match { case Create(cat) => kvsCreate(cat): FreeComposed[Cat] case UpdateById(cat) => kvsUpdateById(cat): FreeComposed[Cat] case DeleteById(id) => kvsDeleteById(id): FreeComposed[Boolean] case FindById(id) => kvsFindById(id): FreeComposed[Option[Cat]] case FindByName(name) => kvsFindByName(name): FreeComposed[List[Cat]] case FindAll => kvsFindAll: FreeComposed[List[Cat]] } // ... ``` --- ## CatLogicInterpreter (2/2)
```scala // ... private def kvsFindAll[A]: FreeComposed[List[Cat]] = kvs.getAll private def kvsFindById[A](id: String): FreeComposed[Option[Cat]] = kvs.get(id) private def kvsFindByName[A](name: String): FreeComposed[List[Cat]] = kvs.getAll.map(_.filter(_.name == name)) private def kvsCreate[A](cat: Cat): FreeComposed[Cat] = for { maybeCat <- kvs.get(cat.id) _ = if (maybeCat.isDefined) { val message = s"cat with id ${cat.id} already exists" log.error(message) throw new RuntimeException(message) } newId <- seq.nextStringId _ <- kvs.put(newId, cat.copy(id = newId)) newMaybeCat <- kvs.get(newId) _ <- log.info(s"Created: $cat") } yield newMaybeCat.get // ... } ``` --- name: Routing_1 ## Routing from one interpreter to the next
*CatLogicInterpreter* provides a natural transformation (*CatManagement ~> Id*). It transforms (*CatManagement ~> FreeComposed*)
*__andThen__*
propagates to *FreeComposedInterpreter* which transforms (*FreeComposed ~> Id*).
```scala // Routing with FunctionK.andThen val CatLogicInterpreter: CatManagement ~> Id = new CatLogicInterpreter andThen FreeComposedLogSeqKvsInterpreter ```
See: [Definition of *FunctionK*](#FunctionK_4) --- ## Program definition and execution
Technically nothing new here (just DSL composition).
```scala type AppDSL[A] = EitherK[CatManagement, Inout, A] def prog(implicit io: Inouts[AppDSL], co: CatOps[AppDSL]): Free[AppDSL, Option[Cat]] = { for { name <- io.ask("Cat's name?") age <- io.ask("Cat's age?") cat <- co.create(Cat(name, age.toInt)) newAge <- io.ask("That was a lie! Tell me the correct age!") _ <- co.updateById(cat.copy(age = newAge.toInt)) _ <- io.printline(s"Hello cat ${cat.name}! Your age is ${cat.age}!") optCat <- co.findById(cat.id) } yield optCat } val result: Id[Option[Cat]] = prog1.foldMap(CatLogicInterpreter or ConsoleInterpreter) println(s"result = $result") ``` --- class: middle, center # 10. Pros & Cons
.footnote[ .left[ See the following video presentations:
Rather on the Pro side:
[Chris Myers' Talk on Free Monads at Typelevel Summit Oslo, 2016](#Resources_2)
Rather on the Cons side:
[Kelly Robinson's Talk on Free Monads at Scala Days Berlin, 2016](#Resources_2) ] ] --- ## Pros
-- - FMs let us create a Monad from any (parameterized) ADT. -- - FMs let us write programs in monadic style (for comprehensions) -- - Decoupled program description and execution/interpretation -- - It is easy to add new ADTs/DSLs. -- - It is easy to add new interpreters for existing ADTs/DSLs. -- - E.g.: Implement different interpreters for prod and test. -- - FMs are stack-safe (due to an internally used technique:
Trampolining
). --- ## Cons
-- - Advanced technology not easily understood. -- - Danger of over-enginieering -- - Possible performance cost
-- To minimize drawbacks:
-- - Be aware of the skill level of your team maintaining the code. -- - Consider using FMs only in library code or in well encapsulated modules. --- ## Principle of Least Power
__Given a choice of solutions,__
__pick the least powerful solution__
__capable of solving your problem.__ \-- Li Haoyi --- class: middle, center # 11. Easing Free Monads with *FreeK*
.footnote[ See: *app5freek.MyApp* ] --- ## *FreeK* - What is it?
It is a library, implemented with Shapeless,
designed to remove some of the boilerplate from your Free Monad code.
- Write only ADTs, no lifting, no injecting - Simplified composition of DSLs - Simplified composition of interpreters --- ## *FreeK* Example: *app5freek.MyApp* (1/2)
```scala // Algebra as an ADT trait Inout[A] final case class Printline(out: String) extends Inout[Unit] final case object Getline extends Inout[String] // DSL to be omitted. No lifting or injecting needed with Freek // ask is a small subroutine written with FreeK type PRG = Inout :|: NilDSL val prg = DSL.Make[PRG] def ask(prompt: String): Free[prg.Cop, String] = for { _ <- Printline(prompt).freek[PRG] input <- Getline.freek[PRG] } yield input def ask2(prompt: String): Free[prg.Cop, String] = Printline(prompt).freek[PRG].flatMap(_ => Getline.freek[PRG]) ``` --- ## *FreeK* Example: *app5freek.MyApp* (2/2)
```scala type AppDSL = Inout :|: KVStore :|: Sequence :|: NilDSL val appDSL = DSL.Make[AppDSL] // infer the right coproduct for AppDSL def prog: Free[appDSL.Cop, (String, Option[Cat])] = { for { name <- ask("What's your name?").expand[AppDSL] // ask must be expanded age <- ask("What's your age?").expand[AppDSL] // to Printline/Getline idLong <- NextId.freek[AppDSL] // freek performs the heavy lifting id = idLong.toString _ <- Put(id, Cat(id, name, age.toInt)).freek[AppDSL] _ <- Printline(s"Hello cat $name! Your age is $age!").freek[AppDSL] optCat <- Get(id).freek[AppDSL] } yield (id, optCat) } // program execution with foldMap or with interpret val composedInterpreter = ConsoleInterpreter :&: KVSInterpreter :&: SeqInterpreter // foldMap is order-sensitive val result1: Id[(String, Option[Cat])] = prog.foldMap(composedInterpreter.nat) println(s"result1 = $result1") // interpret is order-agnostic val result2: Id[(String, Option[Cat])] = prog.interpret(composedInterpreter) println(s"result2 = $result2") ``` --- ## *FreeK* - Howto in a nutshell
-- - Write your ADTs as before -- - Remove all the DSL generation code using *Free.liftF* and *Free.inject*. -- - Write your interpreters as before. -- - Type alias composed *AppDSL* with the *:|:* operator with *NilDSL* at the end. -- - The program doesn't need implicit parameters. -- - "Invoke" the uppercase case class constructors (*Getline* instead of *getline*). -- - Append an invocation of *freek[AppDSL]* (for the "heavy lifting"). -- - Append *expand[AppDSL]* to your own subroutines (such as *ask*). -- - Compose interpreters with the *:&:* operator. -- - Program execution: use *prog.foldMap(myInterpreter.nat)*. *foldMap* is order-sensitive. -- - Or: Use *prog.interpret(myInterpreter)* and omit the appendix *.nat*. *interpret* is order-agnostic.
-- Detailed info about *FreeK* at: https://github.com/ProjectSeptemberInc/freek --- class: middle, center # 12. Resources --- name: Resources_1 ## Resources (1/3) - basic
- Code and Slides of this Talk:
https://github.com/hermannhueck/free-monad-app - Cats documentation on Free Monads:
https://typelevel.org/cats/datatypes/freemonad.html - Blog post on Free Monads by Pere Villega:
http://perevillega.com/understanding-free-monads - Blog post on FreeK by Pere Villega:
http://perevillega.com/freek-and-free-monads - The FreeK project on Github
https://github.com/ProjectSeptemberInc/freek --- name: Resources_2 ## Resources (2/3) - basic
- "A Year living Freely"
Chris Myers' Talk on Free Monads at Typelevel Summit Oslo, 2016
https://www.youtube.com/watch?v=rK53C-xyPWw - "Why the free Monad isn't free"
Kelly Robinson's Talk on Free Monads at Scala Days Berlin, 2016
https://www.youtube.com/watch?v=U0lK0hnbc4U - "Composable application architecture with reasonably priced monads"
Runar Bjarnason's Talk on Free Monads at Scala Days Berlin, 2014
https://www.youtube.com/watch?v=M258zVn4m2M --- name: Resources_3 ## Resources (3/3) - advanced
- Cats documentation on FunctionK:
https://typelevel.org/cats/datatypes/functionk.html - Cats documentation on Free Applicatives:
https://typelevel.org/cats/datatypes/freeapplicative.html - "Free as in Monads" - Daniel Spiewak implements Free Monads
Daniel Spiewak's live coding session at Northeast Scala Symposium, 2017
https://www.youtube.com/watch?v=H28QqxO7Ihc - "Move Over Free Monads: Make Way for Free Applicatives!"
John de Goes' Talk on Free Applicatives at Scala World, 2015
https://www.youtube.com/watch?v=H28QqxO7Ihc --- class: middle, center ## Thanks for Listening
# Q & A
https://github.com/hermannhueck/free-monad-app


| Alabama Crime
Rates 1960 -
2015
|
| Alabama Population
and Number of
Crimes
1960 -
2015 |
|
| Year |
Population |
Index |
Violent |
Property |
Murder |
Forcible |
Robbery |
Aggravated |
Burglary |
Larceny |
Vehicle |
|
|
|
|
|
|
Rape |
|
Assualt |
|
Theft |
Theft |
| 1960 |
3,266,740 |
39,920 |
6,097 |
33,823 |
406 |
281 |
898 |
4,512 |
11,626 |
19,344 |
2,853 |
| 1961 |
3,302,000 |
38,105 |
5,564 |
32,541 |
427 |
252 |
630 |
4,255 |
11,205 |
18,801 |
2,535 |
| 1962 |
3,358,000 |
41,112 |
5,283 |
35,829 |
316 |
218 |
754 |
3,995 |
11,722 |
21,306 |
2,801 |
| 1963 |
3,347,000 |
44,636 |
6,115 |
38,521 |
340 |
192 |
828 |
4,755 |
12,614 |
22,874 |
3,033 |
| 1964 |
3,407,000 |
53,550 |
7,260 |
46,290 |
316 |
397 |
992 |
5,555 |
15,898 |
26,713 |
3,679 |
| 1965 |
3,462,000 |
55,131 |
6,916 |
48,215 |
395 |
367 |
992 |
5,162 |
16,398 |
28,115 |
3,702 |
| 1966 |
3,517,000 |
61,838 |
8,098 |
53,740 |
384 |
341 |
1,124 |
6,249 |
18,551 |
30,583 |
4,606 |
| 1967 |
3,540,000 |
65,527 |
8,448 |
57,079 |
415 |
371 |
1,167 |
6,495 |
20,227 |
31,682 |
5,170 |
| 1968 |
3,566,000 |
71,285 |
8,288 |
62,997 |
421 |
396 |
1,462 |
6,009 |
22,403 |
34,508 |
6,086 |
| 1969 |
3,531,000 |
75,090 |
8,842 |
66,248 |
485 |
494 |
1,448 |
6,415 |
23,559 |
36,644 |
6,045 |
| Year |
Population |
Index |
Violent |
Property |
Murder |
Forcible |
Robbery |
Aggravated |
Burglary |
Larceny |
Vehicle |
|
|
|
|
|
|
Rape |
|
Assualt |
|
Theft |
Theft |
| 1970 |
3,444,165 |
85,399 |
10,185 |
75,214 |
404 |
637 |
1,731 |
7,413 |
26,739 |
40,779 |
7,696 |
| 1971 |
3,479,000 |
86,919 |
10,835 |
76,084 |
524 |
661 |
2,005 |
7,645 |
27,547 |
40,841 |
7,696 |
| 1972 |
3,510,000 |
84,047 |
10,994 |
73,053 |
496 |
660 |
2,407 |
7,431 |
27,714 |
38,493 |
6,846 |
| 1973 |
3,539,000 |
91,389 |
12,390 |
78,999 |
468 |
751 |
2,809 |
8,362 |
31,754 |
39,206 |
8,039 |
| 1974 |
3,577,000 |
107,314 |
13,338 |
93,976 |
536 |
811 |
3,562 |
8,429 |
37,841 |
46,813 |
9,322 |
| 1975 |
3,614,000 |
125,497 |
14,201 |
111,296 |
577 |
738 |
4,446 |
8,440 |
42,059 |
59,470 |
9,767 |
| 1976 |
3,665,000 |
139,573 |
14,248 |
125,325 |
553 |
794 |
3,520 |
9,381 |
42,879 |
72,832 |
9,614 |
| 1977 |
3,690,000 |
136,995 |
15,293 |
121,702 |
524 |
929 |
3,572 |
10,268 |
41,901 |
69,442 |
10,359 |
| 1978 |
3,742,000 |
147,389 |
15,682 |
131,707 |
499 |
954 |
3,708 |
10,521 |
46,001 |
74,387 |
11,319 |
| 1979 |
3,769,000 |
159,950 |
15,578 |
144,372 |
496 |
1,037 |
4,127 |
9,918 |
48,517 |
83,791 |
12,064 |
| Year |
Population |
Index |
Violent |
Property |
Murder |
Forcible |
Robbery |
Aggravated |
Burglary |
Larceny |
Vehicle |
|
|
|
|
|
|
Rape |
|
Assualt |
|
Theft |
Theft |
| 1980 |
3,861,466 |
190,511 |
17,320 |
173,191 |
509 |
1,158 |
5,102 |
10,551 |
58,952 |
102,029 |
12,210 |
| 1981 |
3,916,000 |
191,834 |
18,423 |
173,411 |
465 |
1,021 |
4,952 |
11,985 |
56,811 |
105,471 |
11,129 |
| 1982 |
3,943,000 |
182,701 |
17,653 |
165,048 |
417 |
1,026 |
4,417 |
11,793 |
49,531 |
104,740 |
10,777 |
| 1983 |
3,959,000 |
162,361 |
16,471 |
145,890 |
364 |
931 |
3,895 |
11,281 |
42,485 |
94,279 |
9,126 |
| 1984 |
3,990,000 |
155,691 |
17,204 |
138,487 |
374 |
1,002 |
3,833 |
11,995 |
39,970 |
89,198 |
9,319 |
| 1985 |
4,021,000 |
158,513 |
18,398 |
140,115 |
396 |
1,079 |
4,237 |
12,686 |
41,612 |
88,108 |
10,395 |
| 1986 |
4,053,000 |
173,807 |
22,616 |
151,191 |
409 |
1,150 |
4,523 |
16,534 |
46,974 |
93,396 |
10,821 |
| 1987 |
4,083,000 |
181,751 |
22,833 |
158,918 |
380 |
1,137 |
4,581 |
16,735 |
48,927 |
99,260 |
10,731 |
| 1988 |
4,127,000 |
188,261 |
23,052 |
165,209 |
408 |
1,228 |
4,860 |
16,556 |
50,920 |
103,282 |
11,007 |
| 1989 |
4,118,000 |
190,573 |
24,329 |
166,244 |
421 |
1,276 |
5,515 |
17,117 |
47,224 |
106,771 |
12,249 |
| Year |
Population |
Index |
Violent |
Property |
Murder |
Forcible |
Robbery |
Aggravated |
Burglary |
Larceny |
Vehicle |
|
|
|
|
|
|
Rape |
|
Assualt |
|
Theft |
Theft |
| 1990 |
4,040,587 |
198,604 |
28,630 |
169,974 |
467 |
1,319 |
5,805 |
21,039 |
44,585 |
111,336 |
14,053 |
| 1991 |
4,089,000 |
219,400 |
34,518 |
184,882 |
469 |
1,455 |
6,246 |
26,348 |
51,873 |
118,151 |
14,858 |
| 1992 |
4,136,000 |
217,889 |
36,052 |
181,837 |
455 |
1,704 |
6,819 |
27,074 |
49,053 |
117,801 |
14,983 |
| 1993 |
4,187,000 |
204,274 |
32,676 |
171,598 |
484 |
1,471 |
6,677 |
24,044 |
45,578 |
111,878 |
14,142 |
| 1994 |
4,219,000 |
206,859 |
28,844 |
178,015 |
501 |
1,487 |
7,223 |
19,633 |
44,064 |
119,951 |
14,000 |
| 1995 |
4,253,000 |
206,188 |
26,894 |
179,294 |
475 |
1,350 |
7,900 |
17,169 |
43,586 |
120,967 |
14,741 |
| 1996 |
4,273,000 |
205,962 |
24,159 |
181,803 |
444 |
1,397 |
7,124 |
15,194 |
42,821 |
123,350 |
15,632 |
| 1997 |
4,319,000 |
211,188 |
24,379 |
186,809 |
426 |
1,396 |
6,931 |
15,626 |
43,786 |
127,616 |
15,407 |
| 1998 |
4,352,000 |
200,065 |
22,286 |
177,779 |
354 |
1,443 |
5,698 |
14,791 |
41,965 |
120,943 |
14,871 |
| 1999 |
4,369,862 |
192,819 |
21,421 |
171,398 |
345 |
1,513 |
5,297 |
14,266 |
38,648 |
119,616 |
13,134 |
| Year |
Population |
Index |
Violent |
Property |
Murder |
Forcible |
Robbery |
Aggravated |
Burglary |
Larceny |
Vehicle |
|
|
|
|
|
|
Rape |
|
Assualt |
|
Theft |
Theft |
| 2000 |
4,447,100 |
202,159 |
21,620 |
180,539 |
329 |
1,482 |
5,702 |
14,107 |
40,331 |
127,399 |
12,809 |
| 2001 |
4,468,912 |
192,835 |
19,582 |
173,253 |
379 |
1,369 |
5,584 |
12,250 |
40,642 |
119,992 |
12,619 |
| 2002 |
4,478,869 |
200,331 |
19,931 |
180,400 |
303 |
1,664 |
5,962 |
12,002 |
42,578 |
123,932 |
13,890 |
| 2003 |
4,503,726 |
201,572 |
19,331 |
182,241 |
299 |
1,656 |
6,038 |
11,338 |
43,245 |
124,039 |
14,957 |
| 2004 |
4,525,375 |
201,664 |
19,324 |
182,340 |
254 |
1,742 |
6,042 |
11,286 |
44,666 |
123,650 |
14,024 |
| 2005 |
4,548,327 |
197,071 |
19,678 |
177,393 |
374 |
1,564 |
6,447 |
11,293 |
43,473 |
120,780 |
13,140 |
| 2006 |
4,599,030 |
200,578 |
19,557 |
181,021 |
382 |
1,649 |
7,059 |
10,467 |
44,571 |
121,610 |
14,840 |
| 2007 |
4,627,851 |
204,530 |
20,732 |
183,798 |
412 |
1,545 |
7,398 |
11,377 |
45,331 |
124,237 |
14,230 |
| 2008 |
4,677,464 |
211,401 |
21,109 |
190,292 |
357 |
1,618 |
7,344 |
11,790 |
50,379 |
126,461 |
13,452 |
| 2009 |
4,708,708 |
199,201 |
21,194 |
178,007 |
322 |
1,504 |
6,265 |
13,103 |
48,844 |
118,072 |
11,091 |
| Year |
Population |
Index |
Violent |
Property |
Murder |
Forcible |
Robbery |
Aggravated |
Burglary |
Larceny |
Vehicle |
|
|
|
|
|
|
Rape |
|
Assualt |
|
Theft |
Theft |
| 2010 |
4,785,401 |
187,191 |
18,363 |
168,828 |
275 |
1,355 |
4,864 |
11,869 |
42,484 |
115,564 |
10,780 |
| 2011 |
4,803,689 |
193,358 |
20,166 |
173,192 |
299 |
1,370 |
4,906 |
13,591 |
51,119 |
111,411 |
10,662 |
| 2012
|
4,817,528
|
190,571
|
21,693
|
168,878
|
342
|
1,296
|
5,020
|
15,035
|
47,481
|
111,523
|
9,874
|
| 2013
|
4,833,996
|
182,669
|
20,834
|
161,835
|
346
|
1,449
|
4,645
|
13,788
|
42,410
|
108,862
|
10,563
|
| 2014
|
4,846,411
|
174,814
|
20,727
|
154,087
|
276
|
1,425
|
4,702
|
13,744
|
39,723
|
104,223
|
10,141
|
| 2015
|
4,858,979
|
167,698
|
22,952
|
144,746
|
348
|
1,456
|
4,611
|
15,954
|
35,255
|
99,156
|
10,335
|
|
|
|
Compiled
by the DisasterCenter.com
From:
FBI UCS Annual Crime Reports |
The
Uniform Crime
Reporting
(UCR) Program is the starting place
for those seeking
information on crime in the nation. The UCR is produced from data
received from over 18,000 law enforcement agencies voluntarily
participating
in the program. . |
|
|
| Alabama Population
and Rate of Crime per
100,000 People
1960 -
2015 |
Alabama
Alabama
| Year |
Population |
Index |
Violent |
Property |
Murder |
Forcible |
Robbery |
Aggravated |
Burglary |
Larceny |
Vehicle |
|
|
|
|
|
|
Rape |
|
Assault |
|
Theft |
Theft |
| 1960 |
3,266,740 |
1,222.0 |
186.6 |
1,035.4 |
12.4 |
8.6 |
27.5 |
138.1 |
355.9 |
592.1 |
87.3 |
| 1961 |
3,302,000 |
1,154.0 |
168.5 |
985.5 |
12.9 |
7.6 |
19.1 |
128.9 |
339.3 |
569.4 |
76.8 |
| 1962 |
3,358,000 |
1,224.3 |
157.3 |
1,067.0 |
9.4 |
6.5 |
22.5 |
119.0 |
349.1 |
634.5 |
83.4 |
| 1963 |
3,347,000 |
1,333.6 |
182.7 |
1,150.9 |
10.2 |
5.7 |
24.7 |
142.1 |
376.9 |
683.4 |
90.6 |
| 1964 |
3,407,000 |
1,571.8 |
213.1 |
1,358.7 |
9.3 |
11.7 |
29.1 |
163.0 |
466.6 |
784.1 |
108.0 |
| 1965 |
3,462,000 |
1,592.5 |
199.8 |
1,392.7 |
11.4 |
10.6 |
28.7 |
149.1 |
473.7 |
812.1 |
106.9 |
| 1966 |
3,517,000 |
1,758.3 |
230.3 |
1,528.0 |
10.9 |
9.7 |
32.0 |
177.7 |
527.5 |
869.6 |
131.0 |
| 1967 |
3,540,000 |
1,851.0 |
238.6 |
1,612.4 |
11.7 |
10.5 |
33.0 |
183.5 |
571.4 |
895.0 |
146.0 |
| 1968 |
3,566,000 |
1,999.0 |
232.4 |
1,766.6 |
11.8 |
11.1 |
41.0 |
168.5 |
628.2 |
967.7 |
170.7 |
| 1969 |
3,531,000 |
2,126.6 |
250.4 |
1,876.2 |
13.7 |
14.0 |
41.0 |
181.7 |
667.2 |
1,037.8 |
171.2 |
| Year |
Population |
Index |
Violent |
Property |
Murder |
Forcible |
Robbery |
Aggravated |
Burglary |
Larceny |
Vehicle |
|
|
|
|
|
|
Rape |
|
Assualt |
|
Theft |
Theft |
| 1970 |
3,444,165 |
2,479.5 |
295.7 |
2,183.8 |
11.7 |
18.5 |
50.3 |
215.2 |
776.4 |
1,184.0 |
223.5 |
| 1971 |
3,479,000 |
2,498.4 |
311.4 |
2,187.0 |
15.1 |
19.0 |
57.6 |
219.7 |
791.8 |
1,173.9 |
221.2 |
| 1972 |
3,510,000 |
2,394.5 |
313.2 |
2,081.3 |
14.1 |
18.8 |
68.6 |
211.7 |
789.6 |
1,096.7 |
195.0 |
| 1973 |
3,539,000 |
2,582.3 |
350.1 |
2,232.2 |
13.2 |
21.2 |
79.4 |
236.3 |
897.3 |
1,107.8 |
227.2 |
| 1974 |
3,577,000 |
3,000.1 |
372.9 |
2,627.2 |
15.0 |
22.7 |
99.6 |
235.6 |
1,057.9 |
1,308.7 |
260.6 |
| 1975 |
3,614,000 |
3,472.5 |
392.9 |
3,079.6 |
16.0 |
20.4 |
123.0 |
233.5 |
1,163.8 |
1,645.5 |
270.3 |
| 1976 |
3,665,000 |
3,808.3 |
388.8 |
3,419.5 |
15.1 |
21.7 |
96.0 |
256.0 |
1,170.0 |
1,987.2 |
262.3 |
| 1977 |
3,690,000 |
3,712.6 |
414.4 |
3,298.2 |
14.2 |
25.2 |
96.8 |
278.3 |
1,135.5 |
1,881.9 |
280.7 |
| 1978 |
3,742,000 |
3,938.8 |
419.1 |
3,519.7 |
13.3 |
25.5 |
99.1 |
281.2 |
1,229.3 |
1,987.9 |
302.5 |
| 1979 |
3,769,000 |
4,243.8 |
413.3 |
3,830.5 |
13.2 |
27.5 |
109.5 |
263.1 |
1,287.3 |
2,223.2 |
320.1 |
| Year |
Population |
Index |
Violent |
Property |
Murder |
Forcible |
Robbery |
Aggravated |
Burglary |
Larceny |
Vehicle |
|
|
|
|
|
|
Rape |
|
Assualt |
|
Theft |
Theft |
| 1980 |
3,861,466 |
4,933.6 |
448.5 |
4,485.1 |
13.2 |
30.0 |
132.1 |
273.2 |
1,526.7 |
2,642.2 |
316.2 |
| 1981 |
3,916,000 |
4,898.7 |
470.5 |
4,428.3 |
11.9 |
26.1 |
126.5 |
306.1 |
1,450.7 |
2,693.3 |
284.2 |
| 1982 |
3,943,000 |
4,633.6 |
447.7 |
4,185.8 |
10.6 |
26.0 |
112.0 |
299.1 |
1,256.2 |
2,656.4 |
273.3 |
| 1983 |
3,959,000 |
4,101.1 |
416.0 |
3,685.0 |
9.2 |
23.5 |
98.4 |
284.9 |
1,073.1 |
2,381.4 |
230.5 |
| 1984 |
3,990,000 |
3,902.0 |
431.2 |
3,470.9 |
9.4 |
25.1 |
96.1 |
300.6 |
1,001.8 |
2,235.5 |
233.6 |
| 1985 |
4,021,000 |
3,942.1 |
457.5 |
3,484.6 |
9.8 |
26.8 |
105.4 |
315.5 |
1,034.9 |
2,191.2 |
258.5 |
| 1986 |
4,053,000 |
4,288.4 |
558.0 |
3,730.3 |
10.1 |
28.4 |
111.6 |
407.9 |
1,159.0 |
2,304.4 |
267.0 |
| 1987 |
4,083,000 |
4,451.4 |
559.2 |
3,892.2 |
9.3 |
27.8 |
112.2 |
409.9 |
1,198.3 |
2,431.1 |
262.8 |
| 1988 |
4,127,000 |
4,561.7 |
558.6 |
4,003.1 |
9.9 |
29.8 |
117.8 |
401.2 |
1,233.8 |
2,502.6 |
266.7 |
| 1989 |
4,118,000 |
4,627.8 |
590.8 |
4,037.0 |
10.2 |
31.0 |
133.9 |
415.7 |
1,146.8 |
2,592.8 |
297.5 |
| Year |
Population |
Index |
Violent |
Property |
Murder |
Forcible |
Robbery |
Aggravated |
Burglary |
Larceny |
Vehicle |
|
|
|
|
|
|
Rape |
|
Assualt |
|
Theft |
Theft |
| 1990 |
4,040,587 |
4,915.2 |
708.6 |
4,206.7 |
11.6 |
32.6 |
143.7 |
520.7 |
1,103.4 |
2,755.4 |
347.8 |
| 1991 |
4,089,000 |
5,365.6 |
844.2 |
4,521.4 |
11.5 |
35.6 |
152.8 |
644.4 |
1,268.6 |
2,889.5 |
363.4 |
| 1992 |
4,136,000 |
5,268.1 |
871.7 |
4,396.4 |
11.0 |
41.2 |
164.9 |
654.6 |
1,186.0 |
2,848.2 |
362.3 |
| 1993 |
4,187,000 |
4,878.8 |
780.4 |
4,098.4 |
11.6 |
35.1 |
159.5 |
574.3 |
1,088.6 |
2,672.0 |
337.8 |
| 1994 |
4,219,000 |
4,903.0 |
683.7 |
4,219.4 |
11.9 |
35.2 |
171.2 |
465.3 |
1,044.4 |
2,843.1 |
331.8 |
| 1995 |
4,253,000 |
4,848.1 |
632.4 |
4,215.7 |
11.2 |
31.7 |
185.8 |
403.7 |
1,024.8 |
2,844.3 |
346.6 |
| 1996 |
4,273,000 |
4,820.1 |
565.4 |
4,254.7 |
10.4 |
32.7 |
166.7 |
355.6 |
1,002.1 |
2,886.7 |
365.8 |
| 1997 |
4,319,000 |
4,889.7 |
564.5 |
4,325.3 |
9.9 |
32.3 |
160.5 |
361.8 |
1,013.8 |
2,954.8 |
356.7 |
| 1998 |
4,352,000 |
4,597.1 |
512.1 |
4,085.0 |
8.1 |
33.2 |
130.9 |
339.9 |
964.3 |
2,779.0 |
341.7 |
| 1999 |
4,369,862 |
4,412.5 |
490.2 |
3,922.3 |
7.9 |
34.6 |
121.2 |
326.5 |
884.4 |
2,737.3 |
300.6 |
| Year |
Population |
Index |
Violent |
Property |
Murder |
Forcible |
Robbery |
Aggravated |
Burglary |
Larceny |
Vehicle |
|
|
|
|
|
|
Rape |
|
Assualt |
|
Theft |
Theft |
| 2000 |
4,447,100 |
4,545.9 |
486.2 |
4,059.7 |
7.4 |
33.3 |
128.2 |
317.2 |
906.9 |
2,864.8 |
288.0 |
| 2001 |
4,468,912 |
4,315.0 |
438.2. |
3,876.8 |
8.5 |
30.6 |
125.0 |
274.1 |
909.4 |
2,685.0 |
282.4 |
| 2002 |
4,478,896 |
4,472.8 |
445.0 |
4,027.8 |
6.8 |
37.2 |
133.1 |
268.0 |
950.6 |
2,767.0 |
310.1 |
| 2003 |
4,503,762 |
4,475.6 |
429.2 |
4,046.4 |
6.6 |
36.8 |
134.1 |
251.7 |
960.2 |
2,754.1 |
332.1 |
| 2004 |
4,525,375 |
4,456.3 |
427.0 |
4,029.3 |
5.6 |
38.5 |
133.5 |
249.4 |
987.0 |
2,732.4 |
309.9 |
| 2005 |
4,548,327 |
4,323.8 |
431.7 |
3,892.1 |
8.2 |
34.5 |
141.4 |
248.3 |
955.8 |
2,650.0 |
288.3 |
| 2006 |
4,599,030 |
4,361.3 |
425.2 |
3,936.1 |
8.3 |
35.9 |
153.5 |
227.6 |
969.1 |
2,644.3 |
322.7 |
| 2007 |
4,627,851 |
4,419.6 |
448.0 |
3,971.6 |
8.9 |
33.4 |
159.9 |
245.8 |
979.5 |
2,684.6 |
307.5 |
| 2008 |
4,667,464 |
4,519.6 |
451.3 |
4,068.3 |
7.6 |
34.6 |
157.0 |
252.1 |
1,077.1 |
2,703.6 |
287.6 |
| 2009 |
4,708,708 |
4,230.5 |
450.1 |
3,780.4 |
6.8 |
31.9 |
133.1 |
278.3 |
1,037.3 |
2,507.5 |
235.5 |
| Year |
Population |
Index |
Violent |
Property |
Murder |
Forcible |
Robbery |
Aggravated |
Burglary |
Larceny |
Vehicle |
|
|
|
|
|
|
Rape |
|
Assualt |
|
Theft |
Theft |
| 2010 |
4,785,401 |
3,911.7 |
383.7 |
3,528.0 |
5.7 |
28.3 |
101.6 |
248.0 |
887.8 |
2,414.9 |
225.3 |
| 2011 |
4,803,689 |
4,025.2 |
419.8 |
3,605.4 |
6.2 |
28.5 |
102.1 |
282.9 |
1,064.2 |
2,319.3 |
222.0 |
| 2012
|
4,817,528
|
3,955.8
|
450.3
|
3,505.5
|
7.1
|
26.9
|
104.2
|
312.1
|
985.6
|
2,314.9
|
205.0
|
| 2013
|
4,833,996
|
3,778.9
|
431.0
|
3,347.9
|
7.2
|
30.0
|
96.1
|
285.2
|
877.3
|
2,252.0
|
218.5
|
| 2014
|
4,849,377
|
3,605.0
|
427.4
|
3,177.6
|
5.7
|
29.6
|
96.9
|
283.4
|
819.0
|
2,149.5
|
209.1
|
|
| DisasterCenter.com
developed the following table to rank the rates of
crime in
Alabama over time in relation to the rates of crime of other
States . This new
way to examine fluctuations in the crime rate reveals patterns that are
important for
law enforcement executives, students of criminal justice, researchers,
members of the media, and the public at large seeking information on
crime in the nation..
|
|
The crime
"Index" is made up of the total number of violent and
property crimes. Since most crime is
property related the crime index gives more weight to property
crime. |
|
|
Alabama Population
and
Rate of Crime
Rank Compared
to other States
|
| State |
Year |
Population |
Index |
Violent |
Property |
Murder |
Rape |
Robbery |
Assault |
Burglary |
Larceny |
Vehicle |
| Alabama |
1960 |
18 |
33 |
7 |
41 |
2 |
17 |
26 |
2 |
30 |
41 |
39 |
| Alabama |
1961 |
19 |
39 |
8 |
42 |
1 |
19 |
33 |
5 |
33 |
42 |
42 |
| Alabama |
1962 |
18 |
38 |
10 |
40 |
3 |
28 |
27 |
5 |
34 |
42 |
45 |
| Alabama |
1963 |
19 |
38 |
10 |
39 |
1 |
34 |
29 |
3 |
34 |
42 |
45 |
| Alabama |
1964 |
20 |
37 |
10 |
38 |
4 |
12 |
27 |
4 |
30 |
40 |
40 |
| Alabama |
1965 |
21 |
36 |
13 |
38 |
1 |
22 |
28 |
6 |
30 |
41 |
40 |
| Alabama |
1966 |
21 |
38 |
11 |
40 |
4 |
28 |
30 |
3 |
31 |
41 |
41 |
| Alabama |
1967 |
21 |
41 |
12 |
40 |
1 |
27 |
34 |
4 |
33 |
44 |
41 |
| Alabama |
1968 |
21 |
40 |
18 |
40 |
4 |
29 |
34 |
11 |
32 |
43 |
38 |
| Alabama |
1969 |
21 |
42 |
17 |
42 |
1 |
25 |
37 |
11 |
33 |
44 |
40 |
| State |
Year |
Population |
Index |
Violent |
Property |
Murder |
Rape |
Robbery |
Assault |
Burglary |
Larceny |
Vehicle |
| Alabama |
1970 |
21 |
40 |
18 |
41 |
7 |
16 |
37 |
7 |
32 |
43 |
36 |
| Alabama |
1971 |
21 |
41 |
22 |
43 |
3 |
18 |
35 |
10 |
34 |
45 |
37 |
| Alabama |
1972 |
21 |
42 |
22 |
44 |
4 |
25 |
30 |
16 |
35 |
46 |
39 |
| Alabama |
1973 |
21 |
42 |
21 |
44 |
7 |
24 |
30 |
16 |
34 |
47 |
36 |
| Alabama |
1974 |
21 |
44 |
22 |
45 |
4 |
26 |
29 |
16 |
35 |
48 |
35 |
| Alabama |
1975 |
21 |
43 |
22 |
44 |
1 |
27 |
28 |
17 |
34 |
47 |
33 |
| Alabama |
1976 |
21 |
40 |
21 |
41 |
1 |
28 |
30 |
15 |
31 |
43 |
32 |
| Alabama |
1977 |
21 |
42 |
18 |
43 |
4 |
25 |
29 |
15 |
33 |
42 |
33 |
| Alabama |
1978 |
22 |
37 |
21 |
40 |
5 |
24 |
27 |
16 |
29 |
42 |
34 |
| Alabama |
1979 |
22 |
40 |
26 |
41 |
6 |
28 |
29 |
21 |
30 |
42 |
34 |
| State |
Year |
Population |
Index |
Violent |
Property |
Murder |
Rape |
Robbery |
Assault |
Burglary |
Larceny |
Vehicle |
| Alabama |
1980 |
22 |
32 |
24 |
37 |
8 |
26 |
25 |
22 |
23 |
40 |
32 |
| Alabama |
1981 |
22 |
31 |
22 |
34 |
10 |
32 |
28 |
18 |
27 |
37 |
32 |
| Alabama |
1982 |
22 |
31 |
21 |
33 |
13 |
29 |
30 |
17 |
29 |
37 |
30 |
| Alabama |
1983 |
22 |
34 |
22 |
37 |
13 |
33 |
30 |
16 |
32 |
39 |
31 |
| Alabama |
1984 |
22 |
34 |
22 |
37 |
11 |
32 |
31 |
13 |
31 |
40 |
32 |
| Alabama |
1985 |
22 |
36 |
21 |
40 |
11 |
30 |
26 |
15 |
29 |
41 |
32 |
| Alabama |
1986 |
22 |
34 |
17 |
38 |
12 |
29 |
25 |
11 |
25 |
41 |
31 |
| Alabama |
1987 |
22 |
33 |
15 |
37 |
13 |
33 |
23 |
11 |
21 |
41 |
31 |
| Alabama |
1988 |
22 |
30 |
16 |
33 |
10 |
31 |
23 |
13 |
20 |
38 |
33 |
| Alabama |
1989 |
22 |
30 |
17 |
32 |
9 |
30 |
22 |
11 |
23 |
40 |
33 |
| State |
Year |
Population |
Index |
Violent |
Property |
Murder |
Rape |
Robbery |
Assault |
Burglary |
Larceny |
Vehicle |
| Alabama |
1990 |
22 |
30 |
14 |
36 |
7 |
31 |
23 |
7 |
26 |
39 |
31 |
| Alabama |
1991 |
22 |
27 |
8 |
31 |
9 |
28 |
22 |
4 |
15 |
32 |
30 |
| Alabama |
1992 |
22 |
23 |
9 |
26 |
9 |
26 |
20 |
4 |
15 |
29 |
29 |
| Alabama |
1993 |
22 |
26 |
12 |
30 |
7 |
31 |
22 |
7 |
18 |
35 |
31 |
| Alabama |
1994 |
22 |
25 |
17 |
26 |
4 |
28 |
19 |
14 |
19 |
29 |
33 |
| Alabama |
1995 |
22 |
25 |
21 |
26 |
6 |
32 |
15 |
21 |
19 |
29 |
34 |
| Alabama |
1996 |
23 |
24 |
21 |
25 |
6 |
26 |
19 |
23 |
15 |
27 |
32 |
| Alabama |
1997 |
23 |
21 |
20 |
20 |
5 |
29 |
16 |
20 |
16 |
20 |
32 |
| Alabama |
1998 |
23 |
23 |
21 |
22 |
11 |
26 |
22 |
23 |
14 |
24 |
32 |
| Alabama |
1999 |
23 |
21 |
21 |
20 |
7 |
21 |
22 |
19 |
13 |
19 |
33 |
| State |
Year |
Population |
Index |
Violent |
Property |
Murder |
Rape |
Robbery |
Assault |
Burglary |
Larceny |
Vehicle |
| Alabama |
2000 |
23 |
15 |
20 |
15 |
6 |
24 |
22 |
19 |
11 |
16 |
32 |
| Alabama |
2001 |
23 |
17 |
22 |
20 |
5 |
28 |
21 |
24 |
13 |
22 |
35 |
| Alabama |
2002 |
23 |
17 |
21 |
16 |
11 |
19 |
18 |
23 |
12 |
16 |
31 |
| Alabama |
2003 |
23 |
19 |
22 |
18 |
11 |
19 |
18 |
24 |
12 |
18 |
27 |
| Alabama |
2004 |
23 |
16 |
22 |
17 |
18 |
19 |
17 |
22 |
10 |
16 |
30 |
| Alabama |
2005 |
23 |
18 |
22 |
17 |
4 |
22 |
16 |
23 |
10 |
15 |
31 |
| Alabama |
2006 |
23 |
13 |
23 |
13 |
5 |
17 |
13 |
25 |
8 |
8 |
26 |
| Alabama |
2007 |
23 |
11 |
21 |
10 |
3 |
22 |
11 |
22 |
7 |
7 |
24 |
| Alabama |
2008 |
23 |
5 |
21 |
4 |
5 |
17 |
11 |
22 |
3 |
3 |
21 |
| Alabama |
2009 |
23 |
8 |
18 |
5 |
5 |
25 |
15 |
18 |
5 |
8 |
21 |
| State |
Year |
Population |
Index |
Violent |
Property |
Murder |
Rape |
Robbery |
Assault |
Burglary |
Larceny |
Vehicle |
| Alabama |
2010 |
23 |
13 |
21 |
10 |
11 |
31 |
20 |
20 |
13 |
8 |
18 |
| Alabama |
2011 |
23 |
7 |
16 |
6 |
6 |
28 |
21 |
15 |
3 |
12 |
20 |
| Alabama |
2012 |
23 |
8 |
14 |
7 |
2 |
32 |
17 |
12 |
4 |
12 |
22 |
| Alabama |
2013 |
23 |
7 |
14 |
7 |
2 |
17 |
20 |
12 |
5 |
12 |
20 |
| Alabama |
2014 |
23 |
9 |
12 |
9 |
10 |
21 |
17 |
11 |
4 |
14 |
23 |
| Alabama |
2015 |
24 |
9 |
10 |
10 |
7 |
24 |
19 |
9 |
8 |
15 |
19 |
| State |
Year |
Population |
Index |
Violent |
Property |
Murder |
Rape |
Robbery |
Assault |
Burglary |
Larceny |
Vehicle |
|
| Since we developed
the table
of "Alabama
Population
and
Rate of Crime
Rank Compared
to other States", we are interested in hearing how others are using the
table. Email<EMAIL_ADDRESS>|
|
|
| Alabama
Law Enforcement Agency Uniform Crime Reports 1980 to 2005 |
| *
United States * Alaska* Alabama
* Arkansas
*
Arizona
*
California
*
Colorado
*
Connecticut* Delaware
* Florida
*
Georgia
*
Hawaii
*
Iowa
*
Idaho
*
Illinois
*
Indiana
*
Kansas
*
Kentucky *
Louisiana
*
Massachusetts
*
Maryland *
Maine
*
Michigan
*
Minnesota
*
Missouri
*
Mississippi
*
Montana
*
North
Carolina *
North
Dakota *
Nebraska
*
New
Hampshire *
New
Jersey *
New
Mexico *
Nevada
*
New
York *
Ohio
*
Oklahoma
*
Oregon
*
Pennsylvania
*
Rhode
Island *
South
Carolina *
South
Dakota *
Tennessee
*
Texas
*
Utah
*
Virginia *
Vermont
*
Washington
D. C. *
Washington *
Wisconsin
*
West
Virginia *
Wyoming
* |
|


Four days to governorship poll, Senate approves N10b promissory note for Kogi
by Emmanuel LekeFour days to the governorship election in Kogi State on Saturday, the Senate has approved N10.069 billion settlement of promissory note to the Kogi State Government.
Kogi State had tendered the request along with other States in the Eight Senate, but it was rejected.
Approval of the promissory note came following the consideration of the report of Senate Committee on Local and Foreign Debt.
The Senate Minority Leader, Senator Enyinnaya Abaribe, made attempt to delay the approval of the loan, arguing that with the election on Saturday, it will be appropriate for the approval to be delayed till next week.
But the Senate President, Senator Ahmad Lawan, justified the approval, saying it was just a coincidence.
Lawan said Kogi State had requested for the money in the last Senate, but it was not granted by the lawmakers.
Previous Post
Oshiomhole devalued to local factional leader — DG, APC Governors’ Forum
Next Post
Mexico battles Netherlands in FIFA U-17 World Cup


Dave's Portfolio
It's me..... Dave!
Hello world! Welcome to my portfolio page. My name is David Nienhuis and I’m from Michigan. I have really enjoyed coding thus far. The link to my GitHub is Here.
I haven’t updated my LinkedIn in a while but my linkedin is David R.F. Nienhuis. The best way to contact me is through email at<EMAIL_ADDRESS>Here is a my introduction video
Here is a song I wrote during the Quaritine of 2020


Wordsets
Word sets used as stimuli in various studies of naming and lexical decision.
|
|
g1979a1
|
Glushko (1979), Word & derived nonword sets for regular and exception items. |
|
g1979a2
|
Glushko (1979), Lexically derived nonword set. |
|
g1979a3
|
Glushko (1979), Pronunciation Latency by Consitency and Regularity
word set. |
|
mb1987a
|
McCann & Besner (1987), Word and derived nonword/pseudohomophone set. |
|
mb1987b
|
McCann & Besner (1987), Reaction Time and Error Rate based on
Nonwords and Nonword PSeudohomophones. |
|
rgm2002a
|
Rodd, Gaskell & Marslen-Wilson (2002), Ambiguity word set. |
|
rgm2002b
|
Rodd, Gaskell & Marslen-Wilson (2002), Senses by Ambiguity word set. |
|
rgm2002c
|
Rodd, Gaskell & Marslen-Wilson (2002), Senses by Ambiguity word set. |
|
sps1995a
|
Strain, Patterson & Seidenberg (1995), Frequency by Regularity by Imageability. |
|
sps1995b
|
Strain, Patterson & Seidenberg (1995), Regularity by Imageability in low Frequency words. |
|
sps2002b
|
Strain, Patterson & Seidenberg (2002), Regularity word set. |
|
tgb1990
|
Treiman et al (1990), Nonword set. |
|
tm1987a1
|
Taraban & McClelland (1987), Frequency by Regularity word set. |
|
tm1987a2
|
Taraban & McClelland (1987), Frequency by Consistency word set. |


Questions of community well-being or geopolitical interest were waved away or even crushed. Under this ideology, no distinction can be made between a billion dollars in GDP generated from Netflix consumption and a billion dollars in GDP generated by domestic machine tool production. Nor does it permit us to discern which sectors are vital to retain and which can be safely offshored.
At its most general, cringe is the experience of witnessing failed emotional manipulation: a theater production’s failure to induce suspension of disbelief, a joke followed by silence, a grandiose boast that fails to impress.
Conspiracy theories around 5G have spread on social media, with Facebook, YouTube, and Twitter all taking action to try and curb the spread. One offshoot of the theory claims that 5G accelerates the spread of the virus by lowering the body's immune system and that the coronavirus is itself a fiction designed to cover up damage being done by 5G. Both these claims are false.


One of the most popular requests now fulfilled, Battlefield 1's weapon charts have made their glorious return to the web. A big thanks to Robenter who put in the effort to make these charts happen, so if you seem him around, be sure to show him some love.
With Battlefield 1 formally up on sym.gg, our focus will be turned to additional previous DICE titles such as Battlefield 4 and Battlefield 3. That said, another common request we hear is the desire to cover weapon data for Call of Duty: Modern Warfare. While we too are interested in covering this title, at this moment we unfortunately do not have the means to datamine weapon stats for this game. If anyone has the this ability or knows someone with the ability to accomplish this, please reach out to us via the Sym Discord.
Lastly, with the ongoing COVID-19 pandemic affecting many around the world, we hope that everyone remain safe and healthy during this chaotic time. There will be plenty of game stats to look at on the other side.
Until next time,
- Incarnate


Teams: SAS vs. Spetsnaz
Place: Komi Republic, Russia
Terrain: Expansive neighborhood with balconies with mounted machine guns
Type of Combat: Medium range to close-quarters combat
Downpour is a medium-sized, narrow map that is great for run and gunning, though you always have to be careful about the two stationed machine guns at each end of the map. Downpour is a level with low visibility due to the unceasing rain.
Most Skirmishes occur around the bottleneck, silos and bush area. Usually the team that spawns on the Russian side will come down that west road or main road and camp snipers. Watch for guys climbing the side ladder of the tractor shed to get on the roof and pick people off the bottleneck area. There is a crawl space between the bush and silos but be prepared once you crawl through to shoot.
Another danger zone is first walking up the house ramp to the door of the house. Guys will either mount the Russian turret and just lay fire on that house since it can go through walls and the area between the house and tractor shed. Not only that, but you'll have to contend with guys in the backyard area shooting the windows if you manage to make it inside the house.
The teams that control the higher portion of the map (Russian spawn, Tractor Shed, House, Silos) tend to spawn camp the lower end. It is vital to control that upper area especially the turret. Helicopter barrages occur often and a fast way to take them down is to get on turret and go at it with it. The British Spawn or lower end isn't terrible either if you have dedicated turret guy and some accurate gunners. Smoke is an option as well to help move through the bottleneck.


 It's festive season again, this UGADI we will see some cracking cricket and some firecrackers along.
This is the Core Organizing team of TSS Premier League
Vice Captain, ఇది తోకేసేరకం
Captain, TPL Org
Event organiser, PR
Actual Vice Captain
UX/UI Designer
Design Team
Auctions
TPL org
TPL org
TPL org
Photography
TSS పెద్ద దిక్కు


{if:{comments}}
* Required Fields No HTML is allowed. All links, and new lines will be automagically converted to HTML for you. Notice to spammers, all links will be sanitized with rel="nofollow".


---
layout: post
title: Facebook ROSEdu Hackathon
date: '2013-10-20T04:05:00.001+03:00'
author: Alex Palcuie
tags:
- facebook
- hackday
- rosedu
modified_time: '2014-04-06T00:26:39.374+03:00'
blogger_id: tag:blogger.com,1999:blog-4563358888205449053.post-2302004443419553153
blogger_orig_url: http://palcu.blogspot.com/2013/10/facebook-rosedu-hackathon.html
---
Facebook ROSEdu Hackathon is currently ongoing in University Politehnica of Bucharest, and I'm doing live blogging w/ Marius Ungureanu on TechBlog. About 15 teams of student hackers are battling for the chance to represent Romania at the European Facebook Hackathon.


Copy BNB address from Atomic and send funds to it. Your balances will be updated in a few seconds. Read this article if you want to learn more about AWC.
Go to "Settings" -> "Private Keys", copy 12 words seed phrase.
Open Binance DEX and Click "Unlock Wallet".
Choose "Mnemonic Phrase". Paste your seed phrase in the field.
Make password secure enough and easy to write as Binance DEX will ask you to insert it while trading sometimes. Easy to write pass will help you to catch the wave or close profitable orders just in time 😉
Note: If you have ERC20 AWC and want to swap it to BNB-AWC, please check this guide. Happy Trading!


About
Working in special education, I found that students are more motivated to practice when they are writing about what they are interested in
- but sometimes it's hard to modify a worksheet for them every time.
I hope that parents, teachers, and other school staff find this handwriting worksheet maker easy to use for their students.


OpenAPI-Link-Generator
Add links to an OpenAPI document.
Info
OpenAPI-Link-Generator is a tool that enhances an existing Swagger/OpenAPI documentation by adding link definitions. To use it, simply input a Swagger 2.0 or OpenAPI 3.0 document in JSON or YAML format below. The tool will run the link generator on the document and show the result.
The source code of this webservice is available on GitHub.


I’m a third year student at the University of Waterloo, Electrical and Computer Engineering, Co-op
I strongly believe, engineering has a profound impact on the current world, the seamless integration of different technologies has shaped the existing sphere to be much more user centric than ever. On this page, you can find some of my software and hardware projects as well as a link to my mathematics blog
Contact me for any internship opportunities, May 2018 – September 2018
I possess deep understanding of the Software Development Life Cycle and Agile Methodologies such as Scrum and Kanban. I have worked at SOTI - enterprise mobility management and UXP Systems - user life cycle management. I am particularly interested in Internet of Things (IoT) coupled with the recent advancements in Artificial Intelligence (AI)
Given the discontinuity in the reach of technology across the geographical scheme, some people are inevitably going to be left behind. I aspire to work to minimize this divide between the people having access to technology versus the other half. A sheer increase in the reach of technology will extensively accelerate the rate of change, by re-defining the existing ideas and initiate a culture of technical optimism and innovation
My coursework has exposed me to a multitude of programming languages. Relevant courses: Data Structure and Algorithms, Electronic Circuits, Digital Computers, Engineering Design and Digital Circuits and Systems. Currently, exploring the concepts related to the implementation of a functional drone.


Northeastern Recovery Advocates(NERA) Notice of Privacy Practices
THIS NOTICE DESCRIBES HOW MEDICAL INFORMATION ABOUT YOU MAY BE USED AND DISCLOSED AND
HOW YOU CAN GET ACCESS TO THIS INFORMATION. PLEASE READ IT CAREFULLY.
NERA has adopted the following policies and procedures for protection of the privacy of the people we serve.
Our Obligation to You
We at NERA respect your privacy. This is part of our code of ethics. We are required by law to maintain the privacy of
'protected health information' about you, to notify you of our legal duties and your legal rights, and to follow the privacy policies
described in this notice. 'Protected health information' means any information that we create or receive that identifies you and relates
to your health or payment for services to you.
We will use your protected health information and disclose it to others as necessary to provide treatment to you. Here are some
examples:
- We may provide information to your health plan or another treatment provider in order to arrange for a referral or clinical
consultation
- We will contact you to remind you of appointments.
- We may contact you to tell you about treatment services that we offer that might be of benefit to you.
- Emergencies. If there is an emergency, we will disclose your protected health information as needed to enable people to care for you.
- Disclosure to your family and friends. If you are an adult, you have the right to control disclosure of information about you to any
other person, including family members or friends. If you ask us to keep your information confidential, we will respect your wishes.
But if you don’t object, we will share information with family members or friends involved in your care as needed to enable them to
help you.
- Disclosures with your permission. No other disclosure of protected health information will be made unless you give written
Authorization for the specific disclosure.


Instruction Set Architecture (ISA)¶
Control Word¶
The Control Word (CW) consists of all the control lines of the seperate modules described in the hardware section. By driving these control lines, the behaviour of the modules can be controlled. Most modules are synchronized with the clock, so a change in any of the control bits will take effect on the next clock cycle. For example, driving the AI line high will save whatever state the databus is in into Register A on the next clock tick (and all further ticks until the control line is pulled low again. However, not all lines are syncronied with the clock, some will change the module behaviour as soon as the line is changed. Generally, all input lines are syncronized, while output lines will change immediately. This has the nice side-effect that the databus will have the correct data on it before the clock cycle latches this data into a module.
The control word is set by the Instruction Decoder (ID) which sets the control lines between the clock ticks depending on the current instruction and microinstruction. The CW consists of 16 control lines, thus is 16 bits long.
The following table lists all control lines, their function and the position they have in the CW. The final control word is thus created by ORing the values in the CW column for all active control lines.
CW |
Mnemonic |
Name |
Description |
Synced |
0x0001 |
HLT |
Halt Clock |
Stop the main clock. This will also disable single-stepping and the processor can only leave this state by resetting the system to clear the control word |
N |
0x0002 |
MI |
Memory Address In |
Latch the current state of the databus into the Memory address register (MAR) |
Y |
0x0004 |
RO |
RAM Out |
Put the currently selected RAM byte onto the databus |
N |
0x0008 |
RI |
RAM In |
Write the current state of the databus into the active RAM byte |
Y |
0x0010 |
IO |
Instruction Data Out |
Put the lower nibble (the data section) of the instruction register (IR) onto the databus. The upper nibble will always read as 0 |
N |
0x0020 |
II |
Instruction Register In |
Write the current state of the databus into the IR |
Y |
0x0040 |
AO |
Register A Out |
Put the content of the register A (RA) onto the databus |
N |
0x0080 |
AI |
Register A In |
Latch the current state of the databus into RA |
Y |
0x0100 |
EO |
ALU Out |
Put the sum of register A and B onto the databus |
N |
0x0200 |
SU |
ALU Substract |
compute RA - RB instead of the sum |
N |
0x0400 |
BI |
Register B In |
Latch the current state of the databus into register B (RB) |
Y |
0x0800 |
OI |
Output Latch |
Latch the current state of the databus into the output register (OUT) This will cause the 7-segment display to display the current value of the databus until a new byte is latched into this register |
Y |
0x1000 |
CE |
Programcounter Enable |
Increment the program counter on the next clock-cycle |
Y |
0x2000 |
CO |
Programcounter Out |
Put the current program counter (PC) value the databus. Only the lower nibble will ever read as non-zero |
N |
0x4000 |
JP |
Jump (Programcounter In) |
Latch the current state of the databus into the PC |
Y |
0x8000 |
FI |
Store Flags |
Latch the current state of the flags (ZF and CF) into the flags register (FR) |
Y |
Microcode¶
The Processor will run a list of instructions to execute a program. Although individual instructions are on a pretty low level, they are not quite atomic, since each instruction can consist of multiple microinstructions. The mapping from an instruction to a list of microinstructions is called microcode. Each Instruction can consist of up to 5 microinstructions (T0 - T4), although this could easily be extended to 8 or even 16 steps (as described in the hardware section). However, since there is no way to advance to the next instruction before the 5 microinstructions are all run, it makes sense to limit this to only the maximum number of steps needed for any instruction.
During all microinstruction steps that are not needed, the CW is empty
(0x0000
, all control lines are low).
Fetch Cycle¶
The first 2 microinstaructions are the same for all instructions and are responsible to actually fetch the instruction from memory. Thus only 3 microinstructions are effectivley available for the actual instruction.
A fetch cycle consists of the following steps (microinstructions)
Drive the CO and MI lines high (CW:
0x2000 + 0x0002 = 0x2002
). This will load the current instruction’s address into the MAR and thus the RAM module outputs the instruction as stored in memory.Drive the RO, II and CE lines high (CW:
0x0004 + 0x0020 + 0x1000 = 0x1024
). This will load the instruction from RAM into the Instruction Register and also advance the Programcounter to point to the next instruction’s address.
Instruction Table¶
The following table shows the available instructions and the corresponding microinstructions with the corresponding control lines that are driven high to achieve the desired behaviour. All unspecified control lines need to be driven low.
A instruction in the SAP-1 architecture consists of 1 byte. The upper nibble of this byte (bits 4-7) are the opcode and identify the instruction. The lower nibble (bits 0-3) can be used to pass parameters to the instruction (for example a RAM Address). This data is called Instruction Data (ID).
As described earlier, not all insructions need the whole 5 microinstructions,
however since there is no way to reset the microinstruction counter in the
Instruction Decoder module, all instructions will need 5 clock cycles to
execute.
During the unused clock cycles, the CW is empty (0x0000
).
Opcode |
Mnemonic |
Function |
ID |
Description |
CW |
Microinstruction Description |
|
|
NOP |
No-Op |
A no op (NOP) does nothing but a fetch cycle, thus simply advances to the next instruction |
||||
|
LDA |
Load RA |
RAM Address |
Load the value of the RAM at the address specified by the ID of the instruction into RA |
T2 |
IO, MI |
Load the lower nibble of the IR into the MAR |
T3 |
RO, AI |
Load the selected RAM byte into RA |
|||||
|
ADD |
Caculate sum of data and RA, store result in RA |
RAM Address |
Calculate the sum of the value of the RAM value specified by, the ID of the instruction and RA and store the result in RA |
T2 |
IO, MI |
Load the lower nibble of the IR into the MAR |
T3 |
RO, BI |
Load the selected RAM byte into RB |
|||||
T4 |
EO, AI, FI |
|
|||||
|
SUB |
Caculate difference of data and RA, store result in RA |
RAM Address |
Calculate the sum of the value of the RAM value specified by the ID of the instruction and RA and store the result in RA |
T2 |
IO, MI |
Load the lower nibble of the IR into the MAR |
T3 |
RO, BI |
Load the selected RAM byte into RB |
|||||
T4 |
EO, AI, FI |
a) Set the SU control bit to make the ALU output the difference, rather than the sum between RA and RB b) Take the output of the ALU and store it in RA c) Save the state of the flags into the FR |
|||||
|
STA |
Store RA contents |
RAM Address |
Store the contents of RA into the RAM cell specified by the ID of the instruction |
T2 |
IO, MI |
Load the ID into the MAR |
T3 |
AO, RI |
Store the content of RA into RAM |
|||||
|
LDI |
Load immediately |
Data Nibble |
Load data immediatley into RA |
T2 |
IO, AI |
Store the ID of the instruction into RA |
|
JMP |
Jump |
RAM Address |
Jump to another instruction (set the PC to the instructions ID) |
T2 |
IO, JP |
Set the PC to the ID of the instruction |
|
JC |
Jump if carry |
RAM Address |
Jump to another instruction (set the PC to the instructions ID) if the carry flag is currently set (the last ALU computation did overflow) |
T2 |
NOP if the carry flag is not set |
|
T2 |
IO, JP |
Set the PC to the ID of the instruction if the flag is set |
|||||
|
JZ |
Jump if zero |
RAM Address |
Jump to another instruction (set the PC to the instructions ID) if the zero flag is currently set (the last ALU computation resulted in a zero) |
T2 |
NOP if the zero flag is not set |
|
T2 |
IO, JP |
Set the PC to the ID of the instruction if the flag is set |
|||||
|
<unused> |
||||||
|
<unused> |
||||||
|
<unused> |
||||||
|
<unused> |
||||||
|
<unused> |
||||||
|
OUT |
Display contents of RA |
Set the output display to show the current contents of RA |
T2 |
AO, OI |
Latch the current value of RA into the OUT register |
|
|
HLT |
Halt the clock |
Halt all further program execution. Although this will also run, a fetch cycle and thus advance the PC, the next instruction will, never be executed |
T2 |
HLT |
Halt the clock |
The Microcode is implemented as a Lookuptable (LUT) in the EEPROMs of the
Instruction Decoder module.
See the files spec/ISA.py
and spec/lut_microcode
that will generate
the LUT for those EEPROMs. You can also create your own instructions with
your own microcode in the unused opcodes.


---
title: Home
layout: default
---
Hello!
Javacord is an easy to use multithreaded library for creating Discord bots in Java.
Learn more
Easy to Use
Javacord has been designed to be easy to use both by experienced developers and beginners.
Powerful API
Focused both on usability and performance, Javacord is the perfect choice for every Discord bot.
Rich Documentation
The wiki contains detail information about everything you have to know to get started.
Example Code
{% highlight java %}
public class MyFirstBot {
public static void main(String[] args) {
// Read the token from the first program parameter when invoking the bot
String token = args[0];
DiscordApi api = new DiscordApiBuilder().setToken(token).login().join();
// Add a listener which answers with "Pong!" if someone writes "!ping"
api.addMessageCreateListener(event -> {
if (event.getMessage().getContent().equalsIgnoreCase("!ping")) {
event.getChannel().sendMessage("Pong!");
}
});
// Print the invite url of your bot
System.out.println("You can invite the bot by using the following url: " + api.createBotInvite());
}
}
{% endhighlight %}