If you study, or work on a subject that is IT-related, then you’ve heard of Programming Languages. And, as you know for sure, that’s all about this series of articles is.
I bet every now and again you’ve heard or read the expression the Language’s Grammar. What does it mean?
In this article, we are going to learn what a Formal Grammar is, in the context of programming languages and compiler’s theory.
Definition of Grammar
A Programming Language Grammar is a set of instructions about how to write statements that are valid for that programming language.
The instructions are given in the form of rules that specify how characters and words can be put one after the other, to form valid statements (also called sentences).
Understanding the definition
Let’s start by stating the obvious: in a programming language you cannot type characters randomly on your keyboard and hope something correct will come out of it. You must follow some rules.
Broadly speaking, a Grammar is the definition of such rules.
For example, you can imagine there’s a rule in Java’s Grammar called “the equality condition rule”. This rule says
an equality condition is written in Java language by writing the name of an expression, followed by the ==
special symbol, followed by the name of another expression.
Then, there must be another rule that says what an expression is. And so on for each logical piece of the language (expressions, variables, keywords, etc.).
Looking deeper down, you can expect that the rules of a grammar start by defining very high-level type of sentences, and then go to more and more bottom levels. Let me use again the previous example to clarify this concept.
We know there is a rule about the equality condition. It says an equality statement must be expression, followed by ==
, followed by another expression. We can write is as
eq_statement : expression '==' expression
This the highest level of sentences.
However, the rule is not complete in itself: the Grammar must also specify what an expression
is.
Let’s assume an expression can be a variable, or a string, or an integer. Of course, real programming languages have a more complex definition of expression, but let’s continue with the simple one. So we would have
expression : variable | int | string
You can see that the character |
is used to express the inclusive logical condition (OR). The Grammar is not done yet, because it will also have to clarify what a variable
is.
So, let’s assume a variable is a sequence of characters in a-z, A-Z and digits in 0-9, without length limitations in the number of characters. You would express this with a regular expression rule, which is
variable : [a-zA-Z0-9]*
The *
symbol after the square brackets means you can repeat each of the symbols zero or more times.
Again, real programming languages have more complex definitions for variables, but I am hoping this simple example clarifies the concept.
There are still two pieces of a previous rule that haven’t been specified yet: int
and string
.
Let’s assume that an int
is any non-empty sequence of digits, and string is any sequence of characters in a-z
, A-Z
. Of course in real applications you would have many more characters (for instance, ?!+-
, etc.), but let’s keep it simple for the moment. So, you are going to have two more rules:
int : [0-9]+
string : [a-zA-Z]*
At this point we’ve gone the deepest you can in the definition of an equality condition. Why? Because you cannot expand further these rules. We say that single characters such as a-z
, A-Z
and digits 0-9
are the terminal symbols or, more formally, these are the characters of the Alphabet of the Grammar.
So, let’s recap, from a different angle, which will help seeing things more clearly.
 Alphabets are just set of characters, and in our case it would be {a, b, …, z, A, B, …, Z, 0, 1, …, 9}
.
Then, you define the rules that state how you can concatenate characters in the alphabet to make words and sentences (statements) that are valid in your language. Eventually, the whole set of rules defines the Grammar, which generates the Language.
I want to go back to the example to discuss a few things worth mentioning.
If you count backwards, we had three levels to specify: equality statement, expression and variable/int/string (the last three are at the same level, in a hierarchical sense).
It is worth noting that you could express the entire condition in one-go, and you still can, by replacing the rules in the lower levels inside the rules in the upper levels. To replace literally means to substitute the symbols in the right-hand side of a rule wherever the left-hand side of the same rule appears.
So, when you replace the rules about variable, int, string in the rule about expression you get
expression : [a-zA-Z0-9]* | [0-9]+ | [a-zA-Z]*
Then, when you replace the rule about expression in the equality statement rule, you get
eq_statement : ( [a-zA-Z0-9]* | [0-9]+ | [a-zA-Z]* )
"=="
( [a-zA-Z0-9]* | [0-9]+ | [a-zA-Z]* )
It really is just replacing definition into definition, in a recursive manner.
When the recursion is over, that is all replacements have been done, you can see what an equality statement really must look like to be valid in language that is defined by the grammar. The difficulty though, is that real Grammars have dozens of nested levels and therefore is better to express them in small pieces, rather than in a whole, giant, rule.
Thus, a full Grammar is a (rather big) list of rules that specify the syntactic constraints you must follow in order to write valid sentences in that language. From the highest level constructs, to the tiniest detail, Grammars are very formally specified object.
Before moving on, I believe one thing is worth pointing out. Grammars are only about syntax. Like in a human natural language, also in programming languages, Grammars will tell you if what you are writing is acceptable from syntax point of view.
But the Grammar rules will not tell you whether what you wrote makes sense or not!
And they will not tell you if what you wrote will really do what you meant to, once it’s executed!
So, to wrap up, watch out for the (very important) difference between syntactic and semantic rules! Formal Grammars are about syntactic rules only.
A broader view on Formal Grammar
At this point in the article, I bet you have a question. Or, well, many questions. Some are along these lines:
- Are all Grammars the same?
- What differentiates one Grammar from the others?
- How can I make a new Grammar?
Let’s take them one at a time.
First of all, no, Grammars are not all the same. Of course, I would add.
The way you mix the single characters in the Alphabet is obviously a feature of each language. Now, as it happens, many famous languages have a lot of rules in common, by design (because this way it’s easier to learn them).
For instance, variable identifiers are pretty much the same in C, C++, Java, Python, and many other languages: digits, letters, plus many other symbols, with the first character that has to be a letter. And they cannot be equal to some keywords.
Keywords, on the other hand, vary from language to language. Keywords are also defined as a rule in the grammar, something along these lines:
keyword : 'for' | 'if' | 'else' | 'while' | ...
This a very important first distinction about Grammars. Let’s say it again:
Since Grammars define how characters in the chosen Alphabet are used, the same Alphabet can easily generate two different languages, if the two Grammars are different.
Now, given that the way you write down the rules is so important, someone in the past has taken care of studying and grouping the sensible ways in which you can build a Grammar.
His name is Noam Chomsky, he’s an american linguist and he defined the so-called Chomsky Hierarchy, which I am going to talk about next in this article.
At is turns out, the way you write down the rules defines also the expressivity power of the Grammar, and different Grammars can be grouped in 4 Types, each type with a different power.
Finally, yes, of course you can write your own Grammar. Just decide what Type you want to be in, and follow the rules stated in the Chomsky hierarchy. Good luck with that!
References
The Dragon Book. Compilers: Principles, Techniques and Tools. Wikipedia page (of the book).
The Chomsky Hierarchy, Wikipedia Page, as starting point to follow many links inside it.


Do you often order things online ?I think most of us had face with a problem that the things we ordered delivered on a time that we not free or unable to collect
Here we are to solve your problem.We will help you hold on to the item first then then you can come collect anytime when you free
We have gather lot of technicians to help solve your problems.We have their comapany number and which one is nearer to your location
We even have a rating system!We will provide the best service to you :)
Programmer
Designer
Developer


torchaudio is an extension for torch providing audio loading, transformations, common architectures for signal processing, pre-trained weights and access to commonly used datasets. An almost literal translation from PyTorch’s Torchaudio library to R.
The CRAN release can be installed with:
install.packages("torchaudio")
You can install the development version from GitHub with:
remotes::install_github("curso-r/torchaudio")
torchaudio
also supports loading sound files in the wav and mp3 format. We call waveform the resulting raw audio signal.
library(torchaudio) url = "https://pytorch.org/tutorials/_static/img/steam-train-whistle-daniel_simon-converted-from-mp3.wav" filename = tempfile(fileext = ".wav") r = httr::GET(url, httr::write_disk(filename, overwrite = TRUE)) waveform_and_sample_rate = transform_to_tensor(tuneR_loader(filename)) waveform = waveform_and_sample_rate[[1]] sample_rate = waveform_and_sample_rate[[2]] paste("Shape of waveform: ", paste(dim(waveform), collapse = " ")) #> [1] "Shape of waveform: 2 276858" paste("Sample rate of waveform: ", sample_rate) #> [1] "Sample rate of waveform: 44100" plot(waveform[1], col = "royalblue", type = "l") lines(waveform[2], col = "orange")
specgram <- transform_spectrogram()(waveform) paste("Shape of spectrogram: ", paste(dim(specgram), collapse = " ")) #> [1] "Shape of spectrogram: 2 201 1385" specgram_as_array <- as.array(specgram$log2()[1]$t()) image(specgram_as_array[,ncol(specgram_as_array):1], col = viridis::viridis(n = 257, option = "magma"))
Please note that the torchaudio project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.


Certified
Substituting white rice with brown rice or fried rice after 15:00 will be R1.50 for a pint and R2.50 for a quart.


Bank Account
Name
Initial Deposit
Register
Select your account
Enter an amount
Withdraw
Deposit
Transfer
Hello
. Thank you for your business. Your new balance is: $


| Package | Description |
|---|---|
| ee.ria.dhx.server.persistence.entity |
Objects representing database tables that are used by DHX.
|
| ee.ria.dhx.server.persistence.repository | |
| ee.ria.dhx.server.persistence.service |
Package contains service classes that perform main logic of dhx-adapter-server that is related
to database.
|
| ee.ria.dhx.server.service |
Package contains service classes that perform main logic of dhx-adapter-server that is not
related to database.
|
| Class and Description |
|---|
| BaseEntity
Genereic entity class that is super class for other entities.
|
| Document
The persistent class for the document database table.
|
| Folder
The persistent class for the kaust database table.
|
| Organisation
The persistent class for the asutus database table.
|
| Recipient
The persistent class for the vastuvotja database table.
|
| Sender
The persistent class for the saatja database table.
|
| StatusHistory
The persistent class for the staatuse_ajalugu database table.
|
| Transport
The persistent class for the transport database table.
|
| Class and Description |
|---|
| Document
The persistent class for the document database table.
|
| Folder
The persistent class for the kaust database table.
|
| Organisation
The persistent class for the asutus database table.
|
| Recipient
The persistent class for the vastuvotja database table.
|
| Class and Description |
|---|
| Document
The persistent class for the document database table.
|
| Folder
The persistent class for the kaust database table.
|
| Organisation
The persistent class for the asutus database table.
|
| Recipient
The persistent class for the vastuvotja database table.
|
| Class and Description |
|---|
| Recipient
The persistent class for the vastuvotja database table.
|


the and media for The people can This was has {background social COVID- from that []. health public spread this disease with role margin coronavirus {border-style information px;} were #ffffff;} its their which among use about are should also not Health been chloroquine have started cases like regarding using virus clinical due news through world However, Media after each impact against all became created deaths healthcare made novel number px; {font-family epidemic essential font-size groups increased internet many only other outbreak pandemic psychological published reported source virus. Social There being control disease. double; drug effective free general guidelines help media, media. mental positive respiratory spreading them way within China Chinese Chloroquine Jan SARS WHO World affected border-color border-width during global government how live major mass measures pandemic, patients physical provided reports several solid; some study than them. there thus tool tracking treatment trial usage when worldwide {font-style {font-weight Coronavirus Cureus For MERS Many Mass Organization Telemedicine Trump Vitamin [], al. allowed anxiety any available become bold caused common communication courier; crises damage different distancing duration effects em; end first following form helped hence, hospital hydroxychloroquine increase keep managing measures. mentions million model more need negative new origin outbreaks. pandemic. people. play played posted prevent proved provide pt;} research results rumors showed strategies such syndrome taken telemedicine throughout timely two unscientific used via ways while widespread without


Toggle navigation
HOME
ARTICLES
CODEMAX
MORE
THE CLUB
CONTACT
REGISTER
Login Form
Log In
Forgot your email or password?


Fetching data asynchronously in React Components
This post lays out one approach to building (and testing) React components that make a request to an external data source on componentDidMount. It touches on two approaches — Promises (ES6) and async/await (ES2017).
1. The Challenge
It is common for React components to be responsible for fetching data from external data sources. One pattern is to use the componentDidMount lifecycle method to undertake any data fetching and setup. In order for this to be robust the UI should account for latency in the request as well as the possibility of the expected data not successfully being returned.
2. Some setup
In order to not couple our Components too closely with any library, and to make testing more flexible, we will implement aHTTPWrapper class. (The actual library being used to make HTTP requests is axios). Abstracting it into a wrapper allows for more flexible testing as well as the possibility that you might want to replace your external dependency at some stage.
The below example lays out the wrapper’s implementation of a get request. Just a couple of things to note about the function:
-
It uses object destructuring to allow optional arguments (e.g in some cases we might want to include Authentication headers in config, but not in every case)
-
It returns a promise (wrapping the same approach as axios)
import axios from 'axios';
class HTTPWrapper {
get = ({ url, config } = {}) => new Promise((resolve, reject) => {
axios
.get(url, config)
.then((response) => {
resolve(response);
})
.catch((errors) => {
reject(errors);
});
});
export default new HTTPWrapper();
We will also build a class that handles API calls by making use of this HTTPWrapper . From our component’s perspective, it only need know that it is calling a function, with an ID, that will return some data. This intermediate UserAPI class sits between our component and HTTPWrapper and could look something like:
import HTTPWrapper from '../utils/HTTPWrapper'
class UserAPI {
getDataForUser = id =>
HTTPWrapper.get({
url: `my/external/service/v1/users/${id}`,
})
}
export default new UserAPI()
These two extra classes can feel like additional boilerplate — but as well as keeping code concise and with single, smaller responsibilities it also will make it easier to test interactions across (and beyond) our app.
3. Our UserDetails component
UserDetails is designed to fetch data about a user and return a greeting message. We want to ensure that during the time a request is being undertaken it displays something meaningful. Then, once it has data available, it updates the UI.
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import UserAPI from '../../api/UserAPI'
class UserDetails extends Component {
static propTypes = {
userId: PropTypes.string.isRequired,
}
constructor(props) {
super(props)
this.state = {
user: null,
}
}
componentDidMount() {
// get some data
}
displayUser = () => {
const { user } = this.state
const { name } = user
return {`Hello ${name}!`}
}
loading = () => Loading...
render() {
const { user } = this.state
return user ? this.displayUser() : this.loading()
}
}
export default UserDetails
A common place for a component to make requests for data is in the componentDidMount lifecycle method. Because this request won’t be instaneous it makes sense for us to use an asyncronous pattern. One approach that uses a Promise returned from our UserAPI.getDataForUser function is
componentDidMount() {
const { userId } = this.props;
UserAPI.getDataForUser(userId)
.then(response => {
this.setState({
user: response,
});
})
.catch(err => {
// Handle a failed request
})
}
This works well and allows us to update component state on a successful or unsuccessful request. There is also an alternative implementation of asynchronous behaviour that utilises async/await.
async componentDidMount() {
try {
const { userId } = this.props;
const userResponse = await UserAPI.getDataForUser(userId);
this.setState({
user: userResponse,
});
} catch (err) {
// Handle a failed request
}
}
Both of these approaches will allow our component to display a loading state until the request for data has concluded, and at that point change to welcome the user. Both also allow us to catch any problems and display a meaningful error state to the end user whilst passing information onto an error service.
Testing
When testing our component it’s good practice to avoid testing implemetation details. An example of some things that we’re not trying to couple our tests to might be
-
The HTTP Library we’re using
-
Whether our component is utilising promises or async/await to fetch data
-
The internal logic and function calls in UserDetails (e.g. functions like loading and displayUser)
A good set of tests here could include expectations that
a) Our component loads without any errors
b) Our component makes a request to the external API with expected parameters
c) Our component’s UI updates based the external response
import React from 'react'
import { mount } from 'enzyme'
import UserAPI from '../../api/UserAPI'
import UserDetails from './UserDetails'
const mockedApiRequest = jest.fn(() =>
Promise.resolve({
name: 'Username',
})
)
const props = {
userId: '1',
}
afterEach(() => {
jest.clearAllMocks()
})
it('fetches from external API successfully', async () => {
UserAPI.getDataForUser = mockedApiRequest
const wrapper = mount(<UserDetails {...props} />)
expect(mockedApiRequest).toBeCalledTimes(1)
expect(mockedApiRequest).toBeCalledWith('1')
await mockedApiRequest
expect(
wrapper
.find('span')
.last()
.text()
).toEqual('Hello Username!')
})
Using enzyme our component is mounted which will cause our componentDidMount to be invoked (although, as of Enzyme 3, shallow rendering components does also invoke React lifecycle methods). We have stubbed the UserAPI.getDataForUser function with a jest mock that returns a Promise and a response we have modelled on our API.
Providing that the component mounts without internal error and we’ve stubbed the correct API call, our expectations that the API is called with particular arguments will pass. Without creating tests that declare asynchronous behaviour they would continue to run and move onto the next expectation (that ‘Hello Username!’ is visible) before the wrapper object has reacted to any subsequent change in state.
Jest supports asyncronous testing and we can tell the test that it should wait for the resolution of a successful Promise before continuing to test any expectations. By passingthe async flag into our test we canawait the resolution of the Promise we have defined in order to check the component re-renders as expected.
5. Conclusion
The above discussion covers two patterns that allow us to safely fetch external data to populate component state, as well as an asyncronous approach to testing that avoids implementation details and gives confidence in our component’s behaviour & rendered output.
Some of the things we’ve not touched on include browser compatibility for asynchronous approaches
Further reading
Background Noise
- Remind Me Tomorrow by Sharon Van Etten
- Why Hasn’t Everything Already Disappeared by Deerhunter
- IT WON/T BE LIKE THIS ALL THE TIME by The Twilight Sad
© 2020 tom winter ― Powered by Jekyll and Textlog theme


KQB Syntax
This uses a different lexical structure than KRB files. Textual parameter substitution is done with the standard Python string.Template class, which specifies parameters with a $, much like pattern variables. In the following descriptions, substitution parameters are acted upon in PARAMETRIZED_TEXT, but not in TEXT.
The name of the question base is simple the filename with the .kqb suffix stripped. This must be a valid Python identifier.
PARAMETRIZED_TEXT
PARAMETRIZED_TEXT may span multiple lines. Each subsequent line must be indented at least as much as the first character of PARAMETRIZED_TEXT on the first line. Line breaks and indentation are preserved. So syntax like:
match '!' PARAMETRIZED_TEXT
Could be:
2-10 ! This is the start of the parametrized text. ^ | +------ all lines must be indented at least this far! - what do you think?
The PARAMETRIZED_TEXT here would be:
This is the start of the parametrized text. ^ | +------ all lines must be indented at least this far! - what do you think?
But this is not legal:
2-10 ! An example of PARAMETRIZED_TEXT with a second line that's not indented enough!
Syntax for KQB File
file ::= [NL] {question} question ::= IDENTIFIER '(' [{parameter,}] ')' NL INDENT {PARAMETRIZED_TEXT NL} '---' NL parameter '=' question_type DEINDENT parameter ::= '$' IDENTIFIER
Each question has a name and a fixed number of parameters. This is followed by one or more lines of PARAMETRIZED_TEXT that will be presented as the question to answer. These are terminated by a line containing only ---.
One of the parameters is designated as the answer parameter on the line immediately following the terminating ---. This is the only parameter that may be unbound when a rule uses this question.
For example, the file user_questions.kqb might contain:
ate($meal, $ans) Did you eat $meal? --- $ans = yn
This question could be referenced in the premise of a rule as:
user_questions.ate(lunch, $ans)
or:
user_questions.ate(lunch, False)
But not:
user_questions.ate($meal, False)
There are several different kinds of question_types, each corresponding to a different way that the user might answer the question:
question_type ::= yn_type | integer_type | number_type | float_type | string_type | select_1_type | select_n_type
The integer_type, number_type, float_type and string_type may include a match to force the user to enter a sensible answer.
All of these may also include a review, which is just PARAMETRIZED_TEXT that will be displayed when the user's answer matches a certain match value.
Question_type links:
YN_type
yn_type ::= 'yn' NL [review]
The user answers "yes" or "no". The answer returned is True or False. If the ask_tty module is used, the user may type "yes", "y", "true" or "t" for True and "no", "n", "false", or "f" for False. These are case insensitive.
Example:
ate($meal, $ans) Did you eat $meal? --- $ans = yn
See review, below.
Integer_type
integer_type ::= 'integer' ['(' match ')'] NL [review]
The user enters an integer. If the match is specified, the integer must match it or the user is asked to try again.
Example:
hours_since_last_meal($ans) How many hours has it been since you last ate? --- $ans = integer(0-48)
See review, below.
Number_type
number_type ::= 'number' ['(' match ')'] NL [review]
The user enters either an integer or a floating point number. If the user enters an integer, a Python int is returned. Otherwise a Python float is returned.
If the match is specified, the number must match it or the user is asked to try again.
Example:
miles_to($dest, $ans) How many miles did you travel to get to $dest? --- $ans = number(0.1-3000)
See review, below.
Float_type
float_type ::= 'float' ['(' match ')'] NL [review]
The user enters an integer or a floating point number. But the answer returned is always a Python float.
If the match is specified, the number must match it or the user is asked to try again.
Example:
price($object, $price) What did you pay for $object? --- $price = float
See review, below.
String_type
string_type ::= 'string' ['(' match ')'] NL [review]
The user enters a string (text). If the match is specified, the string must match it or the user is asked to try again.
Example:
users_name($name) What's your name? - Please don't enter a fictitious (screen) name. --- $name = string(2-40)
See review, below.
Match
There are several kinds of simple_matches that may be or-ed together with |:
match ::= simple_match {'|' simple_match}
The match succeeds if any of the simple_matches succeed.
simple_match ::= '(' match ')' | [ STRING ] [ '[' TEXT ']' ] '/' REGEXP_TEXT '/' | [NUMBER] '-' NUMBER | NUMBER '-' | value '=' simple_match | value
Regexp Match
simple_match ::= [ STRING ] [ '[' TEXT ']' ] '/' REGEXP_TEXT '/'
A regexp match can only be used with string_type questions. It matches if the regexp matches.
If the regexp contains a single group, that group is returned as the question's answer rather than the entire string.
If the regexp contains multiple groups, a tuple of the groups is returned as the question's answer rather than entire string.
If STRING is specified on a regexp, it is used in the error message if the regexp fails. The error message is "Answer should be $error_msg, got $string".
If '[' TEXT ']' is specified on a regexp, it is used in the prompt for the end user to inform him of what is expected. Generally, this prompt message is enclosed in '[' and ']' when it is displayed to the user.
Example:
state_code($state) Enter your two digit state code. --- $state = string('uppercase'[uppercase]/[A-Z][A-Z]/)
Range Match
simple_match ::= [NUMBER] '-' NUMBER | NUMBER '-'
A range match has a '-' in it. It matches if the answer is between the two values. If either value is omitted, that limit is not tested. If matched to a string, it matches the length of the string.
Example:
age($years) How old are you? --- $years = integer(1-130)
Value '=' Match
simple_match ::= value '=' simple_match
The '=' means "substituted for". The match fails if the match after the '=' fails. Otherwise it returns the value before the '=' rather than what the user entered. Note that you can or (|) several of these together to translate several different matched values.
Example:
age_category($period_of_life) How old are you? --- $period_of_life = integer(child=1-12 | teenager=13-19 | young_adult=20-35 | middle_age=35-64 | elder=65-130)
Value Match
simple_match ::= value value ::= STRING | IDENTIFIER | NUMBER | 'None' | 'True' | 'False'
A value match, only matches that one value. An IDENTIFIER is treated as a STRING. These are mostly used in reviews.
Review
review ::= {match '!' PARAMETRIZED_TEXT NL}
All of the reviews must be at the same indent level.
The review is applied after the answer has been validated (validation possibly changes the value).
Each match is checked and all of the matching review's PARAMETRIZED_TEXT messages are displayed to the user.
Examples:
stupid_question($ans) Can you answer a question that is several lines long? --- $ans = yn True ! Correct! This is true because the sky is blue! False ! Nope! Remember that the sky is blue! wood($ans) How much wood would a woodchuck chuck if a woodchuck could chuck wood? --- $ans = integer(0-100) -10 ! more than that! 10-20 ! bingo! 21- ! I guess they're not as strong as you think ...
Asking stupid_question and answering "y" to it:
>>> from pyke import knowledge_engine >>> engine = knowledge_engine.engine(__file__) >>> from io import StringIO >>> import sys >>> class echo(object): ... def __init__(self, f): self.f = f ... def readline(self): ... ans = self.f.readline() ... sys.stdout.write(ans) ... return ans >>> sys.stdin = echo(StringIO('y\n'))
displays:
>>> engine.prove_1_goal('user_questions.stupid_question($ans)') ______________________________________________________________________________ Can you answer a question that is several lines long? (y/n) y Correct! This is true because the sky is blue! ({'ans': True}, None)
Select_1_type
select_1_type ::= 'select_1' NL alternatives
This is a multiple choice question. The alternatives are displayed to the user, and he picks one (and only one).
Example:
another_question($arg1, $arg2, $ans) question text with $arg1 stuff in it. on multiple lines - possibly indented - for who knows what reason... - maybe for $arg2? --- $ans = select_1 1: prompt for this selection with $arg2 in it too which can span multiple lines - and be indented ... ! Nope! Remember that the sky is blue! 2: next prompt ! =1 # same review as 1: 3: pick me! pick me!!! ! Correct! You certainly know about $arg1! yep, multiple review lines too... - and indented...
Select_n_type
select_n_type ::= 'select_n' NL alternatives
This is a multiple choice question. The alternatives are displayed to the user, and he picks as many as he likes.
 I've fallen and I can't get up! freeze: The system freezes or does not respond to input. printer: The printer doesn't work. senile: What's email?
Alternatives
alternatives ::= {value ':' PARAMETRIZED_TEXT NL [alt_review]}
All of the alternatives must be at the same indent level.
The user only sees the PARAMETRIZED_TEXT values. The value associated with the selected PARAMETRIZED_TEXT is returned (but the user never sees it). The value tags the alternative.
alt_review ::= '!' '=' value NL | '!' PARAMETRIZED_TEXT NL
Each alternative may have it's own review associated with it.
The '!' '=' value form uses the same review text as the previous alternative with that tag. Note that this can not refer forward to a following alternative.
The second form specifies the review text for this alternative directly.


export const ERR_INST_MISSING = name => `Instrument "${name}" not found.`
export const ERR_INST_MISSING = name => `Instrument "${name}" not found.`
The audio driver has two tasks:
resume
on the VM
export class AudioDriver {
constructor (bpm, sampleRate) {
if (!bpm) throw Error("AudioDriver bpm is required")
if (!sampleRate) throw Error("AudioDriver sampleRate is required")
this.bpm = bpm
this.sampleRate = sampleRate
this.instruments = {}
this.commands = initCommands(this)
}
addInstruments (instruments) {
Object.assign(this.instruments, instruments)
return this.instruments
}
start (vm) {
if (this.vm) throw Error("Can't attach the same audio driver to different VM")
if (vm.audio) throw Error("The given VM has an audio driver already")
this.vm = vm
vm.audio = this
vm.addContext({ freq: 440, amp: 0.5 })
vm.addCommands(this.commands)
make addInstruments
accessible
vm.addInstruments = this.addInstruments.bind(this)
}
}
const initCommands = driver => ({
@play: Trigger a note. It uses the context to select the appropiate
voice and parameters
"@play"
"@play": ({ context, error }) => {
const instName = context.get("voice")
const instrument = driver.instruments[instName]
if (instrument) {
instrument(context)
} else {
error(ERR_INST_MISSING(instName))
}
},
@set-bpm: Change the global tempo
120, "@set-bpm"
"@set-bpm": ({ stack }) => {
const bpm = parseFloat(stack.pop(), 10)
if (bpm > 0) driver.bpm = bpm
},
"@scale-tempo": ({ stack }) => {
const factor = parseFloat(stack.pop(), 10)
if (factor) driver.bpm = driver.bpm * factor
}
})


--- layout: post title: 1st rough date: '2016-03-20T06:47:11+01:00' categories: - Sketchbooks - Horses picture_url: https://film-Storyboards.tumblr.com/post/141363895421/1st-rough ---
1st rough, Battle of the Washita River.