roomai.doudizhu package¶
Submodules¶
roomai.doudizhu.DouDiZhuPokerAction module¶
-
class
roomai.doudizhu.DouDiZhuPokerAction.
DouDiZhuActionElement
[source]¶ -
rank_to_str
= {0: '3', 1: '4', 2: '5', 3: '6', 4: '7', 5: '8', 6: '9', 7: 'T', 8: 'J', 9: 'Q', 10: 'K', 11: 'A', 12: '2', 13: 'r', 14: 'R', 15: 'x', 16: 'b'}¶
-
str_to_rank
= {'A': 11, 'x': 15, 'b': 16, 'K': 10, 'J': 8, 'Q': 9, '3': 0, '2': 12, '5': 2, '4': 1, '7': 4, '6': 3, '9': 6, '8': 5, 'R': 14, 'r': 13, 'T': 7}¶
-
total_normal_cards
= 15¶
-
-
class
roomai.doudizhu.DouDiZhuPokerAction.
DouDiZhuPokerAction
(masterCards, slaveCards)[source]¶ Bases:
roomai.common.common.AbstractAction
-
isMasterStraight
¶ The master cards are straight
-
key
¶ The key of DouDiZhu Action
-
masterCards
¶ The cards act as the master cards
-
masterPoints2Count
¶ The count of different points in the masterCards
-
maxMasterPoint
¶ The max point in the master cards
-
minMasterPoint
¶ The min point in the master cards
-
pattern
¶ The pattern of the action
-
slaveCards
¶ The cards act as the slave cards
-
slavePoints2Count
¶ The count of different points in the slaveCards
-
roomai.doudizhu.DouDiZhuPokerEnv module¶
-
class
roomai.doudizhu.DouDiZhuPokerEnv.
DouDiZhuPokerEnv
[source]¶ Bases:
roomai.common.common.AbstractEnv
The DouDiZhuPoker game environment
-
classmethod
available_actions
(public_state, person_state)[source]¶ Generate all valid action given the public state and the person state
Parameters: - public_state –
- person_state –
Returns: A dict(action_key, action) contains all valid actions
-
classmethod
compete
(env, players)[source]¶ Use the game environment to hold a compete for the players
Parameters: - env – The game environment
- players – The players
Returns: scores for the players
-
forward
(action)[source]¶ The game environment steps with the action taken by the current player
Parameters: action – The action taken by the current player Returns: infos, public_state, person_states, private_state
-
init
(params={})[source]¶ Initialize the DouDiZhuPoker game environment with the initialization params.
The initialization is a dict with some options
- allcards: the order of all poker cards appearing
- record_history: whether to record all history states. if you need call the backward function, please set it to True. default False
- start_turn: players[start_turn] is first to take an action
An example of the initialization param is {“start_turn”:2,”record_history”:True}
Parameters: params – the initialization params Returns: infos, public_state, person_states, private_state
-
classmethod
roomai.doudizhu.DouDiZhuPokerInfo module¶
-
class
roomai.doudizhu.DouDiZhuPokerInfo.
DouDiZhuPersonState
[source]¶ Bases:
roomai.common.common.AbstractPersonState
The person state of DouDiZhu game environment
-
hand_cards
¶ The cards in the hand of the corresponding player
-
-
class
roomai.doudizhu.DouDiZhuPokerInfo.
DouDiZhuPokerHandCards
(cardstr)[source]¶ The hand cards in the DouDiZhuPoker game.
-
card_pointrank_count
¶ The card_pointrank_count is an array of counts for different card point cardpoint_to_rank = {‘3’:0, ‘4’:1, ‘5’:2, ‘6’:3, ‘7’:4, ‘8’:5, ‘9’:6, ‘T’:7, ‘J’:8, ‘Q’:9, ‘K’:10, ‘A’:11, ‘2’:12, ‘r’:13, ‘R’:14}. If key = “33rR”, card_pointrank_count = [2,0,…,0,1,1], len(card_pointrank_count) = 15
-
count2num
¶ The count2num is an array of the number of the different counts. For example, key = “333rR”, count2num = [0,2,0,1,0]. count2num[1] = 2 denotes that two cards (r and R) appear onces. count2num[3] = 1 that one card(3) appears three times
-
key
¶ The key of HandCards. For example, key = “33rR”.
-
num_card
¶ The number of cards in HandCards. For example, key = “33rR”, num_card = 4
-
-
class
roomai.doudizhu.DouDiZhuPokerInfo.
DouDiZhuPrivateState
[source]¶ Bases:
roomai.common.common.AbstractPrivateState
-
keep_cards
¶ A DouDiZhuPokerHandCards class about the keep cards
-
-
class
roomai.doudizhu.DouDiZhuPokerInfo.
DouDiZhuPublicState
[source]¶ Bases:
roomai.common.common.AbstractPublicState
The public state of DouDiZhuPoker
-
continuous_cheat_num
¶ The number of the continuous cheat actions.During the “playing” phase, if is_response is True, the current player need take an valid action with the same pattern as the license action, which was taken by the license player. Unless, he takes the check action. If two continuous cheat actions are taken, is_response will be false, so that the current player needn’t response the license action and can take any valid action
-
epoch
¶ The epoch denotes the count about a player takes an action.
-
first_player
¶ The players[first_player] is first to take an action
-
is_response
¶ is_response. During the “playing” phase, if is_response is True, the current player need take an valid action with the same pattern as the license action, which was taken by the license player. Unless, he takes the check action. If two continuous cheat actions are taken, is_response will be false, so that the current player needn’t response the license action and can take any valid action
-
keep_cards
¶ The keep cards
-
landlord_candidate_id
¶ The candiate landlord player id during the betting_for_be_landlord phase
-
landlord_id
¶ The landlord player id.
-
license_action
¶ The license action. During the “playing” phase, if is_response is True, the current player need take an valid action with the same pattern as the license action, which was taken by the license player. Unless, he takes the check action. If two continuous cheat actions are taken, is_response will be false, so that the current player needn’t response the license action and can take any valid action
-
license_playerid
¶ The license player id. During the “playing” phase, if is_response is True, the current player need take an valid action with the same pattern as the license action, which was taken by the license player. Unless, he takes the check action. If two continuous cheat actions are taken, is_response will be false, so that the current player needn’t response the license action and can take any valid action
-
phase
¶ There are two stages in DouDiZhu, namely 0) betting for being the landlord and 1) playing the game. 0 denotes the betting for being the landlord phase, 1 denotes the playing the game phase.
-


"Do not have anything in your home that you do not find useful or believe to be beautiful."
William Morris
Much better than walking along the edge in closed glass.
Faster than Forrest Gump, no one will catch you.
The past comes back to remember what we should do in the future.
Click here and see the details of the products
ProductsLearn more about our portfolio
PortfolioSolid as stone, light as wind and resistant as diamond, are our differentials.
Tailored for the best comfort and efficiency. We adapt your Bikcraft to your body.
In addition to helping to take care of the environment, taking cars off the street, all production is sustainable.
Learn more about our history
About"The real secret of happiness lies in having a genuine interest in all the details of everyday life."
William Morris


Holy guacamole! You should first fill in the names below.
Game Rules
A player continues to roll the dice until he decides to hold or
he scores 1.
While the player rolls dice everytime, the total score for
current round increments with dice value.
If scored 1 , the player not only get switched. But the round
score for the 1 scoring player is considered 0. To avoid such
scenario, a player can hold to save the current round score.
The first player to reach a score of 100 wins the match.


Serverless Authentication
Redirect localhost!
This is a frontend demonstration how Serverless Authentication works.
Providers
Token
Test
Token is valid for a minute
See also serverless.com
This is a frontend demonstration how Serverless Authentication works.
Token is valid for a minute
See also serverless.com


By Utplakshi
HTML is really a very simple language. It consits of ordinary texts, with commands that are enclosed by "<" and ">" characters, or between ann "&" and a " ;" . You don't really need to know much HTML to create a page, because you can copy bits of HTML from other pages that do what you want, then change the text! This page shows on the left as it appears in your browser, and the corresponding HTML code appears on the right. The HTML commands are linked to explanations of what they do.
HTML doesnt only use line breaks for ordinary texts.A white space of any type is treated as a single space. The code type of format can also bhi used in html, For example
#include <iostream>
int main() {
std::cout << "Hello World!";
return 0;}
(a+b)2= a2 + b2 + 2ab.
If you want to put multiple space entity by multiple times for example, I would like to use more than 3 blank spaces   here. If you want to use the line break command you can use "<BR>",and for the paragraph break, "<p>" command, Which will insert a blank line.You can use some of the subscript,superscript and mark features as given below
1st   2nd   Mark and Emphasized format features
Starting and Stopping Commands
Most HTML Command come in pairs: for example, "&H4>" marks the beginning of a size 4 heading and "&/H4>" marks the end of it.The closing command is always the same as opening command. The closing command is same as the opening command instead of as "/".
Modifiers are also used sometimes including the basic command, inside the opening commands "< >".The modifier need not the be repeated in the closing command.
Copyright © 2020, by Utplakshi
If you would like the link or bookmark to this page the URL is:
www.javadb.com/java-se/


RT @jbcnconf: 📢SPEAKER ANNOUNCEMENT
@jasonrclark will be at #jbcn22
👉 In the talk “Better Understanding through Bytecode” he'll cover t…
5/25/2022, 3:31:07 AM
Favs: 0
Retweets: 0
link--- layout: tweet ---
RT @jbcnconf: 📢SPEAKER ANNOUNCEMENT
@jasonrclark will be at #jbcn22
👉 In the talk “Better Understanding through Bytecode” he'll cover t…
5/25/2022, 3:31:07 AM
Favs: 0
Retweets: 0
link


|
Fusion3D
Version 6.04
|
Creates a single low-resolution texture file that can be used to speed up visualization of very large maps. More...
#include <mosaicr.h>
Public Member Functions | |
| mosaicr (QWidget *parent=Q_NULLPTR) | |
Creates a single low-resolution texture file that can be used to speed up visualization of very large maps.
The code was originally written to make a downsampled mosaic from a group of.tif texture files for the Woson North Korea map. This map is huge and reading a full - scale texture file for each low - res tile – reading it, cropping it, then downsampling it – was taking an unacceptibly long time.
The resulting texture image will be just large enough to encompass all the input files and will be black in any areas where there is no input data.
The code moves file - by - file, summing each input pixel from that file into the appropriate(downsampled) mosaic pixel. Thus every output pixel is the average of all the input pixels that overlap it.
The code is currently implemented for MrSID and GeoTiff input files and a GeoTiff output file. It cannot write MrSID files since we do not have a license to write MrSID(only to read these files). Since the Fusion3D viewer reads the resulting output file only once at full resolution, there is not a significant advantage of MrSID over GeoTiff anyway.
A limitation of the current implementation is that it doesn't do well with making a mosaic from grayscale images. These cant be matched nicely with color MrSID imagery. Adding false color to the images could be done as it is in the Fusion3D viewer but this would require associated elevation images, greatly complicating the implementation and the user interface. The Fusion3D viewer is also not yet capable of adding false color to a grayscale mosaic.
| mosaicr::mosaicr | ( | QWidget * | parent = Q_NULLPTR | ) |


--- layout: post title: Exploring canvas drawing techniques popular: popular tags: - js ---
I recently started working on adding some good-looking brushes to Fabric.js. We've had free drawing functionality for a while, but it was... laughable. Just a simple pencil of varying thickness. Far from anything you would see in those amazing drawing applications popping up in the last few years — Mr. doob's Harmony, deviantART's Muro, or mudcu.be Sketchpad. Freedrawing is one of the strongest points of canvas, so it's a shame not to have something good in a canvas library like Fabric.
image by Krzysztof Banaś
I started experimenting with different styles and techniques — edge smoothing, bezier curves, ink and chalk and pen and stamp and patterns — oh my. Turns out there's not much written about this on the web. Not in the context of Javascript and <canvas>, anyway. The best you can do is look at the demos source code to get a glimpse of what's going on.
So I've got an idea to create sort of an interactive tutorial. Taking you from the very basics (drawing a primitive mouse-following-line on canvas), all the way to those harmony brushes, with their sophisticated curves and strokes, spanning from the edges and curling around into weirdly beautiful structures. The tutorial pretty much reflects my own path of exploration.
I'll go over different code implementations of brushes so that you can understand how to implement free drawing on canvas yourself. And you can play with things around as we go.
Before proceeding, it's good to have general understanding of HTML5 canvas.
So let's start with a very basic approach.
Check out this Pen!
We observe "mousedown", "mousemove", and "mouseup" events on canvas. On "mousedown", we move pointer to clicked coordinates (ctx.moveTo
). On "mousemove", we draw a line to new coordinates of a mouse (ctx.lineTo
). Finally, on "mouseup", we end drawing by setting isDrawing
flag to false. This flag is used to prevent drawing when just moving mouse on canvas (without first clicking it). You could avoid flag by assigning "onmousemove" event handler right in "onmousedown" one (and then removing it in "onmouseup"), but flag is a simple solution that works just as well.
Well, that's a start. Now, we can control the line thickness by changing value of ctx.lineWidth
. However, with thick line comes thick responsibility jagged edges. This happens on "sharp turns" and can be solved by setting ctx.lineJoin
and ctx.lineCap
to "round" (see MDN for examples of how these affect rendering).
Check out this Pen!
Now the lines are not jagged around corners. But they aren't very smooth on the edges either. This is because there's no antialiasing hapenning here (controlling antialiasing on canvas has never been straightforward). So how do we emulate it?
One way to make edges smooth is with the help of shadows.
Check out this Pen!
All we've added is ctx.shadowBlur
and ctx.shadowColor
. Edges are definitely smoother now, since lines are surrounded with a shadow. But there's still a little problem. Notice how line is thinner and blurry at the beginning but then becomes thicker and more solid at the tail. An interesting effect on its own, but perhaps not exactly what we want. So why does this happen?
Turns out this is due to shadows overlapping each other. Shadow from current stroke overlaps shadow from previous stroke which overlaps shadow from previous stroke, and so on. The more overlapping shadows, the less blurry and the thicker line is. So how would we go about fixing this?
One way to avoid these kind of issues is to always stroke once. Instead of blindly stroking on every mousemove, we can introduce a state — store points in an array, and always stroke through them once.
Check out this Pen!
As you can see, it looks the same as the first example. Now we can try adding shadow here. Notice how it stays even throughout entire path.
Check out this Pen!
Another smoothing option is to use radial gradients. Gradients allow for more even color distribution, unlike shadows which often comes out more blurry than "smooth".
Check out this Pen!
But, as you can see, stroking with gradient has other issues. Notice how we're simply filling area with circular gradient on each mousemove. When moving mouse quick, we get a sequence of disconnected circles rather than a straight line with smooth edges.
One way to solve this is by generating additional points whenever there's too much distance between any of them.
Check out this Pen!
Finally a decently smooth curve!
You might notice a small change in the above example. Instead of storing all points of a path, we only store last one. And we always stroke from that last one to the current one. Having last point is all we really need to calculate the distance between it and the current one. If the distance is too large, we stroke more in between. The good thing about this approach is that we use less memory by not having entire points
array!
One interesting concept I came across was using bezier lines instead of straight ones. This allows for curves of a free-drawn path to be naturally smoother. The idea is to replace straight-line stroke with quadraticCurveTo
, using middle point between two consecutive points as quadratic curve control points. Try it:
Check out this Pen!
So there you have it: some basic variations of drawing and smoothing lines, from simple few-liner to more complex curve-based solution. Let's move on to something more fun.
One of the tricks in a realistic brush toolbox is to simply stroke with an image. I came across this technique in this blog post by Andrew Trice. The idea is to fill with an image of a little chunk of a stroke, using last-point-technique. This opens a huge number of possibilities.
Check out this Pen!
Depending on an image, we can achieve different brush styles. In this case, it's something resembling a thick brush.
An interesting twist (excuse the pun) to a previous technique is to fill path with same image but rotating it randomly every time it's rendered. If we do this, we can get something resembling a fur (or a garland?).
Check out this Pen!
When it comes to simulating a pen, a nice solution is to simply randomize segment width of a path! We can still use good-old moveTo
+lineTo
combination, but change "lineWidth" every time stroke occurs. Here's how it looks:
Check out this Pen!
One thing to keep in mind is that, in order for drawing to look realistic, randomized values should be not too far apart.
Another pen simulation is done via multiple strokes. Instead of stroking between points once, we add 2 more passes. But we don't want to stroke at the same spot, as that wouldn't change anything. Instead, we take couple random points (blue dots on a picture) next to original (green dots on a picture), and stroke from there. So instead of 1 line, we get 2 lines "sloppily" stroked right next to the original one. Perfect simulation of a pen!
Check out this Pen!
There's so much you can do with this "multiple stroke" technique. I urge you to try your own variations. Here's one example where, if we increase line thickness and offset 2nd pass just slightly, we get a simulation of a thick brush. Those blank spots on the edges is what makes it look realistic.
Check out this Pen!
If we implement multiple strokes, but at even and small offsets, we can get something resembling a sliced brush again. This time, without using an image. The path simply comes out skewed.
Check out this Pen!
If we take the same brush as in previous example, and give each stroke lesser and lesser opacity, we get an interesting effect like this.
Check out this Pen!
But enough with straight strokes. Can we apply the same technique to, say, bezier-curve based path? Of course. We just need to draw each curve at an offset from the original points. This is how it looks:
Check out this Pen!
We can also use same "fading" technique where each line has lesser opacity. This makes these lines look even more elegant.
Check out this Pen!
As with straight strokes, the possibilities with bezier curves are endless.
After we learned how to stroke lines and curves, implementing stamp brush couldn't be simpler! All we need is to draw certain shape on every mouse move, at a location of a mouse. That's it. Here's an example of stamping with a red circle.
Check out this Pen!
You can see the same issues with intermediate points, which we can solve with the same technique of prefilling. The prefilling in case of stamps tends to create pretty interesting trail-like or tube-like effects. You can control the density of a tube by changing interval at each points are prefilled between last point and current.
Check out this Pen!
Of course we can always spice things up, changing each stamp in some way. For example, randomly varying radius and opacity in the 1st example gives us this.
Check out this Pen!
When it comes to the kind of stamp, you can really go as far as you can — anything from basic shapes (e.g. circle) like we've just seen to more complex paths, made of hundreds or thousands of curves. The only limiting aspect here is performance. Here's an example of stamping with a simple five-pointed star.
Check out this Pen!
And here's the same star, but rotated randomly on each move, for a bit more natural feel.
Check out this Pen!
Heck, let's radomize even more — size, angle, opacity, color, thickness! Now isn't that fun.
Check out this Pen!
We're also not limited to just shapes. One option is to manipulate pixels around mouse point directly. A simple example would be to just randomize their color and location.
Check out this Pen!
Now that we went over stroking and stamping, let's take a look at a completely different beast — patterns. We can use canvas' createPattern
filling the path with it as we go. This makes for some very interesting effects. Let's take a look at a simple dot pattern.
Check out this Pen!
Notice how the pattern is created here. We're instantiating mini canvas, drawing circle on it, then using that canvas as a pattern on a main canvas! We might have just as well used a plain image, but the beauty of using canvas is that we have programmatic access to it and can change it anyway we like. This means we can create dynamic patterns, e.g. changing color of a circle in a patttern, its radius, etc. It also means that we can experiment with patterns quicker and easier.
Based on previous example, you should be able to create something similar. Let's say a horizontal lines pattern.
Check out this Pen!
...or vertical lines, with interchanging colors.
Check out this Pen!
...or even multiple lines with varying colors. Once again, everything is possible. Just think of some pattern and try to create it on a mini canvas. The rest is taken care by createPattern
and path filling.
Check out this Pen!
Finally, here's an example of using image-based pattern together with bezier-curved path. All that's changed here is that we're passing an image object to createPattern
(and then assigning resulting pattern to strokeStyle
).
Check out this Pen!
Now what about goold-old spray brush? There's few ways we can implement it. One of them is to simply fill area (pixels) around mouse point with color. The larger the area (radius), the thicker spray is. The more pixels we fill, the denser it is.
Check out this Pen!
You might notice that previous approach does not really paint like a real spray. A real spray paints area continuously, not just when we move a mouse/brush. In order to achieve this, we need to paint area at a constant interval while the mouse is pressed. This way, certain areas can be made darker just by "holding a spray" there longer.
Check out this Pen!
The previous example is more realistic but not fully so. Real spray throws paint over a round area, not rectangular. So let's try to distribute pixels over a round area.
Check out this Pen!
Much better.
Finally, is there anything else we can do to make spray more realistic? Aside from using an image as a stamp, of course. We can certainly make paint spread out even more sporadically, as it would in a real life. If we change opacity of each of the painted pixels, we get a very similar effect.
Check out this Pen!
The concept of connecting neighbour points was popularized by zefrank's Scribbler and Mr. doob's Harmony. If you remember Harmony brushes like sketchy, shaded, chrome — that's the effect I'm talking about.
The idea is: add additional strokes between nearby points of already drawn path. This usually creates an effect of a sketch, or a web, or a shading of some sort; additional strokes add illusion of darker spots in small, "bended" areas.
A naive approach would be to take our first simple example of point-based brush, and add extra stroking. For each point along the path, we would stroke towards one of previous points on a path:
Check out this Pen!
You can kind of start to see something resembling Harmony's brushes, but it's not exactly the same. It could be made better by reducing opacity (i.e. contrast) of additional strokes, to make them more realistic and shadowy. But to recreate effect fully, we need to follow a different algorithm.
Check out this Pen!
The part responsible for "nearby" stroking is this:
var lastPoint = points[points.length-1];
for (var i = 0, len = points.length; i < len; i++) {
dx = points[i].x - lastPoint.x;
dy = points[i].y - lastPoint.y;
d = dx * dx + dy * dy;
if (d < 1000) {
ctx.beginPath();
ctx.strokeStyle = 'rgba(0,0,0,0.3)';
ctx.moveTo(lastPoint.x + (dx * 0.2), lastPoint.y + (dy * 0.2));
ctx.lineTo(points[i].x - (dx * 0.2), points[i].y - (dy * 0.2));
ctx.stroke();
}
}
What's going on here? Looks crazy. Took me a while to understand but the concept is strikingly simple!
When drawing a line, we check entire distance of already-drawn path comparing all the points to the current (last) one. If the point is in certain proximity (d < 1000
) of a last one, we move pointer to it and stroke a line from there to the current point. dx * 0.2
and dy * 0.2
give those additional strokes a bit of offset.
That's it. Simple idea, powerful effect.
An interesting twist to this technique — seen in Harmony — is to create fur effect. Instead of stroking towards the nearby point (from the last one), the stroke is made to the opposite direction. With a little bit of offset, it produces furry strokes around certain (close) areas.
Check out this Pen!
Shortly after investigating Harmony brushes, I came across this wonderful blog post by Lukáš Tvrdý, explaining nicely some of the variations of neighbor-points technique. He describes how different parameters affect the strokes and the kind of effects they produce. Definitely worth checking out.
So there you have it — some of the basic as well as more interesting drawing techniques. We've only scratched a surface here. There are endless possibilities to customize either of the brushes, creating even more exciting effects. Change opacity or color, width or offsets, introduce random factor, and a whole new effect is born.
Try experimenting with them on your own!


?GARDEN
01498007
New
York
Botanical
Garden
pollen,
spore
ortjeaf^ample
removed
ãaª,
/?.
/3t-r*Z*'"
aMvvS
Institution
'
D.È
^
/l4/v6'C
THE
NEW
YORK
BOTANICAL
GARDEN
EXPLORATION
OF
CUBA
S.
Loma
Menoura,
Oriente
Base
680
Meters
Altitude,
to
summit
I000
Meters
Altitude
01498007
Legend -
Level of confidence that token is an accurately-transcribed word
extremely low
very low
low
undetermined
medium
high
very high


Chapter 23 Bayesian data analysis 3
23.1 Load packages and set plotting theme
library("knitr") # for knitting RMarkdown
library("kableExtra") # for making nice tables
library("janitor") # for cleaning column names
library("modelr") # for doing modeling stuff
library("tidybayes") # tidying up results from Bayesian models
library("brms") # Bayesian regression models with Stan
library("rstanarm") # for Bayesian models
library("cowplot") # for making figure panels
library("ggrepel") # for labels in ggplots
library("gganimate") # for animations
library("GGally") # for pairs plot
library("bayesplot") # for visualization of Bayesian model fits
library("tidyverse") # for wrangling, plotting, etc.
opts_chunk$set(
comment = "",
results = "hold",
fig.show = "hold"
)
theme_set(
theme_classic() + #set the theme
theme(text = element_text(size = 20)) #set the default text size
)
23.2 Load data set
Load the poker data set.
df.poker = read_csv("data/poker.csv") %>%
mutate(skill = factor(skill,
levels = 1:2,
labels = c("expert", "average")),
skill = fct_relevel(skill, "average", "expert"),
hand = factor(hand,
levels = 1:3,
labels = c("bad", "neutral", "good")),
limit = factor(limit,
levels = 1:2,
labels = c("fixed", "none")),
participant = 1:n()) %>%
select(participant, everything())
Parsed with column specification:
cols(
skill = col_double(),
hand = col_double(),
limit = col_double(),
balance = col_double()
)
23.3 Poker
23.3.1 Visualization
Let’s visualize the data first:
df.poker %>%
ggplot(mapping = aes(x = hand,
y = balance,
fill = hand)) +
geom_point(alpha = 0.2,
position = position_jitter(height = 0, width = 0.1)) +
stat_summary(fun.data = "mean_cl_boot",
geom = "linerange",
size = 1) +
stat_summary(fun.y = "mean",
geom = "point",
shape = 21,
size = 4) +
labs(y = "final balance (in Euros)") +
scale_fill_manual(values = c("red", "orange", "green")) +
theme(legend.position = "none")
23.3.2 Linear model
And let’s now fit a simple (frequentist) regression model:
fit.lm = lm(formula = balance ~ 1 + hand,
data = df.poker)
fit.lm %>% summary()
Call:
lm(formula = balance ~ 1 + hand, data = df.poker)
Residuals:
Min 1Q Median 3Q Max
-12.9264 -2.5902 -0.0115 2.6573 15.2834
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 5.9415 0.4111 14.451 < 2e-16 ***
handneutral 4.4051 0.5815 7.576 4.55e-13 ***
handgood 7.0849 0.5815 12.185 < 2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 4.111 on 297 degrees of freedom
Multiple R-squared: 0.3377, Adjusted R-squared: 0.3332
F-statistic: 75.7 on 2 and 297 DF, p-value: < 2.2e-16
23.3.3 Bayesian model
Now, let’s fit a Bayesian regression model using the brm()
function:
fit.brm1 = brm(formula = balance ~ 1 + hand,
data = df.poker,
file = "cache/brm1")
fit.brm1 %>% summary()
Family: gaussian
Links: mu = identity; sigma = identity
Formula: balance ~ 1 + hand
Data: df.poker (Number of observations: 300)
Samples: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
total post-warmup samples = 4000
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Eff.Sample Rhat
Intercept 5.95 0.42 5.12 6.79 3609 1.00
handneutral 4.38 0.59 3.24 5.56 3489 1.00
handgood 7.07 0.59 5.94 8.22 3553 1.00
Family Specific Parameters:
Estimate Est.Error l-95% CI u-95% CI Eff.Sample Rhat
sigma 4.13 0.17 3.81 4.47 3578 1.00
Samples were drawn using sampling(NUTS). For each parameter, Eff.Sample
is a crude measure of effective sample size, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
I use the file =
argument to save the model’s results so that when I run this code chunk again, the model doesn’t need to be fit again (fitting Bayesian models takes a while …).
<IP_ADDRESS> Visualize the posteriors
Let’s visualize what the posterior for the different parameters looks like. We use the geom_halfeyeh()
function from the “tidybayes” package to do so:
fit.brm1 %>%
posterior_samples() %>%
select(-lp__) %>%
gather("variable", "value") %>%
ggplot(data = .,
mapping = aes(y = variable, x = value)) +
geom_halfeyeh()
And let’s look at how the samples from the posterior are correlated with each other:
fit.brm1 %>%
posterior_samples() %>%
select(b_Intercept:sigma) %>%
ggpairs(lower = list(continuous = wrap("points", alpha = 0.03)),
upper = list(continuous = wrap("cor", size = 6))) +
theme(panel.grid.major = element_blank(),
text = element_text(size = 12))
<IP_ADDRESS> Compute highest density intervals
To compute the MAP (maximum a posteriori probability) estimate and highest density interval, we use the mode_hdi()
function that comes with the “tidybayes” package.
fit.brm1 %>%
posterior_samples() %>%
clean_names() %>%
select(starts_with("b_"), sigma) %>%
mode_hdi() %>%
gather("index", "value", -c(.width:.interval)) %>%
select(index, value) %>%
mutate(index = ifelse(str_detect(index, fixed(".")), index, str_c(index, ".mode"))) %>%
separate(index, into = c("parameter", "type"), sep = "\\.") %>%
spread(type, value) %>%
kable(digits = 2) %>%
kable_styling(bootstrap_options = "striped",
full_width = F)
| parameter | lower | mode | upper |
|---|---|---|---|
| b_handgood | 5.93 | 7.10 | 8.20 |
| b_handneutral | 3.19 | 4.42 | 5.47 |
| b_intercept | 5.11 | 6.02 | 6.78 |
| sigma | 3.81 | 4.10 | 4.46 |
<IP_ADDRESS> Posterior predictive check
To check whether the model did a good job capturing the data, we can simulate what future data the Baysian model predicts, now that it has learned from the data we feed into it.
pp_check(fit.brm1, nsamples = 100)
This looks good! The predicted shaped of the data based on samples from the posterior distribution looks very similar to the shape of the actual data.
Let’s make a hypothetical outcome plot that shows what concrete data sets the model would predict:
# generate predictive samples
df.predictive_samples = fit.brm1 %>%
posterior_samples() %>%
clean_names() %>%
select(contains("b_"), sigma) %>%
sample_n(size = 20) %>%
mutate(sample = 1:n()) %>%
group_by(sample) %>%
nest() %>%
mutate(bad = map(data, ~ .$b_intercept + rnorm(100, sd = .$sigma)),
neutral = map(data, ~ .$b_intercept + .$b_handneutral + rnorm(100, sd = .$sigma)),
good = map(data, ~ .$b_intercept + .$b_handgood + rnorm(100, sd = .$sigma))) %>%
unnest(bad, neutral, good)
# plot the results as an animation
df.predictive_samples %>%
gather("hand", "balance", -sample) %>%
mutate(hand = factor(hand, levels = c("bad", "neutral", "good"))) %>%
ggplot(mapping = aes(x = hand,
y = balance,
fill = hand)) +
geom_point(alpha = 0.2,
position = position_jitter(height = 0, width = 0.1)) +
stat_summary(fun.data = "mean_cl_boot",
geom = "linerange",
size = 1) +
stat_summary(fun.y = "mean",
geom = "point",
shape = 21,
size = 4) +
labs(y = "final balance (in Euros)") +
scale_fill_manual(values = c("red", "orange", "green")) +
theme(legend.position = "none") +
transition_manual(sample)
# animate(p, nframes = 120, width = 800, height = 600, res = 96, type = "cairo")
# anim_save("poker_posterior_predictive.gif")
<IP_ADDRESS> Test hypothesis
One key advantage of Bayesian over frequentist analysis is that we can test hypothesis in a very flexible manner by directly probing our posterior samples in different ways.
We may ask, for example, what the probability is that the parameter for the difference between a bad hand and a neutral hand (b_handneutral
) is greater than 0. Let’s plot the posterior distribution together with the criterion:
fit.brm1 %>%
posterior_samples() %>%
select(b_handneutral) %>%
gather("variable", "value") %>%
ggplot(data = .,
mapping = aes(y = variable, x = value)) +
geom_halfeyeh() +
geom_vline(xintercept = 0,
color = "red")
We see that the posterior is definitely greater than 0.
We can ask many different kinds of questions about the data by doing basic arithmetic on our posterior samples. The hypothesis()
function makes this even easier. Here are some examples:
# the probability that the posterior for handneutral is less than 0
hypothesis(fit.brm1,
hypothesis = "handneutral < 0")
Hypothesis Tests for class b:
Hypothesis Estimate Est.Error CI.Lower CI.Upper Evid.Ratio
1 (handneutral) < 0 4.38 0.59 -Inf 5.36 0
Post.Prob Star
1 0
---
'*': The expected value under the hypothesis lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
# the probability that the posterior for handneutral is greater than 4
hypothesis(fit.brm1,
hypothesis = "handneutral > 4")
Hypothesis Tests for class b:
Hypothesis Estimate Est.Error CI.Lower CI.Upper Evid.Ratio
1 (handneutral)-(4) > 0 0.38 0.59 -0.56 Inf 2.89
Post.Prob Star
1 0.74
---
'*': The expected value under the hypothesis lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
# the probability that good hands make twice as much as bad hands
hypothesis(fit.brm1,
hypothesis = "Intercept + handgood > 2 * Intercept")
Hypothesis Tests for class b:
Hypothesis Estimate Est.Error CI.Lower CI.Upper Evid.Ratio
1 (Intercept+handgo... > 0 1.12 0.94 -0.42 Inf 7.6
Post.Prob Star
1 0.88
---
'*': The expected value under the hypothesis lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
# the probability that neutral hands make less than the average of bad and good hands
hypothesis(fit.brm1,
hypothesis = "Intercept + handneutral < (Intercept + Intercept + handgood) / 2")
Hypothesis Tests for class b:
Hypothesis Estimate Est.Error CI.Lower CI.Upper Evid.Ratio
1 (Intercept+handne... < 0 0.85 0.49 -Inf 1.66 0.04
Post.Prob Star
1 0.04
---
'*': The expected value under the hypothesis lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
Let’s double check one example, and calculate the result directly based on the posterior samples:
df.hypothesis = fit.brm1 %>%
posterior_samples() %>%
clean_names() %>%
select(starts_with("b_")) %>%
mutate(neutral = b_intercept + b_handneutral,
bad_good_average = (b_intercept + b_intercept + b_handgood)/2,
hypothesis = neutral < bad_good_average)
df.hypothesis %>%
summarize(p = sum(hypothesis)/n())
p
1 0.04175
<IP_ADDRESS>.1 Multiple comparisons
We can also use the hypothesis()
function to test multiple hypotheses at the same time.
h = c("Intercept + handneutral < (Intercept + Intercept + handgood) / 2", "handneutral > 4")
hyp = hypothesis(fit.brm1,
hypothesis = h,
alpha = 0.025)
hyp
plot(hyp)
Hypothesis Tests for class b:
Hypothesis Estimate Est.Error CI.Lower CI.Upper Evid.Ratio
1 (Intercept+handne... < 0 0.85 0.49 -Inf 1.82 0.04
2 (handneutral)-(4) > 0 0.38 0.59 -0.76 Inf 2.89
Post.Prob Star
1 0.04
2 0.74
---
'*': The expected value under the hypothesis lies outside the 97.5%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
Here, I’ve adjusted the alpha value which affects what credible interval is used to evaluate each hypothesis.
An alternative way of accounting for multiple comparisons within the Baysian framework is by constructing a joint posterior based on the hypotheses of interest, and looking at whether the credible interval of the joint posterior excludes 0 (Gelman and Tuerlinckx 2000).
fit.brm1 %>%
posterior_samples() %>%
clean_names() %>%
select(starts_with("b_")) %>%
mutate(hypothesis_1 = b_intercept > 2,
hypothesis_2 = b_handneutral > 3,
hypotheses_joint = hypothesis_1 * hypothesis_2
) %>%
summarize(hyp1 = sum(hypothesis_1)/n(),
hyp2 = sum(hypothesis_2)/n(),
hyp_joint = sum(hypotheses_joint)/n())
hyp1 hyp2 hyp_joint
1 1 0.9925 0.9925
<IP_ADDRESS> Bayes factor
Another way of testing hypothesis is via the Bayes factor. Let’s fit the two models we are interested in comparing with each other:
fit.brm2 = brm(formula = balance ~ 1 + hand,
data = df.poker,
save_all_pars = T,
file = "cache/brm2")
fit.brm3 = brm(formula = balance ~ 1 + hand + skill,
data = df.poker,
save_all_pars = T,
file = "cache/brm3")
And then compare the models useing the bayes_factor()
function:
bayes_factor(fit.brm3, fit.brm2)
Iteration: 1
Iteration: 2
Iteration: 3
Iteration: 4
Iteration: 1
Iteration: 2
Iteration: 3
Iteration: 4
Iteration: 5
Estimated Bayes factor in favor of bridge1 over bridge2: 3.82103
<IP_ADDRESS> Full specification
So far, we have used the defaults that brm()
comes with and not bothered about specifiying the priors, etc.
<IP_ADDRESS>.1 Getting the priors
Notice that we didn’t specify any priors in the model. By default, “brms” assigns weakly informative priors to the parameters in the model. We can see what these are by running the following command:
fit.brm1 %>%
prior_summary()
prior class coef group resp dpar nlpar bound
1 b
2 b handgood
3 b handneutral
4 student_t(3, 10, 10) Intercept
5 student_t(3, 0, 10) sigma
We can also get information about which priors need to be specified before fitting a model:
get_prior(formula = balance ~ 1 + hand,
family = "gaussian",
data = df.poker)
prior class coef group resp dpar nlpar bound
1 b
2 b handgood
3 b handneutral
4 student_t(3, 10, 10) Intercept
5 student_t(3, 0, 10) sigma
Here is an example for what a more complete model specification could look like:
fit.brm4 = brm(
formula = balance ~ 1 + hand,
family = "gaussian",
data = df.poker,
prior = c(
prior(normal(0, 10), class = "b", coef = "handgood"),
prior(normal(0, 10), class = "b", coef = "handneutral"),
prior(student_t(3, 3, 10), class = "Intercept"),
prior(student_t(3, 0, 10), class = "sigma")
),
inits = list(
list(Intercept = 0, sigma = 1, handgood = 5, handneutral = 5),
list(Intercept = -5, sigma = 3, handgood = 2, handneutral = 2),
list(Intercept = 2, sigma = 1, handgood = -1, handneutral = 1),
list(Intercept = 1, sigma = 2, handgood = 2, handneutral = -2)
),
iter = 4000,
warmup = 1000,
chains = 4,
file = "cache/brm4",
seed = 1
)
fit.brm4 %>% summary()
Family: gaussian
Links: mu = identity; sigma = identity
Formula: balance ~ 1 + hand
Data: df.poker (Number of observations: 300)
Samples: 4 chains, each with iter = 4000; warmup = 1000; thin = 1;
total post-warmup samples = 12000
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Eff.Sample Rhat
Intercept 5.96 0.41 5.15 6.76 9191 1.00
handneutral 4.37 0.58 3.23 5.53 9629 1.00
handgood 7.05 0.58 5.93 8.19 9778 1.00
Family Specific Parameters:
Estimate Est.Error l-95% CI u-95% CI Eff.Sample Rhat
sigma 4.13 0.17 3.81 4.49 12855 1.00
Samples were drawn using sampling(NUTS). For each parameter, Eff.Sample
is a crude measure of effective sample size, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
We can also take a look at the Stan code that the brm()
function creates:
fit.brm4 %>% stancode()
// generated with brms 2.7.0
functions {
}
data {
int<lower=1> N; // total number of observations
vector[N] Y; // response variable
int<lower=1> K; // number of population-level effects
matrix[N, K] X; // population-level design matrix
int prior_only; // should the likelihood be ignored?
}
transformed data {
int Kc = K - 1;
matrix[N, K - 1] Xc; // centered version of X
vector[K - 1] means_X; // column means of X before centering
for (i in 2:K) {
means_X[i - 1] = mean(X[, i]);
Xc[, i - 1] = X[, i] - means_X[i - 1];
}
}
parameters {
vector[Kc] b; // population-level effects
real temp_Intercept; // temporary intercept
real<lower=0> sigma; // residual SD
}
transformed parameters {
}
model {
vector[N] mu = temp_Intercept + Xc * b;
// priors including all constants
target += normal_lpdf(b[1] | 0, 10);
target += normal_lpdf(b[2] | 0, 10);
target += student_t_lpdf(temp_Intercept | 3, 3, 10);
target += student_t_lpdf(sigma | 3, 0, 10)
- 1 * student_t_lccdf(0 | 3, 0, 10);
// likelihood including all constants
if (!prior_only) {
target += normal_lpdf(Y | mu, sigma);
}
}
generated quantities {
// actual population-level intercept
real b_Intercept = temp_Intercept - dot_product(means_X, b);
}
One thing worth noticing: by default, “brms” centers the predictors which makes it easier to assign a default prior over the intercept.
<IP_ADDRESS> Inference diagnostics
So far, we’ve assumed that the inference has worked out. We can check this by running plot() on our brm object:
plot(fit.brm1)
Let’s make our own version of a trace plot for one parameter in the model:
fit.brm1 %>%
spread_draws(b_Intercept) %>%
clean_names() %>%
mutate(chain = as.factor(chain)) %>%
ggplot(aes(x = iteration, y = b_intercept, group = chain, color = chain)) +
geom_line()
We can also take a look at the auto-correlation plot. Ideally, we want to generate independent samples from the posterior. So we don’t want subsequent samples to be strongly correlated with each other. Let’s take a look:
variables = fit.brm1 %>% get_variables() %>% .[1:4]
fit.brm1 %>%
posterior_samples() %>%
mcmc_acf(pars = variables,
lags = 4)
Looking good! The autocorrelation should become very small as the lag increases (indicating that we are getting independent samples from the posterior).
<IP_ADDRESS>.1 When things go wrong
Let’s try to fit a model to very little data (just two observations) with extremely uninformative priors:
df.data = tibble(y = c(-1, 1))
fit.brm5 = brm(
data = df.data,
family = gaussian,
formula = y ~ 1,
prior = c(
prior(uniform(-1e10, 1e10), class = Intercept),
prior(uniform(0, 1e10), class = sigma)
),
inits = list(
list(Intercept = 0, sigma = 1),
list(Intercept = 0, sigma = 1)
),
iter = 4000,
warmup = 1000,
chains = 2,
file = "cache/brm5"
)
Let’s take a look at the posterior distributions of the model parameters:
summary(fit.brm5)
Warning: There were 225 divergent transitions after warmup. Increasing adapt_delta above 0.8 may help.
See http://mc-stan.org/misc/warnings.html#divergent-transitions-after-warmup
Family: gaussian
Links: mu = identity; sigma = identity
Formula: y ~ 1
Data: df.data (Number of observations: 2)
Samples: 2 chains, each with iter = 4000; warmup = 1000; thin = 1;
total post-warmup samples = 6000
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Eff.Sample
Intercept -51502175.28 484211604.68 -1258318917.93 524975203.26 103
Rhat
Intercept 1.04
Family Specific Parameters:
Estimate Est.Error l-95% CI u-95% CI Eff.Sample Rhat
sigma 398611802.92<PHONE_NUMBER>.49 852.93<PHONE_NUMBER>.47 13 1.07
Samples were drawn using sampling(NUTS). For each parameter, Eff.Sample
is a crude measure of effective sample size, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
Not looking good – The estimates and credible intervals are off the charts. And the effective samples sizes in the chains are very small.
Let’s visualize the trace plots:
plot(fit.brm5)
fit.brm5 %>%
spread_draws(b_Intercept) %>%
clean_names() %>%
mutate(chain = as.factor(chain)) %>%
ggplot(aes(x = iteration,
y = b_intercept,
group = chain,
color = chain)) +
geom_line()
Given that we have so little data in this case, we need to help the model a little bit by providing some slighlty more specific priors.
fit.brm6 = brm(
data = df.data,
family = gaussian,
formula = y ~ 1,
prior = c(
prior(normal(0, 10), class = Intercept), # more reasonable priors
prior(cauchy(0, 1), class = sigma)
),
iter = 4000,
warmup = 1000,
chains = 2,
seed = 1,
file = "cache/brm6"
)
Let’s take a look at the posterior distributions of the model parameters:
summary(fit.brm6)
Warning: There were 3 divergent transitions after warmup. Increasing adapt_delta above 0.8 may help.
See http://mc-stan.org/misc/warnings.html#divergent-transitions-after-warmup
Family: gaussian
Links: mu = identity; sigma = identity
Formula: y ~ 1
Data: df.data (Number of observations: 2)
Samples: 2 chains, each with iter = 4000; warmup = 1000; thin = 1;
total post-warmup samples = 6000
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Eff.Sample Rhat
Intercept -0.13 1.69 -4.10 3.06 881 1.00
Family Specific Parameters:
Estimate Est.Error l-95% CI u-95% CI Eff.Sample Rhat
sigma 2.04 1.88 0.61 6.95 1152 1.00
Samples were drawn using sampling(NUTS). For each parameter, Eff.Sample
is a crude measure of effective sample size, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
This looks much better. There is still quite a bit of uncertainty in our paremeter estimates, but it has reduced dramatically.
Let’s visualize the trace plots:
plot(fit.brm6)
fit.brm6 %>%
spread_draws(b_Intercept) %>%
clean_names() %>%
mutate(chain = as.factor(chain)) %>%
ggplot(aes(x = iteration, y = b_intercept, group = chain, color = chain)) +
geom_line()
Looking mostly good – except for one hiccup on sigma …
23.4 Dealing with heteroscedasticity
Let’s generate some fake developmental data where the variance in the data is greatest for young children, smaller for older children, and even smaller for adults:
# make example reproducible
set.seed(0)
df.variance = tibble(
group = rep(c("3yo", "5yo", "adults"), each = 20),
response = rnorm(60, mean = rep(c(0, 5, 8), each = 20), sd = rep(c(3, 1.5, 0.3), each = 20))
)
df.variance %>%
ggplot(aes(x = group, y = response)) +
geom_jitter(height = 0,
width = 0.1,
alpha = 0.7)
While frequentist models (such as a linear regression) assume equality of variance, Baysian models afford us with the flexibility of inferring both the parameter estimates of the groups (i.e. the means and differences between the means), as well as the variances.
We simply define a multivariate model which tries to fit both the response
as well as the variance sigma
:
fit.brm7 = brm(
formula = bf(response ~ group,
sigma ~ group),
data = df.variance,
file = "cache/brm7"
)
Let’s take a look at the model output:
summary(fit.brm7)
Family: gaussian
Links: mu = identity; sigma = log
Formula: response ~ group
sigma ~ group
Data: df.variance (Number of observations: 60)
Samples: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
total post-warmup samples = 4000
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Eff.Sample Rhat
Intercept 0.00 0.72 -1.38 1.45 1273 1.00
sigma_Intercept 1.15 0.17 0.85 1.51 2033 1.00
group5yo 5.16 0.77 3.60 6.62 1424 1.00
groupadults 7.96 0.72 6.49 9.37 1276 1.00
sigma_group5yo -1.05 0.23 -1.51 -0.59 2355 1.00
sigma_groupadults -2.19 0.23 -2.65 -1.74 2231 1.00
Samples were drawn using sampling(NUTS). For each parameter, Eff.Sample
is a crude measure of effective sample size, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
And let’s visualize the results:
df.variance %>%
expand(group) %>%
add_fitted_draws(fit.brm7, dpar = TRUE) %>%
select(group, .row, .draw, posterior = .value, mu, sigma) %>%
gather("index", "value", c(mu, sigma)) %>%
ggplot(aes(x = value, y = group)) +
geom_halfeyeh() +
geom_vline(xintercept = 0, linetype = "dashed") +
facet_grid(cols = vars(index))
This plot shows what the posterior looks like for both mu (the inferred means), and for sigma (the inferred variances) for the different groups.
23.5 Ordinal regression
For more information, see this tutorial.
While running an ordinal regression is far from trivial in frequentist world, it’s easy to do using “brms”.
Let’s load the cars data and turn the number of cylinders into an ordered factor:
df.cars = mtcars %>%
mutate(cyl = ordered(cyl)) # creates an ordered factor
Let’s check that the cylinders are indeed ordered now:
df.cars %>% str()
'data.frame': 32 obs. of 11 variables:
$ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
$ cyl : Ord.factor w/ 3 levels "4"<"6"<"8": 2 2 1 2 3 2 3 1 1 2 ...
$ disp: num 160 160 108 258 360 ...
$ hp : num 110 110 93 110 175 105 245 62 95 123 ...
$ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
$ wt : num 2.62 2.88 2.32 3.21 3.44 ...
$ qsec: num 16.5 17 18.6 19.4 17 ...
$ vs : num 0 0 1 1 0 1 0 1 1 1 ...
$ am : num 1 1 1 0 0 0 0 0 0 0 ...
$ gear: num 4 4 4 3 3 3 3 4 4 4 ...
$ carb: num 4 4 1 1 2 1 4 2 2 4 ...
fit.brm8 = brm(formula = cyl ~ mpg,
data = df.cars,
family = "cumulative",
file = "cache/brm8",
seed = 1)
Visualize the results:
data_plot = df.cars %>%
ggplot(aes(x = mpg, y = cyl, color = cyl)) +
geom_point() +
scale_color_brewer(palette = "Dark2", name = "cyl")
fit_plot = df.cars %>%
data_grid(mpg = seq_range(mpg, n = 101)) %>%
add_fitted_draws(fit.brm8, value = "P(cyl | mpg)", category = "cyl") %>%
ggplot(aes(x = mpg, y = `P(cyl | mpg)`, color = cyl)) +
stat_lineribbon(aes(fill = cyl),
alpha = 1/5,
.width = c(0.95)) +
scale_color_brewer(palette = "Dark2") +
scale_fill_brewer(palette = "Dark2")
plot_grid(ncol = 1, align = "v",
data_plot,
fit_plot
)
Posterior predictive check:
df.cars %>%
select(mpg) %>%
add_predicted_draws(fit.brm8, prediction = "cyl", seed = 1234) %>%
ggplot(aes(x = mpg, y = cyl)) +
geom_count(color = "gray75") +
geom_point(aes(fill = cyl),
data = df.cars,
shape = 21,
size = 2) +
scale_fill_brewer(palette = "Dark2") +
geom_label_repel(
data = . %>% ungroup() %>% filter(cyl == "8") %>% filter(mpg == max(mpg)) %>% dplyr::slice(1),
label = "posterior predictions",
xlim = c(26, NA),
ylim = c(NA, 2.8),
point.padding = 0.3,
label.size = NA,
color = "gray50",
segment.color = "gray75") +
geom_label_repel(
data = df.cars %>% filter(cyl == "6") %>% filter(mpg == max(mpg)) %>% dplyr::slice(1),
label = "observed data",
xlim = c(26, NA),
ylim = c(2.2, NA),
point.padding = 0.2,
label.size = NA,
segment.color = "gray35")
References
Gelman, Andrew, and Francis Tuerlinckx. 2000. “Type S Error Rates for Classical and Bayesian Single and Multiple Comparison Procedures.” Computational Statistics 15 (3): 373–90. https://doi.org/10.1007/s001800000040.


Description of the Vec class
The Vec class implements one-dimensional dense vectors in ScalaSci.
Constructors
Vec(len: Integer): Creates a vector of size len initialized to zeros
var v = new Vec(100) // creates a vector with 100 elements initialized to zero values.
2. Vec(da: Array[Double]): Creates a vector initialized with the da array
var da = new Array[Double](20)
da(3)=3
var dav = new Vec(da)
Construction by specifying the initial elements, e.g.
var v = V(“4.5 5.6 -4”) // space separated
var vv = V(“4, -5.6, 6.7, -100.1”) // comma separated
Basic Methods
def size: Int // Returns the size of the Vector
def length: Int // Returns the size of the Vector
var l = dav.size
Vectors are dynamically resizable while double[] arrays are not. An attempt to update a vector element outside its current range increases automatically the vector's size by a multiplicative factor, e.g. 1.5, in order to avoid frequent resizing operations (which is somehow costly).
Displaying the whole vector contents
The whole contents of the vector are printed to Console Standard Output with the print routine, e.g.
var v = vrand(40) // a random vector with 40 elements
v.print
In-Place operators
var v = vrand(100)
var vo = vones(v.length)
v++vo // adds to v the vo vector
Scalar append Vector operator ::
appends a scalar to the end of a vector, e.g.
var vo = vones(4)
var vo5 = 5 :: vo
Scalar prepend Vector operator :::
prepends a scalar to the start of a vector, e.g.
var vo = vones(4)
var vo6 = 6 ::: vo
Vector append Scalar operator ::<
appends a scalar to the end of a vector, e.g.
var vo = vones(4)
var vo5 = vo ::< 5
Vector prepend Scalar operator :::<
prepends a scalar to the start of a vector, e.g.
var vo = vones(4)
var vo6 = vo :::< 6
Vector append Vector operator :::
appends the first vector at the start of the second, e.g.
vones(2) ::: vrand(5)
Routines
1. linspace: Linearly spaced vector.
linspace(x1, x2) generates a row vector of 100 linearly equally spaced points between x1 and x2.
linspace(x1, x2, N) generates N points between x1 and x2.
var N = pow(2, 14) // signal length
var t = linspace(0, 10, N) // sample time axis
var F1=30; var F2 = 4; // signal frequencies
var x = sin(F1*t)+2.4*cos(F2*t) // construct synthetic signal
var fftx = fft(x) // perform FFT
figure(1); subplot(2,1,1); plot(x); title(“the signal”);
subplot(2,1,2); plot(fftx); title(“FFT of the signal”)
2. logspace: Logarithmically spaced vector.
logspace(x1, x2, N, base) generates a row vector of N logarithmically equally spaced points between x1 and x2.
e.g.
var x = logspace(1, 4, 100, 10)
3. dot : Vector dot product
e.g.
var t = inc(0, 0.001, 10)
var x = t dot sin(3.2*t)
plot(t,x)
4. vones(N: Int) : generates a N-sized vector of ones
5. vzeros(N: Int) : generates a N-sized vector of zeros
6. vfill(N: Int, value: Double): generates a N-sized vector filled with value
abs, min, max, sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, ceil, floor, sqrt, log, exp: the corresponding routines
sum(v: Vec): sums the element of the vector
mean(v: Vec): returns the mean value of the elements of the vector


--- layout: bare body_class: home leadingpath: ./ permalink: /experiments title: Ajey's various experiments and proof of concepts. subpage: Experiments --- Home Experiments
My code experiments with Programming, frameworks, IoT, data and AIGC programming
{% include readingtime.erb page_content=post.content %}


gear_fill
Account
Settings
How Genuine is she?
Odds of booking a date with her:
info_fill
Alerts
my_location
5
Find Dates
alarm
My Schedule
open_in_new
Post a Date
question_answer
Chat


I'm cited in this MediaPost story announcing the release of sellers.json and SupplyChain.
I'm cited in this MediaPost story announcing the release of sellers.json and SupplyChain.
I'm quoted on NBCNews.com:
“We're working on collaborating with browsers to find solutions that put consumers at the center,” Sam Tingleff, the IAB Tech Lab's chief technology officer, said. “We think there's a reasonable middle ground to do so and enable better overall user experiences.”
I mean, that's basically the same as a prime time interview with Lester Holt, right?
I find it difficult to see this GOP tax bill pass and not become incredibly pessimistic about this country's future. Deeply unpopular Congress aims to pass deeply unpopular bill for deeply unpopular president to sign says it all.
We have an extremist minority party serving a voting constituency of all of about 10 people. Whether we are descending into authoritarianism, kleptocracy, oligarchy, or whatever… clearly the situation we find ourselves in is one of taxation without representation.
One wonders if the voters who put these assholes in power - ignore Trump for the moment - are getting what they want.
And still, this tax bill on the face of it does not make a lot of sense politically. At most 30% of Americans like it. Yet some senators have been remarkably honest about whom it is intended to serve.
.@RepChrisCollins (R-NY) on tax reform: "My donors are basically saying, 'Get it done or don’t ever call me again.'"
— Cristina Marcos (@cimarcos) November 7, 2017
The only rational explanation which makes sense to me is this one.
3. THAT is what this is all about. It's an EXIT PLAN for @GOP American Oligarchs.
— Lincoln's Bible (@LincolnsBible) December 2, 2017
So, this is where I want you to put your focus. This is the message we need to send.
NOT - "We're going to vote you out, and that's your punishment..."
BUT - "We're going to vote us in... (cont.)
It's an interesting - and terrible - situation. The pessimistic case is that they are true believers of supply side economics as the one true religion of the GOP. And perhaps that's true for some members of the party.
The optimistic case is that the GOP is fucked, knows it, and will not win another legitimate election for 20 years. The tax “reform” bill is a last gasp F-U to America in an attempt to preserve their own wealth and their donor's wealth for generations.
I've been thinking about civil disobedience in the modern era.
We have a party which maintains power through a huge variety of fuckery and they're not about to give up on the obsolete or corrupt institutions like the Electoral College which keep them in power. They will do everything they can to hold on to power through dirty tricks like gerrymandering and voter disenfrachisement.
They lie through their teeth constantly through social media platforms which provide a massive, free platform to spread the message.
At the same time, their leadership spits out anti-science nonsense of all kinds: climate change denial, maths denial, science denial within the EPA, vaccine denial, forensic science denial, etc etc.
One could reasonably say that you do not get to deny science in one realm yet benefit from it in another.
If you do not believe in the reality of climate change, should you really get to benefit from the science which designed and built the iPhone? If you think that vaccines cause autism, should you really have access to mass communication platforms like twitter, which are built on decades of scientific and technological innovation? If you think encryption (math) is something which can be regulated and restricted, do you really have a right for your email to deliver over SSL?
So, what might a scientist or engineer do as an act of civil disobience towards a party of science deniers? Here's a couple of ideas.
The fact is that we (technology providers) are enabling these assholes yet are under no obligation to do so. And to be clear, I'm not arguing against free speech. But if you're anti-science, the intellectually honest thing to do would be to live with the Amish.
Revisiting last week, I remain convinced that we're better off with Trump than without him.
The bumbling fool makes his malicious intentions clear. He tells you obvious little lies all the time (“biggest Electoral College victory since Reagan”) which makes it very clear that he has no intention of ever telling you the truth. The career politician knows to avoid getting caught in a small lie in order to make the big lies more palatable.
 If you avoid the little lies you are more likely to get away with the big lies, which are complicated and tend not make for good rallies. Whoever went to a march to protest cooking the books on a budget forecast.
 And the liberal outrage dies down, and it becomes far less clear whether or not something is “fake news” or not.


List of 10 elements
Hydrogen
Helium
Berylium
Boron
Carbon
Nitrogen
Oxygen
Fluorine
Neon
Magnesium
Aluminium


Tarzan ***
rated G Walt Disney Pictures 88 minutes starring the voices of Tony Goldwyn, Minnie Driver, Glenn Close, Nigel Hawthorne, Alex D. Linz, Rosie O'Donnell, Wayne Knight based on the story "Tarzan Of The Apes" by Edgar Rice Burroughs written by Tab Murphy, Bob Tzudiker and Noni White directed by Chris Buck and Kevin Lima
Although many movie studios have taken the animation genre to unexpected heights in the past five years, the films carrying the Disney logo are still the most memorable. "Tarzan", Disney's latest, is no exception. Using the original story by Edgar Rice Burroughs, "Tarzan" breaks little new ground, but it is still an entertaining treat. "Tarzan" features Tony Goldwyn(director of "A Walk On The Moon") as the title character, and Minnie Driver as Jane, his love interest. The story is the oft-told one about the boy who is raised as a gorilla and uses his animal instincts to woo a woman who is studying the gorillas. At times, "Tarzan" is very derivative of "The Lion King", and the characters aren't nearly as well developed as those in that film. But "Tarzan" is an animated film that people of all ages should enjoy.
a capsule review by Akiva Gottlieb, The Teenage Movie Critic<EMAIL_ADDRESS>http://teenagemoviecritic.8m.com
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Elon Musk at TED Conference
Entrepreneur Elon Musk is a man with many plans. The founder of PayPal, Tesla Motors & SpaceX sits down with TED curator Chris Anderson to share details about his visionary projects, which include a mass-marketed electric car, a solar energy leasing company and a fully reusable rocket. (Source: TedTalks)


'The ducks have won': French court says they may keep on quacking
DAX, France: The ducks on a small French smallholding may carry on quacking, a French court ruled on Tuesday (Nov 19), rejecting a neighbour's complaint that the birds' racket was making their life a misery.
The court in the town of Dax ruled that the noise from the flock of around 60 ducks and geese kept by retired farmer Dominique Douthe in the foothills of the Pyrenees, southwestern France, was within acceptable limits, broadcaster France 3 said.
"The ducks have won," Douthe told Reuters after the court decision. "I'm very happy because I didn't want to slaughter my ducks."
The complaint was brought by Douthe's neighbour who moved from the city around a year ago into a property about 50m away from the enclosure in the Soustons district where Douthe keeps her flock.
READ: French ducks in the dock for quacking
The dispute is the latest in a series of court cases that have pitted the traditional way of life in rural France against modern values which, country-dwellers say, are creeping in from the city.
In a court ruling in September, a rooster named Maurice was allowed to continue his dawn crowing, despite complaints from neighbours who had also moved in from the city.
The neighbour in Soustons, about 700km south-west of Paris, who filed the complaint about the quacking has not been publicly identified.
The neighbour's lawyer said the noise exceeded permissible levels, and prevented the plaintiff enjoying their garden or sleeping with their house windows open.
The neighbour had asked for immediate steps to reduce the noise, and for 3,500 euros in damages, according to French media reports.


This document is for Next.js versions 9.3 and up. If you’re using older versions of Next.js, refer to our previous documentation.
In the Pages documentation and the Data Fetching documentation, we talked about how to pre-render a page at build time (Static Generation) using getStaticProps
and getStaticPaths
.
Static Generation is useful when your pages fetch data from a headless CMS. However, it’s not ideal when you’re writing a draft on your headless CMS and want to preview the draft immediately on your page. You’d want Next.js to render these pages at request time instead of build time and fetch the draft content instead of the published content. You’d want Next.js to bypass Static Generation only for this specific case.
Next.js has a feature called Preview Mode which solves this problem. Here are instructions on how to use it.
Take a look at the API Routes documentation first if you’re not familiar with Next.js API Routes.
First, create a preview API route. It can have any name - e.g. pages/api/preview.js
(or .ts
if using TypeScript).
In this API route, you need to call setPreviewData
on the response object. The argument for setPreviewData
should be an object, and this can be used by getStaticProps
(more on this later). For now, we’ll use {}
.
res.setPreviewData
sets some cookies on the browser which turns on the preview mode. Any requests to Next.js containing these cookies will be considered as the preview mode, and the behavior for statically generated pages will change (more on this later).
You can test this manually by creating an API route like below and accessing it from your browser manually:
// A simple example for testing it manually from your browser.
// If this is located at pages/api/preview.js, then
// open /api/preview from your browser.
export default function handler(req, res) {
res.setPreviewData({});
res.end("Preview mode enabled");
}
If you use your browser’s developer tools, you’ll notice that the __prerender_bypass
and __next_preview_data
cookies will be set on this request.
In practice, you’d want to call this API route securely from your headless CMS. The specific steps will vary depending on which headless CMS you’re using, but here are some common steps you could take.
These steps assume that the headless CMS you’re using supports setting custom preview URLs. If it doesn’t, you can still use this method to secure your preview URLs, but you’ll need to construct and access the preview URL manually.
First, you should create a secret token string using a token generator of your choice. This secret will only be known by your Next.js app and your headless CMS. This secret prevents people who don’t have access to your CMS from accessing preview URLs.
Second, if your headless CMS supports setting custom preview URLs, specify the following as the preview URL. (This assumes that your preview API route is located at pages/api/preview.js
.)
<your-site>
should be your deployment domain.<token>
should be replaced with the secret token you generated.<path>
should be the path for the page that you want to preview. If you want to preview /posts/foo
, then you should use &slug=/posts/foo
.Your headless CMS might allow you to include a variable in the preview URL so that <path>
can be set dynamically based on the CMS’s data like so: &slug=/posts/{entry.fields.slug}
Finally, in the preview API route:
slug
parameter exists (if not, the request should fail).res.setPreviewData
.slug
. (The following example uses a 307 redirect).export default async (req, res) => {
// Check the secret and next parameters
// This secret should only be known to this API route and the CMS
if (req.query.secret !== "MY_SECRET_TOKEN" || !req.query.slug) {
return res.status(401).json({ message: "Invalid token" });
}
// Fetch the headless CMS to check if the provided `slug` exists
// getPostBySlug would implement the required fetching logic to the headless CMS
const post = await getPostBySlug(req.query.slug);
// If the slug doesn't exist prevent preview mode from being enabled
if (!post) {
return res.status(401).json({ message: "Invalid slug" });
}
// Enable Preview Mode by setting the cookies
res.setPreviewData({});
// Redirect to the path from the fetched post
// We don't redirect to req.query.slug as that might lead to open redirect vulnerabilities
res.redirect(post.slug);
};
If it succeeds, then the browser will be redirected to the path you want to preview with the preview mode cookies being set.
getStaticProps
The next step is to update getStaticProps
to support the preview mode.
If you request a page which has getStaticProps
with the preview mode cookies set (via res.setPreviewData
), then getStaticProps
will be called at request time (instead of at build time).
Furthermore, it will be called with a context
object where:
context.preview
will be true
.context.previewData
will be the same as the argument used for setPreviewData
.export async function getStaticProps(context) {
// If you request this page with the preview mode cookies set:
//
// - context.preview will be true
// - context.previewData will be the same as
// the argument used for `setPreviewData`.
}
We used res.setPreviewData({})
in the preview API route, so context.previewData
will be {}
. You can use this to pass session information from the preview API route to getStaticProps
if necessary.
If you’re also using getStaticPaths
, then context.params
will also be available.
You can update getStaticProps
to fetch different data based on context.preview
and/or context.previewData
.
For example, your headless CMS might have a different API endpoint for draft posts. If so, you can use context.preview
to modify the API endpoint URL like below:
export async function getStaticProps(context) {
// If context.preview is true, append "/preview" to the API endpoint
// to request draft data instead of published data. This will vary
// based on which headless CMS you're using.
const res = await fetch(`https://.../${context.preview ? "preview" : ""}`);
// ...
}
That’s it! If you access the preview API route (with secret
and slug
) from your headless CMS or manually, you should now be able to see the preview content. And if you update your draft without publishing, you should be able to preview the draft.
# Set this as the preview URL on your headless CMS or access manually,
# and you should be able to see the preview.
https://<your-site>/api/preview?secret=<token>&slug=<path>
By default, no expiration date is set for the preview mode cookies, so the preview mode ends when the browser is closed.
To clear the preview cookies manually, you can create an API route which calls clearPreviewData
and then access this API route.
export default function handler(req, res) {
// Clears the preview mode cookies.
// This function accepts no arguments.
res.clearPreviewData();
// ...
}
setPreviewData
takes an optional second parameter which should be an options object. It accepts the following keys:
maxAge
: Specifies the number (in seconds) for the preview session to last for.previewData
size limitsYou can pass an object to setPreviewData
and have it be available in getStaticProps
. However, because the data will be stored in a cookie, there’s a size limitation. Currently, preview data is limited to 2KB.
getServerSideProps
The preview mode works on getServerSideProps
as well. It will also be available on the context
object containing preview
and previewData
.
API Routes will have access to preview
and previewData
under the request object. For example:
export default function myApiRoute(req, res) {
const isPreview = req.preview;
const previewData = req.previewData;
// ...
}
next build
Both the bypass cookie value and the private key for encrypting the previewData
change when next build
is completed. This ensures that the bypass cookie can’t be guessed.
Note: To test Preview Mode locally over HTTP your browser will need to allow third-party cookies and local storage access.
The following pages might also be useful.


Here's a link to AMP 1 on this site.
Here's a link to AMP 1 on another domain.
Here's a link to Plain 1 on this site.
Here's a link to Plain 1 on another domain.


Welcome to
DETROIT.GOV
FRIDAY, SEPTEMBER 8
CITY BUILDINGS
All city buildings are operating at normal hours.
PARKING METER
All city parking meters are currently working.
TRASH & RECYCLING
All city waste pick up services are behind due to holidays.


--- layout: page category: spec title: "WebDriver" ---
| Current Status: | Candidate Recommendation (CR) |
|---|---|
| Canonical URI: |
http://www.w3.org/TR/webdriver
|
| Abstract: | This specification defines the WebDriver API, a platform-and language-neutral interface that allows programs or scripts to introspect into, and control the behaviour of, a web browser. The WebDriver API is primarily intended to allow developers to write tests that automate a browser from a separate controlling process, but may also be implemented in such a way as to allow in-browser scripts to control a browser. The WebDriver API is defined by a set of interfaces to discover and manipulate DOM elements on a page, and to control the behaviour of the containing browser. This specification also includes a non-normative reference useful for browser vendors. |
WebDriverUpdates:


Thermostat
increase temperature
decrease temperature
Power Save Mode On
Power Save Mode Off
Power saving mode:
on
Reset temp


Example app for showing how to do authentication in Angular, with an emphasis on how to do OAuth easily.


A Little Compilation
ì í
These are just a few hints on to ask a good (technical) question. If you follow these carefully, you are much more likely to get high quality answers, so investing a little time into your question is recommended.
What would the answer to your question be?
Ask yourself how would come up with an approach to the question. You need to make sure that your question points into the right direction. Otherwise people invest time in answering something you didn't necessarily want to know. Improve the question until you can read it and think "If I knew the answer, I would exactly know what do do now".
Do you have a good title?
Try to catch the interest of broad range of people. Often it is not important which programming language you use, because the solution would look very similar in other languages. You exclude a group of people right away if you start your title with a specific attribute like "Java: ...".
Do you provide enough context information?
If you, however, would like get a very specific answer, you should provide as much additional information as possible, using hash tags, or even add some details about the platform you use in the text. Don't use the title for this.
What do you want to get out of your question?
If you want to have high quality answers to more than one question, you should sepereate the questions into different threads. Otherwise you will probably get a kind of fuzzy answer to your many questions in one thread. Though it might be easy for you to recognize the emphasis of your thread, it can be hard for others. In order to get their mind around what you are trying to ask, focus only on one question.
Do you provide an example for what went wrong, or what you want your code to to?
If possible, provide either code from what you've tried so far, or pseudocode of what you want to do. Because the characteristics of sourcecode are a lot more specific than a spoken language, it might become a lot clearer what the question is about.
Is your language reasonably correct?
Even if your not a native speaker there are some things you should avoid. For example, check for spelling mistakes. It's easy to look up words online. Also format your text in an intelligent way. Only highlight the things you want to emphasize. Make sure you're code is readable. Don't include information that is useless for solving the issue.
Good habits.
You should be registered with a meaningful username and respond quickly to answers. If someone posted an answer that points into a wrong direction, that might mean your question was not clear enough. If that's the case, edit your question and mark/add to the text what you have edited.
What would the answer to your question be?
Ask yourself how would come up with an approach to the question. You need to make sure that your question points into the right direction. Otherwise people invest time in answering something you didn't necessarily want to know. Improve the question until you can read it and think "If I knew the answer, I would exactly know what do do now".
Do you have a good title?
Try to catch the interest of broad range of people. Often it is not important which programming language you use, because the solution would look very similar in other languages. You exclude a group of people right away if you start your title with a specific attribute like "Java: ...".
Do you provide enough context information?
If you, however, would like get a very specific answer, you should provide as much additional information as possible, using hash tags, or even add some details about the platform you use in the text. Don't use the title for this.
What do you want to get out of your question?
If you want to have high quality answers to more than one question, you should sepereate the questions into different threads. Otherwise you will probably get a kind of fuzzy answer to your many questions in one thread. Though it might be easy for you to recognize the emphasis of your thread, it can be hard for others. In order to get their mind around what you are trying to ask, focus only on one question.
Do you provide an example for what went wrong, or what you want your code to to?
If possible, provide either code from what you've tried so far, or pseudocode of what you want to do. Because the characteristics of sourcecode are a lot more specific than a spoken language, it might become a lot clearer what the question is about.
Is your language reasonably correct?
Even if your not a native speaker there are some things you should avoid. For example, check for spelling mistakes. It's easy to look up words online. Also format your text in an intelligent way. Only highlight the things you want to emphasize. Make sure you're code is readable. Don't include information that is useless for solving the issue.
Good habits.
You should be registered with a meaningful username and respond quickly to answers. If someone posted an answer that points into a wrong direction, that might mean your question was not clear enough. If that's the case, edit your question and mark/add to the text what you have edited.


Welcome, Customer Name
Basically, Flexigigs is a platform designed for employers and freelance, part-time and intern service providers to meet. Employers register in order to be able to search FlexiGigs’ extensive database for the perfect candidate to perform a job for them.
It’s pretty simple. You, as a HeadHunter, can hire a service provider, a GigHunter, through one of the following methods:
Direct order: search the database and lock an order with your chosen service provider.
Post a Gig: publish an advertisement for service providers to apply for. You can then shortlist the applications and confirm the order with your chosen service provider.
This is the best part. Paying a service provider is processed through FlexiGigs. Once an order has been placed with a service provider, will make the payment in advance and in full. Money is then held in FlexiGigs’ super secure “cash vault” until the job is successfully done.
FlexiGigs offers you different payment methods for more convenience. You can either pay online using your credit cards, or through any “Fawry” outlet. No trips to the bank or awkward envelope slipping necessary. You will just be charged a premium of 10% over and above service cost in handling fees.
To avoid any scams or fraud, you have to notify FlexiGigs immediately if your service provider solicits payment from you outside the platform.Relax, Flexigigs guarantees that any personal information provided will be handled securely.
Please refer to our “Privacy Policy” for more details.
The Cash Vault feature enables you to transfer certain payment responsibilities to FlexiGigs. This is where the money you’ve paid in advance is held- nice and cozy- to be released when your service provider has completed the service successfully.
Sad but true; in certain cases a dispute may occur between you and your chosen service provider. Flexigigs can assume the role of impartial mediator in order to resolve the issue for a reasonable fee.
Please refer to our “Refund Policy” for more details.
Well, to protect your rights of course! FlexiGigs is designed to uphold and reserve the rights of both employers and service providers. To avoid scams or any type of fraud, Flexigigs will keep the money- safe and sound- on behalf of both parties, until the job is successfully performed.
To ensure that you get exactly what you pay for, FlexiGigs agrees not to pay service providers for services until after you have accepted the completed service to your satisfaction.
Great news! Registration and posting jobs are completely free. The only fee you are responsible for is a 10% handling fee when you pay an invoice.
In case of a “Dispute Case”, Dispute Resolution Service Fee is equal to EGP 25 or 5% (whichever is greater) of the total amount you’ve paid to FlexiGigs for the project in question.
Basically, Flexigigs is a platform designed for employers and freelance, part-time and intern service providers to meet. Service providers should register in order to be featured in our comprehensive database. Employers then search through it for the perfect candidate (hopefully you!) to perform a job for them.
Practically any freelance job you can think of can be found on FlexiGigs. With its wide range of categories and subcategories, our database is designed to cover all kinds of freelance jobs; some of which can be completed remotely, while others are usually performed offline.
It’s simple. After uploading your portfolio, you, as a GigHunter, can get hired by an employer, a HeadHunter, through one of the following methods:
Direct order: when an employer directly locks an order with you as a preferred service provider.
Search gigs: when you search the database of published advertisements and apply for the one which fits your profile best. Your application will be sent to the employer, after which he will shortlist the applications and confirm the order with the chosen service provider (hopefully you!).
Relax, Flexigigs guarantees that any personal information provided will be handled securely.
Please refer to our “Privacy Policy” for more details.
Great news! Registration and applying for jobs are completely free. You are only charged 10% out of the total project fee as a transaction fee. This amount will be deducted from your earnings. If you choose to be paid through bank transfer, then an additional 2% will be deducted as a bank transfer fee.
In case of a “Dispute Case”, Dispute Resolution Service Fee is equal to EGP 25 or 5% (whichever is greater) of the total amount the employer has paid to FlexiGigs for the project in question.
This is one of our best features. Once an employer has confirmed a service request with you, advanced payment for your service will be paid and held in FlexiGigs’ super secure “cash vault”. FlexiGigs will accordingly assume responsibility for the payment, directly releasing it to you as soon as the employer verifies that the service has been successfully completed. No more late payments and lost invoices!
For more details, please refer to clause II “Safe Deposit Service” under section 6 “FlexiGigs BILLING AND PAYMENT SERVICES” of Terms and Conditions.
Well, to protect your rights of course! FlexiGigs is designed to uphold and reserve the rights of both employers and service providers. To avoid scams or any type of fraud, Flexigigs will keep the money- safe and sound- on behalf of both parties, until the job is successfully performed.


My Info
First Name:
Last Name:
Phone Number:
Email Address:
Gender: Male Female
Age: Under18 18-24 25-34 35-44 45-54 55-64 65 and over
Days Available:
Any Comments?


Set price for you agent to show and sell for you.
Agency will show them to tourists.
Agency will show them to tourists.
{{item.description}}
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"


There's no control, he just let's his emotions go... Chorus C'mon! Sing with me (Sing!) Sing for the year (Sing It) Sing for the laughter sing for the tear (C'mon!) Sing it with me Just for today Maybe tomorrow The good Lord will take you away...   Any dispute won't hesitate to produce handguns That's why these prosecutors wanna convict me, strictly just to get me off of these streets quickly But all they kids be listenin' to me religiously, so I'm signin' CDs while police fingerprint me They're for the judge's daughter but his grudge is against me.  I couldn't. I wouldn't be fit to.   Well if it can, then the next time you assault a dude, just tell the judge it was my fault and I'll get sued See what these kids do is hear about us totin' pistols and they want to get one cuz they think the shit's cool not knowin' we really just protectin' ourselves, we entertainers, of course the shit's affectin' our sales, you ignoramus But music is reflection of self, we just explain it, and then we get our checks in the mail.    Just let our spirits live on, through our lyrics that you hear in our songs and we can... Chorus X2 |


User Sign Up
arrow_back
USER SIGN UP
Please fill in the details to sign up.
Enter your name
Enter the username
Enter the password
Enter the email
Choose a profile picture
Subscribe to updates
Sign Up


Basic Example
Dynamic Example
isDisabled: {{isDisabled}} Disable buttons
Align end
Dynamic Example with two-way data-binding
Your favorite season is: {{favoriteSeason}}


| Values' Details |
| LEFT_TO_RIGHT
|
| RIGHT_TO_LEFT
|
| EUROPEAN_NUMBER
|
EUROPEAN_NUMBER_SEPARATOR
EUROPEAN_NUMBER_SEPARATOR = 3,
|
|
EUROPEAN_NUMBER_TERMINATOR
EUROPEAN_NUMBER_TERMINATOR = 4,
|
|
| ARABIC_NUMBER
|
COMMON_NUMBER_SEPARATOR
COMMON_NUMBER_SEPARATOR = 6,
|
|
| BLOCK_SEPARATOR
|
| SEGMENT_SEPARATOR
|
| WHITE_SPACE_NEUTRAL
|
| OTHER_NEUTRAL
|
LEFT_TO_RIGHT_EMBEDDING
LEFT_TO_RIGHT_EMBEDDING = 11,
|
|
LEFT_TO_RIGHT_OVERRIDE
LEFT_TO_RIGHT_OVERRIDE = 12,
|
|
RIGHT_TO_LEFT_ARABIC
RIGHT_TO_LEFT_ARABIC = 13,
|
|
RIGHT_TO_LEFT_EMBEDDING
RIGHT_TO_LEFT_EMBEDDING = 14,
|
|
RIGHT_TO_LEFT_OVERRIDE
RIGHT_TO_LEFT_OVERRIDE = 15,
|
|
POP_DIRECTIONAL_FORMAT
POP_DIRECTIONAL_FORMAT = 16,
|
|
DIR_NON_SPACING_MARK
DIR_NON_SPACING_MARK = 17,
|
|
| BOUNDARY_NEUTRAL
|
Copyright © 2013, The Apache Software Foundation, Licensed under the Apache License, Version 2.0. Apache, the Apache feather logo, Apache OpenOffice and OpenOffice.org are trademarks of The Apache Software Foundation. Other names may be trademarks of their respective owners.


Isar735.github.io
So you want to write sci-fi, eh? Some claim that creative writing cannot be taught, but it can certainly be learned. And a good guide, be it a teacher. Las Vegas Creative Writing Class (Las Vegas, NV) Meetup. RT @HILOBROW: GOLDEN AGE SCI-FI: 75 BEST NOVELS OF 1934–1963. Here they are! My Top 75 faves. Let the arguments begin. co/03BzyQcI…. 20 Creative Writing Careers Writing Forward. 25 Best Sci-Fi Movies Of the 21st Century, From Children. Have you ever bothered to look at the creative writing careers that are available? Browse these job possibilities, and then go out there and make it happen.
Image by Alan Light released under Creative Commons license. When he passed away in 2012, science fiction master Ray Bradbury left us with a number.
A Sci-Fi Magazine Created Entirely By Writers And Editors.
It s time for. drum roll sci-fi story 20 Sci-Fi Story A highschooler from fifteen hundred years in our future is assigned a one-page writing project. Afrofuturism: The World of Black Sci-Fi and Fantasy. The List: 58 Science Fiction Writing Prompts. You find out you’re a DNA experiment combining as many recessive genes into one person as possible. Are you a fan of speculative fiction or mysterious poetry? Want to give it a try? Here are some creative writing prompts to kick-start your imagination. Sci fi fantasy creative writing prompts - Proofreading and proofediting aid from top professionals. Use this platform to get your profound paper delivered Story Starters: Creative Writing Prompts Use these creative writing prompts to get your story or character started. Scholastic's Story Starters kids' writing activity generates creative writing prompts, from general fiction to adventure, fantasy, and science fiction.
Ever feel stumped? Uninspired? Blank? These creative writing prompts will kick your muse into high gear so you can start writing again. Be creative. Fall 2018 - Saturday, October 20, 11:30 am-12:30 pm. This class has reached full capacity.
The History of Science Fiction” – there is a saying in the martial arts to describe the proper mind frame needed to become sci fi creative writing master. 30 Sci Fi Writing Prompts - Justin McLachlan. Home / Fiction Writing / The Ultimate Guide To World-Building: How To Write Fantasy, Sci-Fi And Real-Life Worlds. Who doesn’t love a great writing prompt? Here are 34 more scifi and fantasy writing prompts, licensed, as usual, under Creative Commons and culled. Historically, science fiction has been good at opening up space for creatives to imagine possible futures. By speculating about tomorrow, writers, artists.
Hear Ray Bradbury's Beloved Sci-Fi Stories as Classic. Amazon.com: Crossing In Time: An Edgy Sci-Fi Love Story. Random sci-fi story idea generator We created this random story idea generator to provide inspiration to science fiction writers.
These creative writing prompts will help you uncover the book ideas you’ve been Here are some sci-fi writing prompts to help you do that. Crossing In Time: An Edgy Sci-Fi Love Story (Between Two Evils Book 1) - Kindle edition by D. L. Orton. Download it once and read it on your Kindle device, PC, phones. 100 Best Sci-Fi Movies - Time Out London. 20 Sci-fi Story Ideas - The Write Practice. Sci fi creative writing - IearnDaily.com.
With themes that range from love to fear to humanity itself, the best sci-fi movies of the 21st century share distinctly original visions. Free audio books, free audiobooks, free education, free learning, free online courses, free courses, free lectures, education, knowledge, free movies online The Ultimate Guide to Worldbuilding – Writer’s. Science fiction (often shortened to Sci-Fi or SF) is a genre of speculative fiction, typically dealing with imaginative concepts such as advanced science. GOLDEN AGE SCI-FI: 1934–1963 – HILOBROW. Sci-Fi Lullabies is a two-disc compilation album by English alternative rock band Suede, consisting of B-sides from the singles that were released from the group's. 200+ Creative Writing Prompts: 100% Unique Fiction Book Ideas. The science of writing SF Books The Guardian. Register now for Sci-Fi Fantasy Writing - Salesforce.com. 34 More Scifi and Fantasy Writing Prompts - Justin McLachlan.
A few sci fi writing prompts to spark your imagination and help kick start a short story or NaNoWriMo novel. Free online creative writing course, covering releasing your creativity, how to write a short story, writing from a point of view, bringing your writing From 'Star Wars' to '2001: A Space Odyssey', science fiction films know no bounds. Here are 100 of the best Sci-fi movies
Sci-Fi Story Idea Generator - SciFi Ideas. 25 Creative Writing Prompts Writing Forward. Creative Writing Prompts for Sci-Fi Fantasy Lovers.
Sci fi fantasy creative writing prompts - Naimakka. Sci Fi Archives Open Culture archive Open Culture. Afrofuturism: The World of Black Sci-Fi and Fantasy Culture Ytasha L. Womack on Amazon.com. FREE shipping on qualifying offers. 2014 Locus Awards Finalist.
Hi. I am Maxwell Alexander Drake and I am an award-winning Sci-Fi/Fantasy author. Join me at the Centennial Hills Library for my free writing classes hosted 58 Science Fiction Writing Prompts Mandy Wallace.


Easy-to-use online transcription tool for research purposes. This is not doing anything automatically. Developed and maintained by Datenfrühstück (imprint). Access granted upon personal request.
Hold on,
I am loading and setting things up and getting stuff done and ...
Caution After this step I need a little while to set things up (and to load your audio). Probably up to 30 seconds, depending on your internet connection. Please be patient until I'll tell you that everything is set up.


module PhConfig: sig
.. end
This module is useful to configure a brick.
Configuration
This module is useful to configure a brick. Put in a dico file all variables in config/<brick>/main.dico
(or if you want to package the brick in bricks_src/<brick>/config_model/main.dico
) and you will be able to load it here. Please don't forget to also edit the file config/<brick>/modules.xml
to apply any modification, and bricks_src/<brick>/package/replacement.qdico
if you want to ask some questions to the user when you install the brick.
Get the dictionary
exception Config_item_not_found of string
Error raised when you ask for an item not present in the config file. (usually you forgot to report in the config/<brick>/modules.xml
file.)
type
dico = (string * string) list
Main type. A dico is a set of couple (key,value) loaded from the xml configuration file. (inserted in www/run_server.conf
)
val get_dico : unit -> dico
This function load a dico from the
Get the configuration
val get_value : dico -> string -> string
get_value dico key
get in the dico the key key
.
Raises Config_item_not_found
key
if the key isn't in the dico.
val get_value_opt : dico -> string -> string option
Same as get
but return None
if the value is empty or not present
val get_value_list : dico -> ?sep:string -> string -> string list
get_value_list dico ~sep key
will return a list of item that are separeted by sep
(by default, sep = '/'
). It is useful to get a prefix url for example.
Raises Config_item_not_found
if the key isn't in the dico.
val get_value_list_opt : dico -> ?sep:string -> string -> string list option
val get_bool : dico -> string -> bool
Same as get_value, but return true
if the value is in the set (the case isn't important), and false
else.
Raises Config_item_not_found
if the key isn't in the dico.
val print_config : string -> int -> unit
print_config brick_name brick_verb
will print all elements in the brick_dico in a pretty way.
Advanced functions
val get_xml : unit -> Simplexmlparser.xml list
Get the xml associated with the brick
val dico_from_xml : Simplexmlparser.xml list -> dico


wedding.finley.sh
Join us on Saturday, October 10th at 10:20 AM PT (1:20 ET) as we live stream our wedding.
More information is available on our
website
Add to Calender


Premier League confirm dates and times for January transfer window
The window will open on Wednesday 1 January and close at 23:00 (UK time) on Friday 31 January 2020
by Matt Maltby, https://www.mirror.co.uk/authors/matt-maltby/The Premier League has confirmed the dates and times for the January transfer window, when top-flight teams will be able to strengthen their ranks.
The window will open on Wednesday 1 January and close at 23:00 (UK time) on Friday 31 January 2020.
It has also been confirmed that top-flight clubs will be given an extension to finalise their 25-man squad for the second half of the campaign.
Normally clubs need to register their final squad for the rest of the campaign the day after the transfer window closes, but because Deadline Day is the day before a round of fixtures, the deadline for submission of final squad lists will be on Wednesday 5 February 2020.
The Premier League said: "New players signed on 1-2 January will not be eligible for Matchweek 21, but they can be made available for the following Matchweeks as clubs are permitted to make changes to their squad lists throughout the January window.
"Clubs completing deals late on Deadline Day, 31 January, will be able to submit a Deal Sheet between 21:00-23:00 GMT.
"Clubs will have until midnight on Deadline Day to complete the information needed by FIFA's Transfer Matching System to apply for international clearance for new signings."
With almost a third of the season completed, the Premier League is starting to take shape.
And it is Liverpool who are on track for a title triumph, with manager Jurgen Klopp enjoying a stunning start to the season.
The Liverpool manager is the man with the Midas touch at the moment.
Revered on Merseyside by the Reds faithful, Klopp's stock rose further still with last Sunday's 3-1 win over Manchester City at Anfield, opening up an eight-point gap over nearest challengers Leicester, and a nine-point cushion to Pep Guardiola's side.
The 52-year-old German has so far masterminded a near-perfect league campaign, with 11 wins and a draw from 12 matches.
Under Klopp, this could well be the year Liverpool finally end their 30-year wait to land the league title.