library(ggplot2)
library(tibble)
library(tidyr)
source("./code/theme_gar.txt")
source("./code/Rallfun-v35-simplified.txt")
library(beepr) # for little auditory rewards :)
We compute multiple bootstrap sampling distributions for the same sample.
set.seed(1)
n <- 30 # sample size
nsim <- 50 # number of bootstrap distributions
nboot <- 100 # number of bootstrap samples
tr <- 0.2 # amount of trimming
samp <- rlnorm(n) # unique sample from lognormal distribution
boot.samp.dist <- matrix(0, nrow = nsim, ncol = nboot)
boot.q975 <- vector(mode = "numeric", length = nsim)
for(iter in 1:nsim){ # get bootstrap samples multiple times
boot.samp.dist[iter,] <- apply(matrix(sample(samp, n*nboot, replace = TRUE), nrow = nboot), 1, mean, trim = tr)
boot.q975[iter] <- quantile(boot.samp.dist[iter,], probs = 0.975) # get upper bound of confidence interval
}
# boot.samp.dist[iter,] = nsim (50) bootstrap sampling distributions
# boot.q975[iter] = nsim (50) upper bounds of the percentile bootstrap confidence intervals. These upper bounds are shown as black vertical lines in the next chunk `Superimpose 0.975 quantile`.
p <- ggplot(tibble(x = as.vector(boot.samp.dist),
samp = factor(rep(1:nsim, nboot))),
aes(x = x)) + theme_gar +
# bootstrap distributions from nsim samples
geom_line(aes(group = samp, colour = "bootstrap samples"), stat = "density", size = 0.5) +
coord_cartesian(xlim = c(0.5, 3)) +
scale_x_continuous(breaks = seq(0.5, 3, 0.5)) +
theme(legend.position = "none") +
labs(x = "20% trimmed means", y = "Density") +
guides(colour = guide_legend(override.aes = list(size = 3))) +
ggtitle("Bootstrap sampling distributions: nboot = 100")
p
df.q <- tibble(q = boot.q975)
ggplot(tibble(x = as.vector(boot.samp.dist),
samp = factor(rep(1:nsim, nboot))),
aes(x = x)) + theme_gar +
# bootstrap distributions from nsim samples
geom_line(aes(group = samp, colour = "bootstrap samples"), stat = "density", size = 0.5) +
geom_vline(data = df.q, mapping=aes(xintercept = q)) +
coord_cartesian(xlim = c(1.5, 2.5)) +
scale_x_continuous(breaks = seq(0.5, 3, 0.5)) +
theme(legend.position = "none") +
labs(x = "20% trimmed means", y = "Density") +
guides(colour = guide_legend(override.aes = list(size = 3))) +
ggtitle("Bootstrap sampling distributions: nboot = 100")
set.seed(1)
n <- 30 # sample size
nsim <- 50 # number of bootstrap distributions
nboot <- 1000 # number of bootstrap samples
tr <- 0.2 # amount of trimming
samp <- rlnorm(n) # unique sample from lognormal distribution
boot.samp.dist <- matrix(0, nrow = nsim, ncol = nboot)
boot.q975 <- vector(mode = "numeric", length = nsim)
for(iter in 1:nsim){ # get bootstrap samples multiple times
boot.samp.dist[iter,] <- apply(matrix(sample(samp, n*nboot, replace = TRUE), nrow = nboot), 1, mean, trim = tr)
boot.q975[iter] <- quantile(boot.samp.dist[iter,], probs = 0.975) # get upper bound of confidence interval
}
# boot.samp.dist[iter,] = nsim (50) bootstrap sampling distributions
# boot.q975[iter] = nsim (50) upper bounds of the percentile bootstrap confidence intervals. These upper bounds are shown as black vertical lines in the next chunk `Superimpose 0.975 quantile`.
p <- ggplot(tibble(x = as.vector(boot.samp.dist),
samp = factor(rep(1:nsim, nboot))),
aes(x = x)) + theme_gar +
# bootstrap distributions from nsim samples
geom_line(aes(group = samp, colour = "bootstrap samples"), stat = "density", size = 0.5) +
coord_cartesian(xlim = c(0.5, 3)) +
scale_x_continuous(breaks = seq(0.5, 3, 0.5)) +
theme(legend.position = "none") +
labs(x = "20% trimmed means", y = "Density") +
guides(colour = guide_legend(override.aes = list(size = 3))) +
ggtitle("Bootstrap sampling distributions: nboot = 1000")
p
df.q <- tibble(q = boot.q975)
ggplot(tibble(x = as.vector(boot.samp.dist),
samp = factor(rep(1:nsim, nboot))),
aes(x = x)) + theme_gar +
# bootstrap distributions from nsim samples
geom_line(aes(group = samp, colour = "bootstrap samples"), stat = "density", size = 0.5) +
geom_vline(data = df.q, mapping=aes(xintercept = q)) +
coord_cartesian(xlim = c(1.5, 2.5)) +
scale_x_continuous(breaks = seq(0.5, 3, 0.5)) +
theme(legend.position = "none") +
labs(x = "20% trimmed means", y = "Density") +
guides(colour = guide_legend(override.aes = list(size = 3))) +
ggtitle("Bootstrap sampling distributions: nboot = 1000")
set.seed(1)
n <- 30 # sample size
nsim <- 50 # number of bootstrap distributions
nboot <- 10000 # number of bootstrap samples
tr <- 0.2 # amount of trimming
samp <- rlnorm(n) # unique sample from lognormal distribution
boot.samp.dist <- matrix(0, nrow = nsim, ncol = nboot)
boot.q975 <- vector(mode = "numeric", length = nsim)
for(iter in 1:nsim){ # get bootstrap samples multiple times
boot.samp.dist[iter,] <- apply(matrix(sample(samp, n*nboot, replace = TRUE), nrow = nboot), 1, mean, trim = tr)
boot.q975[iter] <- quantile(boot.samp.dist[iter,], probs = 0.975) # get upper bound of confidence interval
}
# boot.samp.dist[iter,] = nsim (50) bootstrap sampling distributions
# boot.q975[iter] = nsim (50) upper bounds of the percentile bootstrap confidence intervals. These upper bounds are shown as black vertical lines in the next chunk `Superimpose 0.975 quantile`.
p <- ggplot(tibble(x = as.vector(boot.samp.dist),
samp = factor(rep(1:nsim, nboot))),
aes(x = x)) + theme_gar +
# bootstrap distributions from nsim samples
geom_line(aes(group = samp, colour = "bootstrap samples"), stat = "density", size = 0.5) +
coord_cartesian(xlim = c(0.5, 3)) +
scale_x_continuous(breaks = seq(0.5, 3, 0.5)) +
theme(legend.position = "none") +
labs(x = "20% trimmed means", y = "Density") +
guides(colour = guide_legend(override.aes = list(size = 3))) +
ggtitle("Bootstrap sampling distributions: nboot = 10000")
p
df.q <- tibble(q = boot.q975)
ggplot(tibble(x = as.vector(boot.samp.dist),
samp = factor(rep(1:nsim, nboot))),
aes(x = x)) + theme_gar +
# bootstrap distributions from nsim samples
geom_line(aes(group = samp, colour = "bootstrap samples"), stat = "density", size = 0.5) +
geom_vline(data = df.q, mapping=aes(xintercept = q)) +
coord_cartesian(xlim = c(1.5, 2.5)) +
scale_x_continuous(breaks = seq(0.5, 3, 0.5)) +
theme(legend.position = "none") +
labs(x = "20% trimmed means", y = "Density") +
guides(colour = guide_legend(override.aes = list(size = 3))) +
ggtitle("Bootstrap sampling distributions: nboot = 1000")
Example of a simple simulation to check the probability coverage of a confidence interval method. The simulation has 2,000 iterations. Increasing this number would lead to more precise results. For a simple test, 10,000 iterations or more could be used (and is often recommended or expected in the literature). For more complex applications, time might be a constraint.
The sample size is 30, which seems reasonably high for a psychology experiment. A more systematic simulation should include sample size as a parameter.
The population is lognormal and is generated outside the simulation loop. An alternative is to generate the random numbers directly inside the loop by using samp <- rlnorm(nsamp)
. The lognormal distribution is one of many skewed mathematical distributions. It serves to illustrate what can happen when sampling from skewed distributions in general. Other shapes could be used to, if some domain specific information is available. For instance, ex-Gaussian distributions do a good job at capturing the shape of reaction time distributions.
The population means and trimmed means differ and are estimated independently in the simulation: the sample mean is used to make inferences about the population mean, whereas the sample trimmed mean is used to make inferences about the population trimmed mean.
DO NOT RUN THE NEXT CHUNK UNLESS YOU’RE PLANNING A BREAK!
set.seed(666) # reproducible results
nsim <- 2000 # simulation iterations
nsamp <- 30 # sample size
nboot <- 500 # could use more
pop <- rlnorm(1000000) # define population
pop.m <- mean(pop) # population mean
pop.tm <- mean(pop, trim = 0.2) # population 20% trimmed mean
ci.coverage <- matrix(0, nrow = nsim, ncol = 3) # declare matrix of results
for(S in 1:nsim){ # simulation loop
if(S == 1){
print(paste("iteration",S,"/",nsim))
beep(2)
}
if(S %% 500 == 0){
print(paste("iteration",S,"/",nsim))
beep(2)
}
samp <- sample(pop, nsamp, replace = TRUE) # random sample from population
# Mean + t-test
ci <- t.test(samp, mu = pop.m)$conf.int # standard t-test equation
ci.coverage[S,1] <- ci[1]<pop.m && ci[2]>pop.m # CI includes population value?
# Mean + bootstrap-t
ci <- trimcibt(samp,tr=0,alpha=.05,nboot=nboot,side=FALSE)$ci # get bootstrap confidence interval
ci.coverage[S,2] <- ci[1]<pop.m && ci[2]>pop.m # CI includes population value?
# 20% trimmed mean + percentile bootstrap
ci <- onesampb(samp, est = mean, nboot=nboot, trim = 0.2)$ci # get bootstrap confidence interval
ci.coverage[S,3] <- ci[1]<pop.tm && ci[2]>pop.tm # CI includes population value?
}
apply(ci.coverage, 2, mean) # average across simulations for each method
# save simulation results to load in next chunk
save(ci.coverage, file = "./data/ci.coverage.RData")
beep(8)
Here are the results:
load("./data/ci.coverage.RData")
out <- apply(ci.coverage, 2, mean) # average across simulations
Coverage is 88.2% for the t-test, 92.9% for the bootstrap-t + mean, and 94.2% for the percentile bootstrap + 20% trimmed mean. This means that when sampling from a skewed distribution such as the lognormal distribution, coverage can be very different from the expected one (here 95% coverage).
We start with a standard power analysis. We’re going to look at the power of the one-sample t-test using the mean, as a function of both sample size and effect size.
# Define parameters
nsim <- 5000 # number of simulation iterations
nvec <- seq(10,500,10) # vector of sample sizes to test
esvec <- seq(0,1,0.1) # vector of effect sizes
Do not run with 5000 iterations unless you’re planning a long coffee break.
set.seed(44) # set number generator for reproducible results
simres <- array(0, dim = c(length(esvec), length(nvec))) # define matrix holding the results
for(S in 1:nsim){ # simulation loop
if(S == 1){
print(paste("iteration",S,"/",nsim))
beep(2)
}
if(S %% 500 == 0){
print(paste("iteration",S,"/",nsim))
beep(2)
}
for(N in 1:length(nvec)){ # sample sizes
x <- rnorm(nvec[N]) # draw one sample from normal distribution
for(E in 1:length(esvec)){ # effect sizes
# one-sample t-test on sample from normal distribution with a variable shift in location:
pm = trimci(x + esvec[E], pr=F, tr=0)$p.value
if(pm<=.05) simres[E,N] <- simres[E,N] + 1 # number of type I errors
}
}
}
power.res <- simres / nsim
save(power.res, file = "./data/power_res_m.RData")
beep(8)
We get the type I error rate and power for each combination of effect sizes and sample sizes.
load("./data/power_res_m.RData")
# create data frame
df <- tibble(x = nvec,
y = power.res[1,])
# make plot
p <- ggplot(df, aes(x, y)) + theme_bw() +
geom_ribbon(ymin = 0.025, ymax = 0.075, fill = "grey90") + # Bradley's (1978) satisfactory range
geom_abline(intercept = 0.05, slope = 0) + # 0.05 reference line
geom_line(size=1) +
theme(axis.title.x = element_text(size = 18),
axis.text = element_text(size = 16),
axis.title.y = element_text(size = 18)) +
scale_y_continuous(limits = c(0,0.16),
breaks = seq(0, 0.15, 0.025)) +
labs(x = "Sample size", y = "False positive probability")
p
# create data frame
fm <- array(0, dim = c(length(nvec), length(esvec))) # make full matrix
fm[,1] <- nvec
fm[,2:length(esvec)] <- t(power.res[2:length(esvec),])
colnames(fm) <- c("SS", "0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "1.0")
df <- as_tibble(fm)
df <- tidyr::gather(df,ES,TP,2:length(esvec))
df[[2]] <- as.factor(df[[2]])
# make plot
p <- ggplot(df, aes(SS, TP, group = ES)) + theme_bw() +
geom_abline(intercept = 0.80, slope = 0, size = 0.5) + # 0.80 reference line
geom_abline(intercept = 0.90, slope = 0, size = 0.5) + # 0.90 reference line
geom_line(aes(colour = ES), size=0.5) + # plot results
scale_colour_viridis_d() + # change to perceptually uniform colourmap
theme(axis.title.x = element_text(size = 18),
axis.text = element_text(size = 16),
axis.title.y = element_text(size = 18),
legend.title=element_text(size=14),
legend.text=element_text(size=12)) +
scale_y_continuous(limits = c(0,1),
breaks = seq(0, 1, 0.2)) +
scale_x_continuous(limits = c(0, 500),
breaks = seq(0, 500, 50)) +
labs(x = "Sample size", y = "True positive probability") +
guides(colour = guide_legend(override.aes = list(size=3)))
p
We draw samples of n = 30 observations from a lognormal distribution with a mean of 0.5 or a 20% trimmed mean of 0.5. If you want to run your own power analysis, you need to consider all these choices: the shape of the distribution to sample from, the sample size, the effect size, the statistical tests. With the current selection of paramaters, we simply wanted to illustrate that when sampling from a skewed distribution with a relatively large sample size in psychology and neuroscience, the choice of statistical test can have large effects on power. In particular, a t-test on the mean can have very low power, whereas a t-test on a trimmed mean, or a test on the median can provide much larger power.
set.seed(44) # set number generator for reproducible results
nsim <- 5000 # number of simulation iterations
n <- 30 # sample size
es <- 0.5 # specify effect size
tr <- 0.2 # amount of trimming
npm <- 0 # number of positive results for the mean
nptm <- 0 # number of positive results for the trimmed mean
npmd <- 0 # number of positive results for the median
# create lognormal population
pop <- rlnorm(1000000)
pop.m <- pop - mean(pop) + es # set mean to `es`
pop.tm <- pop - mean(pop, trim = tr) + es # set 20% trimmed mean to `es`
pop.md <- pop - median(pop) + es # set median to `es`
for(S in 1:nsim){ # simulation loop
pm <- trimci(sample(pop.m, n, replace = TRUE), pr=F, tr=0)$p.value # t-test on mean
ptm <- trimci(sample(pop.tm, n, replace = TRUE), pr=F, tr=tr)$p.value # t-test on 20% trimmed mean
pmd <- sintv2(sample(pop.md, n, replace = TRUE), pr=FALSE)$p.value # parametric test on median
if(pm<=.05) npm <- npm + 1 # mean
if(ptm<=.05) nptm <- nptm + 1 # 20% trimmed mean
if(pmd<=.05) npmd <- npmd + 1 # median
}
print(c(npm/nsim,nptm/nsim,npmd/nsim))
## [1] 0.1564 0.6526 0.8506
The results show power of 15.6% for the mean, 65.3 for 20% trimmed mean, and 85.1 for the median.
This new simulation is an extension of the previous one and includes: - multiple sample sizes; - sampling from normal and lognormal distributions; - t-tests using means and 20% trimmed means; - parametric test on the median; - different effect sizes. We include an effect size of zero, to assess the type I error rate, or false positives, of the tests.
# Define parameters
nsim <- 5000 # number of simulations
nvec <- seq(10,300,10) # vector of sample sizes to test
max.size <- max(nvec)
esvec <- c(0, 0.5) # vector of effect sizes
tr <- 0.2 # amount of trimming
To run the chunk below when knitting the notebook, you need to change {r, eval = FALSE}
to {r, eval = TRUE}
. You could run a faster simulation by changing nsim
to 1000 in the previous chunk for instance.
Do not run with 5000 iterations unless you’re planning a long coffee break.
set.seed(45) # set random number generator for reproducibility
# 6 conditions = 2 (normal / skewed) x 3 (mean / trimmed mean / median)
simres <- array(0, dim = c(6, length(esvec), length(nvec), nsim))
pop.norm <- rnorm(1000000)
pop.lnorm <- rlnorm(1000000)
pop.lnorm.m <- mean(pop.lnorm)
pop.lnorm.tm <- mean(pop.lnorm, trim = tr)
pop.lnorm.md <- median(pop.lnorm)
for(S in 1:nsim){ # simulation iterations
large.norm.sample <- sample(pop.norm, max.size, replace = TRUE)
large.lnorm.sample <- sample(pop.lnorm, max.size, replace = TRUE)
for(N in 1:length(nvec)){ # sample sizes
for(E in 1:length(esvec)){ # effect sizes
# sub-sample + shift by effect size
norm.sample <- large.norm.sample[1:nvec[N]] + esvec[E]
lnorm.sample <- large.lnorm.sample[1:nvec[N]] + esvec[E]
# normal: t-test on mean
simres[1,E,N,S] <- trimci(norm.sample, tr=0, pr=FALSE)$p.value
# normal: t-test on 20% trimmed mean
simres[2,E,N,S] <- trimci(norm.sample, tr=0.2, pr=FALSE)$p.value
# normal: median test
simres[3,E,N,S] <- sintv2(norm.sample, pr=FALSE)$p.value
# lognormal: t-test on mean - subtract population mean so the mean is zero + ES on average
simres[4,E,N,S] <- trimci(lnorm.sample - pop.lnorm.m, tr=0, pr=FALSE)$p.value
# lognormal: t-test on 20% trimmed mean - subtract population trimmed mean so the trimmed mean is zero + ES on average
simres[5,E,N,S] <- trimci(lnorm.sample - pop.lnorm.tm, tr=tr, pr=FALSE)$p.value
# lognormal: median test - subtract population median so the median is zero + ES on average
simres[6,E,N,S] <- sintv2(lnorm.sample - pop.lnorm.md, pr=FALSE)$p.value
}
}
}
power.res <- apply(simres <= 0.05, c(1,2,3), mean)
save(power.res, file = "./data/power_res_onesample.RData")
beep(8)
We get the type I error rate and power for each combination of tests, sample sizes and effect sizes.
load("./data/power_res_onesample.RData")
E <- 1 # effect size 0, no effect
# create data frame
y <- c(power.res[1,E,],power.res[2,E,],power.res[3,E,],
power.res[4,E,],power.res[5,E,],power.res[6,E,])
Distribution <- c(rep('Normal',length(nvec)*3), rep('Lognormal',length(nvec)*3))
Estimator <- c(rep('Mean',length(nvec)), rep('Trimmed mean',length(nvec)), rep('Median',length(nvec)),
rep('Mean',length(nvec)), rep('Trimmed mean',length(nvec)), rep('Median',length(nvec)))
df <- tibble(x = rep(nvec, 6), # sample size
y = y, # `Type I error probability
as.factor(Distribution),
as.factor(Estimator))
# make plot
p <- ggplot(df, aes(x, y)) + theme_bw() +
geom_ribbon(ymin = 0.025, ymax = 0.075, fill = "grey90") + # Bradley's (1978) satisfactory range
geom_abline(intercept = 0.05, slope = 0) + # 0.05 reference line
geom_line(aes(linetype=Distribution, colour=Estimator), size=0.5) +
scale_colour_manual(values = c("#56B4E9", "#D55E00", "#009E73")) +
theme(axis.title.x = element_text(size = 18),
axis.text = element_text(size = 16),
axis.title.y = element_text(size = 18),
legend.title=element_text(size=14),
legend.text=element_text(size=12)) +
scale_y_continuous(limits = c(0,0.18),
breaks = seq(0, 0.18, 0.025)) +
scale_x_continuous(limits = c(0, 300),
breaks = seq(0, 300, 50)) +
labs(x = "Sample size", y = "Type I error probability") +
guides(colour = guide_legend(override.aes = list(size=3)))
p
E <- 2 # effect size = +0.5 shift in location
# create data frame
y <- c(power.res[1,E,],power.res[2,E,],power.res[3,E,],
power.res[4,E,],power.res[5,E,],power.res[6,E,])
Distribution <- c(rep('Normal',length(nvec)*3), rep('Lognormal',length(nvec)*3))
Estimator <- c(rep('Mean',length(nvec)), rep('Trimmed mean',length(nvec)), rep('Median',length(nvec)),
rep('Mean',length(nvec)), rep('Trimmed mean',length(nvec)), rep('Median',length(nvec)))
df <- tibble(x = rep(nvec, 6), # sample size
y = y, # `Type I error probability
as.factor(Distribution),
as.factor(Estimator))
# make plot
p <- ggplot(df, aes(x, y)) + theme_bw() +
geom_abline(intercept = 0.80, slope = 0) + # 0.80 reference line
geom_abline(intercept = 0.90, slope = 0) + # 0.90 reference line
geom_line(aes(linetype=Distribution, colour=Estimator), size=0.5) +
scale_colour_manual(values = c("#56B4E9", "#D55E00", "#009E73")) +
theme(axis.title.x = element_text(size = 18),
axis.text = element_text(size = 16),
axis.title.y = element_text(size = 18),
legend.title=element_text(size=14),
legend.text=element_text(size=12)) +
scale_y_continuous(limits = c(0,1),
breaks = seq(0, 1, 0.1)) +
scale_x_continuous(limits = c(0, 300),
breaks = seq(0, 300, 50)) +
labs(x = "Sample size", y = "Power (true positive probability)") +
guides(colour = guide_legend(override.aes = list(size=3)))
p
# Define parameters
nsim <- 5000 # number of simulation iterations
nvec <- seq(10,300,10) # vector of sample sizes to test
nmax <- max(nvec) # maximum sample size
es <- 0.5 # effect size
tr <- 0 # zero trimming = t-test on means
Do not run with 5000 iterations unless you’re planning a coffee break.
set.seed(44) # set number generator for reproducible results
simres <- array(0, dim = c(3, length(nvec))) # define matrix holding the results
# create normal populations with desired means
pop1.norm <- rnorm(1000000)
pop2.norm <- rnorm(1000000)
pop1.norm <- pop1.norm - mean(pop1.norm) + es # mean = es
pop2.norm <- pop2.norm - mean(pop2.norm) # mean = 0
# create lognormal populations with desired means
pop1.lnorm <- rlnorm(1000000)
pop2.lnorm <- rlnorm(1000000)
pop1.lnorm <- pop1.lnorm - mean(pop1.lnorm) + es # mean = es
pop2.lnorm <- pop2.lnorm - mean(pop2.lnorm) # mean = 0
for(S in 1:nsim){ # simulation loop
if(S == 1){
print(paste("iteration",S,"/",nsim))
beep(2)
}
if(S %% 500 == 0){
print(paste("iteration",S,"/",nsim))
beep(2)
}
# draw nmax samples from populations
samp1.norm <- sample(pop1.norm, nmax, replace = TRUE)
samp2.norm <- sample(pop2.norm, nmax, replace = TRUE)
samp1.lnorm <- sample(pop1.lnorm, nmax, replace = TRUE)
samp2.lnorm <- sample(pop2.lnorm, nmax, replace = TRUE)
for(N in 1:length(nvec)){ # sample sizes = subsample nmax samples
# Compare two normal samples
pval <- yuen(samp1.norm[1:nvec[N]], samp2.norm[1:nvec[N]], tr=0, alpha=0.05)$p.value
if(pval<=.05) simres[1,N] <- simres[1,N] + 1 # number of type I errors
# Compare two lognormal samples
pval <- yuen(samp1.lnorm[1:nvec[N]], samp2.lnorm[1:nvec[N]], tr=0, alpha=0.05)$p.value
if(pval<=.05) simres[2,N] <- simres[2,N] + 1 # number of type I errors
# Compare one lognormal sample to a normal sample
pval <- yuen(samp1.lnorm[1:nvec[N]], samp2.norm[1:nvec[N]], tr=0, alpha=0.05)$p.value
if(pval<=.05) simres[3,N] <- simres[3,N] + 1 # number of type I errors
}
}
power.res <- simres / iter
save(power.res, file = "./data/power_res_twosample.RData")
beep(8)
load("./data/power_res_twosample.RData")
# create data frame
df <- tibble(power = as.vector(power.res),
pop = factor(rep(c("N-N", "LN-LN", "LN-N"), length(nvec))),
n = rep(nvec, each = 3))
# make plot
p <- ggplot(df, aes(x = n, y = power, colour = pop)) + theme_bw() +
geom_abline(intercept = 0.80, slope = 0, size = 0.5) + # 0.80 reference line
geom_abline(intercept = 0.90, slope = 0, size = 0.5) + # 0.90 reference line
geom_line(size=1) + # plot results
scale_colour_viridis_d(end = 0.9) + # change to perceptually uniform colourmap
theme(axis.title.x = element_text(size = 18),
axis.text = element_text(size = 16),
axis.title.y = element_text(size = 18),
legend.title=element_text(size=14),
legend.text=element_text(size=12)) +
scale_y_continuous(limits = c(0,1),
breaks = seq(0, 1, 0.1)) +
scale_x_continuous(limits = c(0, 300),
breaks = seq(0, 300, 50)) +
labs(x = "Sample size", y = "True positive probability") +
# ggtitle("Two-sample t-tests: power") +
guides(colour = guide_legend(override.aes = list(size=3)))
p
Guillaume A. Rousselet, 2019, University of Glasgow.


--- layout: post status: publish published: true title: Which Is the More Effective Pitcher? author: display_name: Andy login: Andy email<EMAIL_ADDRESS>url: '' author_login: Andy author_email<EMAIL_ADDRESS>wordpress_id: 4957 wordpress_url: http://ivyenvy.com/?p=4957 date: '2011-04-12 22:26:12 +0000' date_gmt: '2011-04-13 03:26:12 +0000' categories: - Relief Pitching tags: - John Grabow - Batting Tee comments: - id: 3205 author: Matt Veto author_email<EMAIL_ADDRESS>author_url: '' date: '2011-04-14 08:35:24 +0000' date_gmt: '2011-04-14 13:35:24 +0000' content: Or...http://micahmcmillan.files.wordpress.com/2008/11/sweet-tea-pitcher.jpg - id: 3210 author: Ryan author_email<EMAIL_ADDRESS>author_url: '' date: '2011-04-14 09:29:29 +0000' date_gmt: '2011-04-14 14:29:29 +0000' content: This is a tough one. Grabow (although hard to believe) has a better curve ball. But the tee ensures perfect "pitch" placement. Grabow is an actual human being which is another advantage but the only problem is the human being he happens to be is John Grabow and that's very unfortunate. The tee is made of polyethylene, which is recyclable, and you have to figure that you don't have to cut the tee a paycheck. - id: 3234 author: Andy author_email<EMAIL_ADDRESS>author_url: http://ivyenvy.com date: '2011-04-16 15:44:07 +0000' date_gmt: '2011-04-16 20:44:07 +0000' content: I think I have to go with the pitcher full of sweet tea. So sweaty and tasty. ---
John Grabow
or
Batting Tee


Abstract
BACKGROUND:
Meningoencephalomyelitis of unknown origin (MUO) is a common and life-threatening neuroinflammatory disease in dogs. Features of the disease are suggestive of an underlying immune-mediated process, but the association of this disease with a pathogen is still unknown.
HYPOTHESIS/OBJECTIVES:
To search for candidate etiologic agent associated with cases if MUO using next generation metagenomic sequencing.
ANIMALS:
Twenty-two dogs diagnosed with either MUO (11/22; 10 CSF and 3 brain), or noninflammatory CNS diseases inconsistent with MUO (11/22; 11 CSF and 2 brain) that served as negative controls.
METHODS:
A case control study was performed by identifying MUO and non-MUO cases. Samples were blindly processed and then unblinded for comparative analyses. Inclusion criteria for MUO cases included consistent MRI lesions and inflammatory CSF with a negative PCR panel for infectious agents or histopathologic diagnosis. Dogs with glucocorticoid therapy within 2 weeks of sample collection were excluded. Fresh-frozen cerebrospinal fluid (CSF; 21) and brain (5) samples were collected and RNA and DNA were extracted separately for shotgun metagenomic sequencing. Known positive samples were used as controls to validate our sequencing and analysis pipelines and to establish limits of detection. Sequencing results were analyzed at a nucleotide and protein level for broad comparison to known infectious organisms.
RESULTS:
No candidate etiologic agents were identified in dogs with MUO.
CONCLUSIONS AND CLINICAL IMPORTANCE:
These results support but do not prove the hypothesis that MUO is not associated with infectious agents and might be an autoimmune disease.
Comment
This work was a result of a great collaboration with veterinary neurologist Stephanie McGrath, who is a co-corresponding author.


Jan @Novoj Novotný
set of filters can differ for various path patterns
(org.springframework.security.web.SecurityFilterChain)
path matching is done via RequestMatcher
mostly via AntPathRequestMatcher but also RegexRequestMatcher and more
/foo/*/bar/**/data/*.jpg
/foo/**
/bar/*
/*.html
ChannelProcessingFilter - relocates user from HTTP to HTTPS (and vice versa) when ChannelDecisionManager says so
HeaderWriterFilter - takes care of writing HTTP security headers to the response
ConcurrentSessionFilter - tracks presence of all sessions,
SessionManagementFilter - enforces session management
Both types of configuration are similar one to another.
Typically UsernamePasswordAuthenticationFilter uses AuthenticationManager that calls AuthenticationProvider (usually DaoAuthenticationProvider) to load user details from UserDetailsService implementation.
DaoAuthenticationProvider checks validity of the password via PasswordEncoder.
When password is ok, new Authentication object is created and stored in SecurityContext.
SecurityContextPersistenceFilter fills SecurityContextHolder (usually ThreadLocal) with SecurityContext from SecurityContextRepository
/admin/**=ROLE_ADMINISTRATOR, ROLE_SUPER_ADMINISTRATOR
/userManagement/**=#{hasRole('ROLE_COMPANY_OWNER') and hasIpAddress('<IP_ADDRESS>/24')
/**=IS_AUTHENTICATED_ANONYMOUSLY
You can use either simple rules or expression rules, not both.
<http use-expressions="true">
<intercept-url pattern="/user/{userId}/**"
access="@myAuthService.checkUserId(authentication,#userId)"/>
</http>
@ refers to Spring bean objects
# refers to url parameters
Operates using Spring AOP abstraction.
Thus you can configure it manually by custom Aspects or exact mapping.
Method annotations:
@PreAuthorize("#contact.name == authentication.name")
public void doSomething(Contact contact);
@PreAuthorize("hasRole('USER')")
@PostFilter("hasPermission(filterObject, 'read')")
public List<Contact> getAll();
Filtering is not suitable for paged output.
But Spring Security can integrate with Spring Data!
Useful in scenarios when user having certain role
should also have another role.
ROLE_ADMIN > ROLE_STAFF
ROLE_STAFF > ROLE_USER
ROLE_USER > ROLE_GUEST
Admin will be also STAFF, USER, GUEST regarding access decision logic.
Hierarchy rules can be changed without touching user data.
If you need more robust authorization system - ie. when roles are not enough.
Implement your own PermissionEvaluator
public interface PermissionEvaluator extends AopInfrastructureBean {
boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission);
boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission);
}
And configure it:
Or use already implemented ACL system from Spring Security.
Allows you to mitigate String based "programming".
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("#contact.name == authentication.name")
public @interface ContactPermission {}
@ContactPermission
public void doSomething(Contact contact);
Currently doesn't allow multiple annotations on a single method.
Issue #4003
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@SecurityExecutionListeners
public class ExampleTestClass {
@Test(expected = AccessDeniedException.class)
@WithAnonymousUser
public void getMessageUnauthenticated() {
messageService.getMessage();
}
@Test
<EMAIL_ADDRESS>public void getMessageAsClientUser() {
assertNotNull(messageService.getMessage());
}
@Test
<EMAIL_ADDRESS>public void getMessageAsAdminUser() {
assertNotNull(messageService.getMessage());
}
}
To avoid strings in annotations and add better maintainability use meta-annotations:
@Retention(RetentionPolicy.RUNTIME)
<EMAIL_ADDRESS>public @interface RunAsAdministrator { }
And use it in test:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@SecurityExecutionListeners
public class ExampleTestClass {
@Test
@RunAsClient
public void getMessageAsClientUser() {
assertNotNull(messageService.getMessage());
}
@Test
@RunAsAdmin
public void getMessageAsAdminUser() {
assertNotNull(messageService.getMessage());
}
}
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
public class ExampleTestClass {
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders.webAppContextSetup(context)
.apply(springSecurity())
.build();
}
@Test
@WithAnonymousUser
public void shouldUserLogin() {
mvc.perform(formLogin("/auth").user("admin").password("pass")).with(csrf()))
.andExpect(authenticated());
}
@Test
@RunAsClient
public void shouldUserLogout() {
mvc.perform(logout("/signout")).with(csrf()))
.andExpect(unauthenticated());
}
}
Handy for developers as well as for customer administrators. Allows user with admin roles to switch to any other user with lower roles without knowing password.
@Override
protected void configure(HttpSecurity http) throws Exception {
final SwitchUserFilter filter = new SwitchUserFilter();
filter.setSwitchUserUrl("/switchUser");
filter.setUsernameParameter("username");
filter.setExitUserUrl("/restoreUserBack");
http.addFilterAfter(filter, FilterSecurityInterceptor.class)
.authorizeRequests()
.antMatchers("/switchUser").hasAnyAuthority("ROLE_ADMIN")
.antMatchers("/restoreUser").authenticated();
}
Consider also adding an IP check or other authentication checks to better secure user switching.
Warning! This feature is kind of a backdoor to your application.
Contact me at @Novoj or<EMAIL_ADDRESS>/userProfile/*=IS_AUTHENTICATED_FULLY
/login=IS_AUTHENTICATED_ANONYMOUSLY
/logout=IS_AUTHENTICATED_ANONYMOUSLY
/lostPassword=IS_AUTHENTICATED_ANONYMOUSLY
/**=IS_AUTHENTICATED_REMEMBERED
base64(username + ":" + expirationTime + ":" +
md5Hex(username + ":" + expirationTime + ":" password + ":" + key))
username: As identifiable to the UserDetailsService
password: That matches the one in the retrieved UserDetails
expirationTime: The date and time when the remember-me token expires, expressed in milliseconds
key: A private key to prevent modification of the remember-me token
series:token
Technique that misuses an authenticated relation to execute operations via HTTP calls invisible to the user using well known URLs and parameters.
HTTP GET method is easiest to hack, other methods require social engeneering or JavaScript to execute. But are not hard to do.
Originally Spring Security used CSRF token per request but it was quite impractical (browser back button, partial update) and thus CSRF token is now unique to session.
X-XSRF-TOKEN
to HTTP header (attacker won't be able to do this due to same origin policy) ... see
CookieCsrfTokenRepositoryNew W3C proposal First-Party-Only-Cookies suggests SameSite cookie that could bring an and to CSRF attack entirely.
Targeted for all types of authentication cookies.
These are defaults:
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
By only declaring:
Header example:
X-Content-Type-Options: nosniff
Tells browsers (Chrome,IE) not to guess content type of the document from it's content.
Attack scenario: malicious user uploads PDF file that contains JavaScript. Your server let other users to download such file and open it in their browser. Even if server supplies PDF content type, browser might decide not to trust it and detect content type by the contents of the file. Finally it handles PDF file as JavaScript one and executes the script.
Header example:
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Tells browser that all resources on this domain must be reached by HTTPS protocol.
Except first request all subsequent ones will be loaded over HTTPS by the browser. Even if there is explicit link with HTTP protocol.
First request problem can be solved with HSTS Preload
Header example:
Public-Key-Pins-Report-Only: max-age=5184000;
pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=";
pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=";
report-uri="http://example.net/pkp-report";
includeSubDomains
Tells browser that public key in the server certificate must match any of presented SHA256 hashes. Protects you against compromised CA.
Trust on First Use.
When using Public-Key-Pins
and the server delivers an unknown public key, the client should present a warning to the user.
Reports can be processed with Report URI service
Header example:
X-Frame-Options: deny
Tells browser not to load any FRAMES on your domain (or only frames targeting your/some domain).
Standardized as part of Content Security Policy.
Alternative variants:
X-Frame-Options: deny
X-Frame-Options: sameorigin
X-Frame-Options: allow-from www.seznam.cz
Header example:
X-XSS-Protection: 1; mode=block
Ask browser to assist you with reflected XSS attack.
If browser detects suspicious script in request that is reflected in the server response, script is blocked or reported.
Alternative variant:
X-XSS-Protection: 1; report=https://report-uri.io/
Header example:
Content-Security-Policy: script-src 'self' https://trustedscripts.example.com;
report-uri /csp-report-endpoint/
Site tels browser from which sources it expects to load resources.
Documentation at https://content-security-policy.com
Alternative variant:
Content-Security-Policy-Report-Only: script-src 'self';
report-uri /csp-report-endpoint/
After successfull authentication all registered
SessionAuthenticationStrategy
are called.
Preprogrammed implementations provide:
Attack vector: Attacker will create it's own session in the application. Via social engineering sends link to a user (or uses similar technique) that will make user browser to use already existing attacker session. When user logs in, attacker can act on behalf of the user.
Create new session on user login:
<session-management session-fixation-protection="migrateSession"/>
Spring Security can track all sessions in SessionRegistry.
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" expired-url="/sessionExpired.html"/>
When error-if-maximum-exceeded is false and max-sessions is exceeded least recently used session is invalidated. User using this session will get expired-url page.
Contact me at @Novoj or novotnaci@gmail.com


Contact information:
Address:
6 Place de l’Université 1205 Geneva - Switzerland
Telephone:
+ 41 22 592 5050
Email:
ASF INVESTMENTS SA is a Swiss wealth management company that specialises in international clienteles.
Our worldwide presence and our international expertise enable us to help you establish long-term tax and investment strategies.
Our mission is to advise clients and manage their assets in a completely independent manner.
Whether you are an entrepreneur, an executive or you represent a legal entity, our mission is to assist you within a privileged relationship, one that is based on trust and the long-term, in order to meet all of your estate needs.
Our main mission here at ASF INVESTMENTS SA is to assess and advise you in terms of the legal and fiscal structure of your private and business assets.

As today's legal and tax environment is constantly changing, we ensure that the legal, tax and estate strategies we establish are appropriate.
Our lawyers and our tax experts will subsequently accompany you in the implementation of our recommendations and your decisions.
Our investment philosophy is based on a secure and totally independent approach. Although our goal is to ensure performance, the priority is the preservation of your capital.
ASF INVESTMENTS SA's expertise entails an objective quantitative analysis combined with a qualitative analysis in order to select and combine the funds and managers that are most appropriate for the market environment.
Many competitors claim to have the same principle, paradoxically developing their own range of products which are specifically aimed at their own clients. This is obviously not the case with us.
We offer two types of services:
Clients who wish to delegate the management of their portfolio may entrust us with a management mandate. Together, we will then define an orientation that meets their objectives as well as the risk level that is best for them. We constantly adapt our management choices and our asset allocations according to the economic situation and financial market developments.
Clients who wish to actively manage their own investments can be accompanied in their choices through regular input in the form of personalised recommendations that are tailored to their convictions.
The establishment of a trust or foundation can allow you to secure your estate and plan its transfer to future generations while optimising your tax situation.
In addition, a trust or foundation can, for example, allow you to decide in advance who will look after your assets in the event that you are unable to do so in the future. This will ensure that your loved ones will not have to worry about your daily business affairs instead of your well-being.
We can also assist you in the preparation of your will.
Our role will be to oversee the protection of your assets, ensure the proper handling of your accounts and provide your beneficiaries with detailed reports.
It is therefore important that you appoint a trustee with experience, one that is known for its impartiality and its ability to administer assets, particularly in order to enhance your wealth according to your goals.
Thanks to our many banking partnerships, ASF INVESTMENTS SA offers a wide range of banking and cash management services including:
Address:
6 Place de l’Université 1205 Geneva - Switzerland
Telephone:
+ 41 22 592 5050
Email:


Producer-Consumer
- The bottle neck always exists.
- Low Liveness or Unsafe in guarded suspension example
- Data will be exchanged without the throughput loss
- Channel with exclusive control
- Channel
Queue, Stack, Priority queue, and etc.
- Built-in
- ArrayBlockingQueuue, LinkedBlockingQueue
- PriorityBlockingQueue
- DelayQueuue
- SynchronousQueue
- ConcurrentLinkedQueue


No noobs are allowed!!!
To prevent it, you must score atleast 3/5 in this qualifying test
To begin the test click here
Alohomora


Greetings!
At $datetime, an exception occurred while attempting to process a request from $user_login [$user_oid].
Ticket-friendly summary:
> User OID: $user_oid
> Method: $r_method
> URL: $r_url
> JSON: $r_json
>
```
$traceback
```
Good Luck!
Your friend,
Exception Auto-mailer


Overview
★
This library consists of 3 packages:
@ngx-gallery/core provides gallery component and service.
@ngx-gallery/lightbox provides a lightbox service that opens the gallery in an overlay.
@ngx-gallery/gallerize provides [gallerize]
directive that automatically hooks img elements to the lightbox.


Comparison of rate capabilities of LFP/LTO batteries made with different amounts of LFP and LTO and with LFP/LTO mass ratios of 1 and ~0.85. Paper Kodoshi separator is used for all electrodes. Full and empty characters represent charges and discharges, respectively.


| xpq | XPath query debugger. |
| sted | Simple full screen text editor that runs on the Windows command window or Linux terminal window. |
| rex | Simple regular expression matcher. |
| ms | Executes a command given as argument and prints its duration in milliseconds. |
| keys | Prints key codes obtained from the curses library. |
| HexDump | Prints hexadecimal dump of a file to console. |
| Hello | Hello World in Cmajor. |
| Calculator | Desk calculator whose parser is written manually. |
| BigNumCalc | Multiprecision desk calculator whose parser is generated using cmparsergen tool. |
| Args | Prints command line arguments to console. |


Klaytn API
(Transport<any>)
(string
= "klaytn"
)
import Klaytn from "@kompose-app/hw-app-klaytn";
const klay = new Klaytn(transport)
get Klaytn legacy account address for a given BIP 32 path.
Promise<{publicKey: string, address: string, chainCode: string?}>
:
an object with a publicKey, address and (optionally) chainCode
klay.getAddress("44'/8217'/0'/0/0").then(o => o.address)
This commands provides a trusted description of a Klaytn token to associate a contract address with a ticker and number of decimals.
It shall be run immediately before performing a transaction involving a contract calling this contract address to display the proper token information to the user if necessary.
(any)
: a blob from "tokens.js" utilities that contains all token information.
| Name | Description |
|---|---|
info.data any
|
Promise<boolean>
import { byContractAddress } from "@kompose-app/hw-app-klaytn/tokens"
const kusdInfo = byContractAddress("0x5faad3204b3ca681a6a312e15ff52a4cc76ade06")
if (kusdInfo) await klay.provideTokenInformation(kusdInfo)
const signed = await klay.signTransaction(path, rawTxHex)
You can sign a transaction and retrieve v, r, s given the raw transaction and the BIP 32 path of the account to sign
Promise<{v: number, r: string, s: string}>
klay.signTransaction("44'/8217'/0'/0/0", "e8018504e3b292008252089428ee52a8f3d6e5d15f8b131996950d7f296c7952872bd72a2487400080").then(result => ...)
You can sign a message according to klay_sign RPC call and retrieve v, r, s given the message and the BIP 32 path of the account to sign.
Promise<{v: number, s: string, r: string}>
klay.signPersonalMessage("44'/8217'/0'/0/0", Buffer.from("test").toString("hex")).then(result => {
var v = result['v'] - 27;
v = v.toString(16);
if (v.length < 2) {
v = "0" + v;
}
console.log("Signature 0x" + result['r'] + result['s'] + v);
})
Klaytn Tokens
import Tokens from "@kompose-app/hw-app-klaytn/tokens";
const tokensList = new Tokens().list();


In this post I will demonstrate how to add MiniProfiler to the XAF MainDemo web application.
MiniProfiler is a simple fast profiler with a pretty user interface. It is fast because it only profiles code that you have explicitly decorated with the MiniProfiler.Step() method. It was designed by the team at StackOverflow.
First, add the MiniProfiler NuGet package to the MainDemo.Web project. Then add a placeholder to default.aspx just before the last  tag.
12345678
<asp:PlaceHolderID="mp"runat="server"><%= StackExchange.Profiling.MiniProfiler.RenderIncludes() %>
</asp:PlaceHolder>
(MiniProfiler uses jQuery, but it does not usually require XAF to include it since it will automatically retrieve it if missing. Unfortunately there is currently a bug which causes a ’jQuery is undefined’ javascript error when initially launching the application. The easiest workaround I found is to explicitly include jQuery before calling RenderIncludes(). Hopefully this will be fixed in a future version of MiniProfiler.)
In global.asax.cs add the following to the Application_Start method.
Now we implement a helper class which determines whether profiling is enabled and which URLs to profile. We can use a variety of methods, the cookie probably being the most versatile one, but for the moment, the IsEnabled() function always returns true.
publicstaticclassMiniProfilerHelper{publicstaticboolIsEnabled(){// While we are testing let's always return truereturntrue;// We should not profile if we are EasyTestingif(TestScriptsManager.EasyTestEnabled==true)returnfalse;// We could choose to profile only local requestsif(HttpContext.Current.Request.IsLocal)returntrue;// Or based on a cookieHttpCookieminiProfileCookie=HttpContext.Current.Request.Cookies["MainDemoMiniProfiler"];returnminiProfileCookie!=null&&miniProfileCookie.Value!="0";}// Optionally ignore some paths to prevent the output being too busy.publicstaticvoidRegisterPathsToIgnore(){if(!NetSecuritySettings.IsProfilingAllowed())return;List<String>ignoredByMiniProfiler=newList<String>(MiniProfiler.Settings.IgnoredPaths);// these are a substring search so wildcards are not supportedignoredByMiniProfiler.Add("SessionKeepAliveReconnect.aspx");ignoredByMiniProfiler.Add("TemplateScripts.js");ignoredByMiniProfiler.Add("EasyTestJavaScripts.js");ignoredByMiniProfiler.Add("MoveFooter.js");ignoredByMiniProfiler.Add("ImageResource.axd");MiniProfiler.Settings.IgnoredPaths=ignoredByMiniProfiler.ToArray();}}
Done. Now whenever you run the web application, you get timing statistics for the loading of the assets. They appear as little clickable ‘chiclets’ in the top left of the browser page.
However, the real strength of MiniProfiler comes with the ability to add your own profiling steps. Let’s say we want to know exactly what percentage of the load takes place in the OnLoad event. Then we add the following to default.aspx.cs in order to add a ‘step’ to the MiniProfiler breakdown.
12345678
protectedoverridevoidOnLoad(EventArgse){varprofiler=MiniProfiler.Current;// it's ok for this to be nullusing(profiler.Step("ASP.NET: Page_Load(Default)")){base.OnLoad(e);}}
Now, the output is a good deal richer. Also, note that if the MiniProfiler assembly is missing from the web application’s bin directory, the profiling is ignored completely without error.
As another example, let’s profile the FindBySubject controller action.
Add the MiniProfiler NuGet package to the MainDemo.Module project. Then modify the FindBySubjectController.cs as follows
12345678910111213141516171819
private void FindBySubjectAction_Execute(object sender, ParametrizedActionExecuteEventArgs e)
{
+ var profiler = MiniProfiler.Current;+ using (profiler.Step("FindBySubject")) // doesn't matter if profiler is null+ { IObjectSpace objectSpace = Application.CreateObjectSpace();
string paramValue = e.ParameterCurrentValue as string;
if (!string.IsNullOrEmpty(paramValue))
{
paramValue = "%" + paramValue + "%";
}
object obj = objectSpace.FindObject(((ListView)View).ObjectTypeInfo.Type,
new BinaryOperator("Subject", paramValue, BinaryOperatorType.Like));
if (obj != null)
{
e.ShowViewParameters.CreatedView = Application.CreateDetailView(objectSpace, obj);
}
+ }}
Now navigate to the Tasks list view and enter some text where it says ‘Type Subject…’. You should see a new chiclet appear which contains the timing details as shown here.
MiniProfiler is a great tool for providing helpful profiling benchmarks, even in production. It’s often difficult to measure when a remote user complains to support that the site seems slow. How slow is slow? In a production environment, you can turn on MiniProfiler for the user (by setting a cookie for instance) and then ask them to share their profiling information for some basic operations. This information can be invaluable in determining where the fault lies.


Bruno Henriques
Software Engineer @ Kaluza | Backend | Former iOS Dev
Github
LinkedIn
Knowledge Base
Medium
Resume


5 biggest winners and losers in college basketball this week
by Meredith Cash, Business Insider US- The second week of the 2019-2020 basketball season has come and gone, and the AP Top 25 Poll looks quite different from last week.
- The Duke Blue Devils took over the top spot after the previously top-ranked Kentucky Wildcats fell in dramatic fashion to the unranked Evansville Purple Aces.
- The Louisville Cardinals, Michigan State Spartans, Kansas Jayhawks, and North Carolina Tar Heels round out the top five for the week.
- The ACC, Pac-12, and Big 12 all boast four teams in the rankings, while the Big Ten, SEC, and Big East conferences have three teams apiece in the top 25.
- Here are the five biggest winners and losers of Week 3 of the college basketball season.
- Visit Business Insider’s homepage for more stories.
Winners
▲ No. 10 Ohio State Buckeyes — Up 6 spots in the AP Top 25 Poll
Few teams had a better week than the Buckeyes. Ohio State hosted the then-No. 10 Villanova Wildcats and took care of business to the tune of a 25-point victory. The Buckeyes then followed up that effort with a 35-point win against Stetson and a six-spot climb in the AP Top 25 Poll. They’ll look to carry that momentum into December when they’re slated to face two top-10 teams in No. 5 North Carolina and No. 9 Kentucky.
▲ No. 14 Arizona Wildcats — Up 5 spots in the AP Top 25 Poll
The Wildcats beat their opponents by an average of 39 points this week. That incredible margin of victory, plus some major losses by previously higher-ranked teams in the AP Poll, bought Arizona a five-spot jump in this week’s rankings.
▲ No. 18 Xavier Musketeers — Up 3 spots in the AP Top 25 Poll
The Musketeers have looked solid through and through. This week, they survived close contests against the Missouri Tigers and Missouri State Bears, keeping their composure throughout. Now, Xavier will use the next few weeks to tune up and prepare for a December 30 showdown against Big East and fellow top-25 foe Villanova.
▲ No. 19 Auburn Tigers — Up 3 spots in the AP Top 25 Poll
Auburn survived a close call against the South Alabama Jaguars Tuesday but bounced back in a big way against the Cal State Northridge Matadors three days later. Guard Samir Doughty dropped 33 points en route to the Tigers’ 116-70 win. Auburn has unranked opponents lined up on the docket for the foreseeable future but looks to be one of the stronger teams in a wavering SEC.
▲ No. 1 Duke Blue Devils — Up 1 spot in the AP Top 25 Poll
The Blue Devils kicked off the week with a 51-point victory on their home floor before welcoming the Georgia State Panthers to Cameron Indoor Stadium for a closer but arguably even more impressive win. Sophomore point guard Tre Jones found his much-coveted shooting stroke, dropping a career-high 31 points on 10-of-19 shooting from the field and 4-of-8 shooting from beyond the arc. Mike Krzyzewski’s squad benefitted from Kentucky’s blunder and rode it to the top of the college basketball field.
Losers
▼ No. 9 Kentucky Wildcats — Down 8 spots in the AP Top 25 Poll
John Calipari’s Kentucky Wildcats were sitting pretty atop the world of college basketball when they made the bold and brave decision to invite the Evansville Purple Aces to Rupp Arena. The Purple Aces took care of business, toppling Goliath and dealing him his first loss of the season. The damage was good enough to bounce the Wildcats back eight spots in the AP Top 25 Poll. They have a few weeks to regain their bearings before facing No. 10 Ohio State and No. 2 Louisville back-to-back to end 2019.
▼ No. 17 Villanova Wildcats — Down 7 spots in the AP Top 25 Poll
Kentucky takes the cake for the worst week, but Jay Wright’s Villanova Wildcats weren’t too far behind. They started the week with a big win against the Army Black Knights, but a trip to the Buckeye State turned sour when then-No. 16 Ohio State dealt the Wildcats a demoralizing 25-point loss. Villanova bounced back with a decisive victory against the Ohio Bobcats, but it wasn’t enough to prevent a seven-point slide in this week’s AP Top 25 Poll.
▼ No. 16 Memphis Tigers — Down 3 spots in the AP Top 25 Poll
Penny Hardaway’s Tigers lost a tough matchup against the then-No. 14 Oregon Ducks early in the week, but perhaps their more noteworthy loss came in the form of their player. After initially resisting NCAA compliance, Memphis benched top-ranked freshman and preseason All-America selection James Wiseman and deemed him ineligible. It’s unclear how many games the 7-foot-1 center will miss while waiting for reinstatement, but the Tigers will undoubtedly miss their star as they gear up to take on Ole Miss, NC State, and No. 20 Tennessee in the coming weeks.
▼ No. 25 Washington Huskies — Down 5 spots in the AP Top 25 Poll
The Huskies lost their first game of the season to the previously unranked but respectable Tennessee Volunteers this week. Though Washington took down Mt. St Mary’s a few days prior, its 10-point victory wasn’t enough to offset the effect of a double-digit loss to Rick Barnes’ squad in the AP Poll.
▼ Florida Gators — Dropped out of the AP Top 25 Poll
On a recent episode of “CBS Sports’ Eye On College Basketball podcast,” hosts Gary Parrish and Matt Norlander deemed the Florida Gators the most overrated team heading into the 2019-2020 season. After getting blown out at home against in-state rival Florida State last week, the Gators barely survived in the final seconds against unranked Towson on Thursday. Three days later, Florida lost to another unranked squad – the Connecticut Huskies – cementing its drop out of the AP Poll for week 3.


BrunoJS is simmlar to React (Babel for JSX), but includes advanced features such as prototypes (varname.prototype) and is stored at it's same domain (of the docs), https://brunozhon.github.io
varname.prototype
https://brunozhon.github.io
Get BrunoJS now: Yay!


Doctor Lookup
Search by name
Search
Search by symptom
Search
Doctor/Practice Name
Address
Phone
WebSite
Accepting patients


| Interface | Description |
|---|---|
| Effect |
A simple function that represents the behaviour of a card.
|
| EffectContext |
An object that represents a context where an effect can run.
|
| Class | Description |
|---|---|
| ChainsawEffect |
Card effect that implements Adrenaline' Chainsaw weapon card.
|
| CyberbladeEffect |
Card effect that implements Adrenaline' Cyberblade weapon card.
|
| EffectLoader |
Class that provides methods to create effect objects from their class names.
|
| EffectManager |
Object that provides methods to card effect classes to:
- ask players who called the corresponding cards additional information
required by the defined rules.
|
| ElectroscytheEffect |
Card effect that implements Adrenaline' Electroscythe weapon card.
|
| FlamethrowerEffect |
Card effect that implements Adrenaline' Flamethrower weapon card.
|
| FurnaceEffect |
Card effect that implements Adrenaline' Furnace weapon card.
|
| GrenadeLauncherEffect |
Card effect that implements Adrenaline' Grenade Launcher weapon card.
|
| HeatseekerEffect |
Card effect that implements Adrenaline' Heatseeker weapon card.
|
| HellionEffect |
Card effect that implements Adrenaline' Hellion weapon card.
|
| LaserMagnumEffect |
Card effect that implements Adrenaline' Laser Magnum weapon card.
|
| LockRifleEffect |
Card effect that implements Adrenaline' Lock Rifle weapon card.
|
| MachineGunEffect |
Card effect that implements Adrenaline' Machine Gun weapon card.
|
| MockGameListener | |
| NewtonEffect |
Card effect that implements Adrenaline' Newton power up card.
|
| PaymentInvoice |
Represents a payment invoice containing a price for an action or card.
|
| PaymentReceipt |
Object that describes the ammos and power ups a player has used to pay.
|
| PaymentReceiptData |
A serializable version of PaymentReceipt.
|
| PlasmaGunEffect |
Card effect that implements Adrenaline' Plasma Gun weapon card.
|
| PowerGloveEffect |
Card effect that implements Adrenaline' Power Glove weapon card.
|
| RailgunEffect |
Card effect that implements Adrenaline' Railgun weapon card.
|
| RocketLauncherEffect |
Card effect that implements Adrenaline' Rocket Launcher weapon card.
|
| ShockwaveEffect |
Card effect that implements Adrenaline' Shockwave weapon card.
|
| ShotgunEffect |
Card effect that implements Adrenaline' Shotgun weapon card.
|
| SledgehammerEffect | |
| TagbackGrenadeEffect |
Card effect that implements Adrenaline' Tagback Grenade power up card.
|
| TargetingScopeEffect |
Card effect that implements Adrenaline' Targeting Scope power up card.
|
| TeleportEffect |
Card effect that implements Adrenaline' Chainsaw power up card.
|
| TestChainsawEffect | |
| TestCyberbladeEffect | |
| TestEffectManager | |
| TestElectroscytheEffect | |
| TestFlamethrowerEffect | |
| TestFurnaceEffect | |
| TestGrenadeLauncherEffect | |
| TestHeatseekerEffect | |
| TestHellionEffect | |
| TestLaserMagnumEffect | |
| TestLockRifleEffect | |
| TestMachineGunEffect | |
| TestNewtonEffect | |
| TestPlasmaGunEffect | |
| TestPowerGloveEffect | |
| TestRailgunEffect | |
| TestRocketLauncherEffect | |
| TestShockwaveEffect | |
| TestShotgunEffect | |
| TestSledgehammerEffect | |
| TestTagbackGrenadeEffect | |
| TestTargetingScopeEffect | |
| TestTeleportEffect | |
| TestTHOREffect | |
| TestTractorBeamEffect | |
| TestVortexCannonEffect | |
| TestWhisperEffect | |
| TestZX2Effect | |
| THOREffect |
Card effect that implements Adrenaline' T.H.O.R.
|
| TractorBeamEffect |
Card effect that implements Adrenaline' Tractor Beam weapon card.
|
| VortexCannonEffect |
Card effect that implements Adrenaline' Vortex Cannon weapon card.
|
| WhisperEffect |
Card effect that implements Adrenaline' Whisper weapon card.
|
| ZX2Effect |
Card effect that implements Adrenaline' ZX-2 weapon card.
|
| Enum | Description |
|---|---|
| MetaPlayer |
Possible values representing the player colors drawn in cards.
|
| Exception | Description |
|---|---|
| InvalidEffectException |
Thrown when the effect could not be loaded for problems with reflection and/or class file reading.
|
| UndoException |
Exception thrown when the user requests to undo the last choice they made.
|


You can't use your login before you receive the confirmation email and visit the activation link in there!
There is currently no way to reset a lost/forgotten password. If this happens, email the editors. You can change your password through the Preferences page once you're logged in. So use a simple password to register, and change it to the 128-bits-of-true-randomness-secure-one afterwards, otherwise you risk locking yourself out when you mis-type it here ;)
Login The login name you choose will be visible to other users in comments you post instead of your IP address.
Password Only hashes of passwords are stored on disk, but don't use the same password as for other systems.
Password confirmation
Full name The full name you specify here will be inserted as default in your future posts. You can still edit the value with each individual post, this merely saves you some typing.
Email address Please provide a valid email address. An email will be sent to this address containing an activation link. Your account will not be enabled before that link is visited. Your email address will not be visible to other users.
Web page Similar to the full name, this becomes the editable default value for future posts.
%%CAPTCHA%%


JS Bin is an open source collaborative JavaScript debugging tool.
If you want to get involved to help make JS Bin better (or perhaps fix a bug you've found), please fork JS Bin on github and send me a pull request.
Video tutorials will be coming shortly one day.


Hello world, parent.
{{::person.name}} is {{::person.age}}, and enjoys {{::person.hobby}}.
Number of people to show:
Add New Person
Hello world, child.
{{::person.name}} is {{::person.age}}, and enjoys {{::person.hobby}}.
Number of people to show:
Add New Person


Rezolver.Microsoft.AspNetCore.Hosting Package
This builds on the Rezolver.Microsoft.Extensions.DependencyInjection package to enable the integration of Rezolver into your Asp.Net Core site somewhat earlier in its startup phase.
Rezolver integration is available for both Asp.Net Core 1.1 and 2.0, with the Asp.Net Core 2.0 integration offering more flexibility as it allows you to perform configuration on the container(s) that are created before any registrations are made.
Asp.Net Core 2.1/2.0
Version 2.1
of the package supports Asp.Net Core 2.1; 2.0
supports Asp.Net Core 2.0.
Program.cs changes
After adding the package, change your program.cs
file so it looks like this:
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseRezolver()
.UseStartup<Startup>()
.Build();
// NOTE - you can also pass a configuration callback to UseRezolver(), e.g:
/*
* .UseRezolver(o =>
* {
* // Example of disabling contravariance
* o.TargetContainerConfig.ConfigureOption<EnableContravariance>(false);
*
* // you can also add configuration to the container configuration via
* // the ContainerConfig property (e.g. change compilers).
* })
*/
}
So, at the most basic level you just call the UseRezolver method, and that's enough.
Configuration call-back
If you've been reading some of the topics on this site - say, about contravariance
or lazy and eager enumerables then you'll have seen how we can use options
to control complex behaviours in Rezolver containers. That's what is shown in the alternative call
to UseRezolver
in the commented code. you can also pass a configuration callback that will be called
to modify the RezolverOptions that will be used to create both the IRootTargetContainer that
forms the basis of the registrations, and the ScopedContainer that will ultimately create the objects
for the application.
Note
Please note that lazy enumerables are currently switched off in Rezolver's integration with Asp.Net Core because of a mis-specification of a test by the Dependency Injection team.
The specification test is something which a DI container should pass if it's intending to be used with Asp.Net Core - and unfortunately there was one test that failed when Rezolver was using lazy enumerables - which is its default behaviour. An issue was raised on the Git repo and has been fixed, but it'll take a few more days/weeks before we see it in the wild.
We can say that if you need lazy enumerables, then you should be able to re-enable them and your application will work.
Startup.cs changes
Now we need to tell the Asp.Net Core stack that you want an IRootTargetContainer to be created in order to construct the ScopedContainer that will be used as the DI container.
The simplest way to do this is to add a single method (it can be empty) called ConfigureContainer
, which
accepts a single parameter of the type IRootTargetContainer.
Note
The IRootTargetContainer interface was added in Rezolver 1.3.2 to accommodate covariance
and is now the interface used for 'top-level' target containers. You can still declare your method
as ConfigureContainer<ITargetContainer>
without losing any functionality - so projects which are
upgrading from v2.0.x of the Hosting package will still work without any code changes.
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// you need AddOptions if you intend to use the configuration callback
// in your call to UseRezolver() in program.cs
services.AddOptions();
services.AddMvc();
}
// Adding this method (even if empty) is enough to trigger the use of Rezolver
// as the Asp.Net Core 2 Application's DI container.
public void ConfigureContainer(IRootTargetContainer targets)
{
// The targets passed here will be used to create the ScopedContainer.
// Perform additional Rezolver-specific registrations (e.g. Decoration) here.
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
Note
Note the call to AddOptions()
in the ConfigureServices
method. As the comment in the code says,
you need this if you intend to use configuration callbacks in your UseRezolver
method call in program.cs
.
By adding that ConfigureContainer
method, a new Rezolver ScopedContainer will be created and populated
from the IServiceCollection
that contains all the service registrations for the application.
As the comment states, inside that method you can also perform more configuration or registrations on the
IRootTargetContainer, such as decorators, expressions etc which are not supported by Microsoft's DI
abstractions, before the target container is passed to a new ScopedContainer that will then be
used as the application's IServiceProvider
.
And that's it - your application is configured.
Asp.Net Core 1.1
Version 1.3
is the latest version of the package that supports Asp.Net Core 1.1. The setup is fundamentally
identical, except the UseRezolver
method does not accept any callbacks.
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
//add the Rezolver container to the host builder
.UseRezolver()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
}
The startup.cs
is similar to what's required for Asp.Net Core 2.0 - except your ConfigureContainer
method should accept an ITargetContainer
- i.e. ConfigureContainer(ITargetContainer)
and then Rezolver will be used as the container for your application.
Clearly, we recommmend moving to Asp.Net Core 2.0 ASAP as it has more features, is faster, and is generally way cooler than 1.1! 😉


Weapons Trader Stanford:
I won't say it twice. You're a nuisance to the other customers, so please leave!


Whitefoot the Woodmouse
by Thornton W. Burgess
"Whitefoot Finds a Home at Last"
Additional Information
- Year Published: 1922
- Language: English
- Country of Origin: United States of America
- Source: Burgess T. W. (1922). Whitefoot the Woodmouse Boston: Little, Brown & Co..
-
Readability:
- Flesch–Kincaid Level: 4.5
- Word Count: 742
- Genre: Fantasy
- Keywords: 20th century literature, american literature, life lessons, nature
- ✎ Cite This
Downloads
True independence he has known
Whose home has been his very own.
—Whitefoot.
Curled up in his splendid warm bed, Timmy the Flying Squirrel slept peacefully. He didn’t know he had a visitor. He didn’t know that on top of that same bed lay Whitefoot the Wood Mouse. Whitefoot wasn’t asleep. No, indeed! Whitefoot was too worried to sleep. He knew he couldn’t stay in that fine house because it belonged to Timmy. He knew that as soon as Timmy awoke, he, Whitefoot, would have to get out. Where should he go? He wished he knew. How he did long for the old home he had left. But when he thought of that, he remembered Shadow the Weasel. It was better to be homeless than to feel that at any minute Shadow the Weasel might appear.
It was getting late in the afternoon. Before long, jolly, round, red Mr. Sun would go to bed behind the Purple Hills, and the Black Shadows would come creeping through the Green Forest. Then Timmy the Flying Squirrel would awake. “It won’t do for me to be here then,” said Whitefoot to himself. “I must find some other place before he wakes. If only I knew this part of the Green Forest I might know where to go. As it is, I shall have to go hunt for a new home and trust to luck. Did ever a poor little Mouse have so much trouble?”
After awhile Whitefoot felt rested and peeped out of the doorway. No enemy was to be seen anywhere. Whitefoot crept out and climbed a little higher up in the tree. Presently he found another hole. He peeped inside and listened long and carefully. He didn’t intend to make the mistake of going into another house where some one might be living.
At last, sure that there was no one in there, he crept in. Then he made a discovery. There were beech nuts in there and there were seeds.
It was a storehouse! Whitefoot knew at once that it must be Timmy’s storehouse. Right away he realized how very, very hungry he was. Of course, he had no right to any of those seeds or nuts. Certainly not! That is, he wouldn’t have had any right had he been a boy or girl. But it is the law of the Green Forest that whatever any one finds he may help himself to if he can.
So Whitefoot began to fill his empty little stomach with some of those seeds. He ate and ate and ate and quite forgot all his troubles. Just as he felt that he hadn’t room for another seed, he heard the sound of claws outside on the trunk of the tree. In a flash he knew that Timmy the Flying Squirrel was awake, and that it wouldn’t do to be found in there by him. In a jiffy Whitefoot was outside. He was just in time. Timmy was almost up to the entrance.
“Hi, there!” cried Timmy. “What were you doing in my storehouse?”
“I—I—I was looking for a new home,” stammered Whitefoot.
“You mean you were stealing some of my food,” snapped Timmy suspiciously.
“I—I—I did take a few seeds because I was almost starved. But truly I was looking for a new home,” replied Whitefoot.
“What was the matter with your old home?” demanded Timmy.
Then Whitefoot told Timmy all about how he had been obliged to leave his old home because of Shadow the Weasel, of the terrible journey he had had, and how he didn’t know where to go or what to do. Timmy listened suspiciously at first, but soon he made up his mind that Whitefoot was telling the truth. The mere mention of Shadow the Weasel made him very sober.
He scratched his nose thoughtfully. “Over in that tall, dead stub you can see from here is an old home of mine,” said he. “No one lives in it now. I guess you can live there until you can find a better home. But remember to keep away from my storehouse.”
So it was that Whitefoot found a new home.


BY EDWIN JAHIEL
EAST-WEST (France-Russia, 1999) *** Directed by Regis Wargnier. Written by Wargnier, Roustan Ibraguimbek, Sergei Bodrov, Louis Gardel. Photography, Laurent Dailland. Editing, Herve Schneid. Production design, Vladimir Svetozarov, Alexei Levtchenko. Music, Patrick Doyle. Cast: Sandrine Bonnaire (Marie), Oleg Menchikov (Alexei Golovin), Catherine Deneuve (Gabrielle), Sergei Bodrov, Jr. (Sacha), Ruben Tapiero (Serioja at 7), Erwan Baynaud (Serioja at 14), Grigoru Manoukiv, Tatiana Doguileva, Bogdan Stupka, Meglena Massalitinova, Valentine Gavev, Nikilai Binev, Rene Feret, et al. A Sony Classics release. In French (and some Russian) with subtitles. 121 minutes. PG-13. At the New Art Theatre.
World War II ended in 1945. A year later, in June 1946, the Soviet dictator Josef Stalin started a barrage of propaganda in the West, especially western Europe where there were many thousands of Russian émigrés. Stalin promised milk and honey, or more specifically, amnesty, a Russian passport, a warm welcome to the Soviet Union which the returnees would help reconstruct after its destructions during the Hitler War, and in fact make it even better a Workers' Paradise than it used to be. Russians seem to be more sentimental and nostalgic for their country than other people. So a lot of the émigrés took the bait --and lived (sometimes very briefly) to regret it.
Among them was Alexei Golovin a young doctor from Paris, his young French wife Marie, and their 7-year French-born son Serioja.
No sooner had the ship reached Odessa, even before all the passengers were on terra firms, the Golovin couple and many others realized what a mistake their return was. The majority of returnees get jailed, executed or are sent to gulags. The Golovins are spared because the Soviets need doctors.
The family is sent to Kiev, in a horrible "kommunalka" apartment where at best one gets just room per family, shares facilities (an euphemism--we see a man coming out of the toilet carrying his own wooden seat!), have no peace, no privacy, and be subjected to miseries by others. The people are also always spied upon, informed on, betrayed. It's not a wonderful life.
Very, very soon Marie wants to return to France -- and she would be stupid if she did not--but in the Soviet Union, what's done cannot be undone. Stalinist paranoia and mass madness rule, no one is safe, not even in his or her thoughts, not to mention that the least act or action can and will result in catastrophes.
Alexei agrees with his wife, but being more realistic (as well as of Russian extraction) he advises patience --which will lead a split in the couple. It's all very believable and very well documented and shown. A third, important character, depending on your set of mind, may or may not be considered a melodramatic addition. He is Sacha, the teen-ager and star swimmer (played by the son of one of the film's writers) who, under circumstances that I find not at all hard to believe, enters into a special relationship with Marie and later becomes part of her scheme to be taken back to France. The latter is a thread (a fat one too) that runs throughout the plot as it deals with the failed efforts of the woman (partly because her French passport was torn up by the Soviets) to contact French authorities in Russia.
There is a great more in incidents, events, surprises, suspense and criticism of Stalinist Russia. The movie was filmed in Russia for the most part, and has an undeniable visual authenticity. It is, of course, manicheistic, with white hats vs black hats, but there is really no way to maintain half-tones and subtleties in situations which, in real life, were black and white with little in-between.
Political films are becoming rare and more's the pity. Wargnier (pronounced Var-NYEH) had earlier won the Best Foreign Film Oscar for his also political "Indochine." I hope he stays on the track of history and politics, which teaches audiences a great deal more than space travel fiction.
"Le mauvais gout mene au crime"(Stendhal)
Edwin Jahiel's film reviews are at: http://www.prairienet.org/ejahiel/
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


3.1 Problems with sharing data between threads
If all shared data is read-only, there’s no problem. However, if data is shared between threads, and one or more threads start modifying the data, there’s a lot of potential for trouble.
One concept that’s widely used to help programmers reason about their code is that of invariants—statements that are always true about a particular data structure, These invariants are often broken during an update, especially if the data structure is of any complexity or the update requires modification of more than one value.
Consider a doubly linked list, the steps in deleting an entry from such a list are shown below:
- Identify the node to delete (N). a
- Update the link from the node prior to N to point to the node after N. b
- Update the link from the node after N to point to the node prior to N. c
- Delete node N. d
if one thread is reading the doubly linked list while another is removing a node, it’s quite possible for the reading thread to see the list with a node only partially removed (because only one of the links has been changed, as in step b of figure 3.1), so the invariant is broken.
The consequences of this broken invariant can vary; if the other thread is just reading the list items from left to right in the diagram, it will skip the node being. On the other hand, if the second thread is trying to delete the rightmost node in the diagram, it might end up permanently corrupting the data structure and eventually crashing the program. this is an example of one of the most common causes of bugs in concurrent code: a race condition.
3.1.1 Race Condition
In concurrency, a race condition is anything where the outcome depends on the relative ordering of execution of operations on two or more threads; the threads race to perform their respective operations.
the term race condition is usually used to mean a problematic race condition; benign race conditions aren’t so interesting and aren’t a cause of bugs. The C++ Standard also defines the term data race to mean the specific type of race condition that arises because of concurrent modification to a single object (see section 5.1.2 for details); data races cause the dreaded undefined behavior and it is problemic race condition.
Take steps in deleting an entry from such a list above as example. Assume thread a operation is to visit each element and thread b operation is to delete element. There are 3 outcomes with diferent relative-ordering executions:
- benign race condition outcome: thread a reads deleting element -> thread b deletes left link step b-> thread b deletes right link step c
- problemic race condition outcome: thread b deletes left link step b -> thread a reads deleting element -> thread b deletes right link step c
- benign race condition outcome: thread a reads deleting element -> thread b deletes right link step c -> thread a reads deleting element
3.1.2 Problematic race conditions
Problematic race conditions typically occur where completing an operation requires modification of two or more distinct pieces of data, such as the two link pointers in the above example.
what happens is that the operation must access two separate pieces of data, these must be modified in separate instructions, and another thread could potentially access the data structure when only one of them has been completed.
Because race conditions are generally timing sensitive, they can often disappear entirely when the application is run under the debugger, because the debugger affects the timing of the program, even if only slightly.
3.1.3 Avoid Problematic race conditions
- The simplest option is to wrap your data structure with a protection mechanism, to ensure that only the thread actually performing a modification can see the intermediate states where the invariants are broken. From the point of view of other threads accessing that data structure,such modifications either haven’t started or have completed.
- Another option is to modify the design of your data structure and its invariants so that modifications are done as a series of indivisible changes, each of which preserves the invariants. This is generally referred to as lock-free programming and is difficult to get right.
- Another way of dealing with race conditions is to handle the updates to the data structure as a transaction, just as updates to a database are done within a transaction. The required series of data modifications and reads is stored in a transaction log and then committed in a single step.
The most basic mechanism for protecting shared data provided by the C++ Standard is the mutex, so we’ll look at that.
3.2 Protecting shared data with mutexes
Before accessing a shared data structure, you lock the mutex associated with that data, and when you’ve finished accessing the data structure, you unlock the mutex.
Mutexes are the most general of the data-protection mechanisms available in C++, but they’re not a silver bullet:
- it’s important to structure your code to protect the right data (see section 3.2.2)
- avoid race conditions inherent in your interfaces (see section 3.2.3)
- deadlock (see section 3.2.4)
- protecting either too much or too little data (see section 3.2.8)
3.2.1 Use mutex
n C++, you create a mutex by constructing an instance of std::mutex , lock it with a call to the member function lock() , and unlock it with a call to the member function unlock().
The following listing shows how to protect a list that can be accessed by multiple threads using a std::mutex , along with std::lock_guard . Both of these are declared in the
#include <list>
#include <mutex>
#include <algorithm>
std::list<int> some_list; // 1
std::mutex some_mutex; // 2
void add_to_list(int new_value)
{
std::lock_guard<std::mutex> guard(some_mutex); // 3
some_list.push_back(new_value);
}
bool list_contains(int value_to_find)
{
std::lock_guard<std::mutex> guard(some_mutex); // 4
return std::find(some_list.begin(), some_list.end(), value_to_find) != some_list.end();
}
there’s a single global variable 1, and it’s protected with a corresponding global instance of std::mutex 2.
The use of std::lock_guard<std::mutex>
in add_to_list()
3 and again in list_contains()
4 means that the accesses in these functions are mutually exclusive: list_contains() will never see the list partway
through a modification by add_to_list()
.
If all the member functions of he class lock the mutex before accessing any other data members and unlock it when done, the data is nicely protected from all comers.
Well, that’s not quite true, as the astute among you will have noticed: if one of the member functions returns a pointer or reference to the protected data, then it doesn’t matter that the member functions all lock the mutex in a nice orderly fashion, because you’ve just blown a big hole in the protection.
Any code that has access to that pointer or reference can now access (and potentially modify) the protected data without locking the mutex.
Protecting data with a mutex therefore requires careful interface design, to ensure that the mutex is locked before there’s any access to the protected data and that there are no backdoors.
3.2.2 Structure code to protect right shared data
At one level, checking for stray pointers or references is easy; as long as none of the member functions return a pointer or reference to the protected data to their caller either via their return value or via an out parameter, the data is safe.
those functions that aren’t under your control might store the pointer or reference in a place where it can later be used without the protection of the mutex. Particularly dangerous in this regard are functions that are supplied at runtime via a function argument or other means, as in the next listing.
class some_data
{
int a;
std::string b;
public:
void do_something();
};
class data_wrapper
{
private:
some_data data;
std::mutex m;
public:
template<typename Function>
void process_data(Function func)
{
std::lock_guard<std::mutex> l(m);
func(data); // 1 Pass “protected” data to user-supplied function
}
};
some_data* unprotected;
void malicious_function(some_data& protected_data)
{
unprotected = &protected_data;
}
data_wrapper x;
void foo()
{
x.process_data(malicious_function); // 2 Pass in a malicious function
unprotected->do_something(); // 3 Unprotected access to protected data
}
you have a guideline to follow, which will help you in these cases:
Don’t pass pointers and references to protected data outside the scope of the lock, whether by
returning them from a function, storing them in externally visible memory, or passing them as
arguments to user-supplied functions.
Although this is a common mistake when trying to use mutexes to protect shared data, it’s far from the only potential pitfall. As you’ll see in the next section, it’s still possible to have race conditions, even when data is protected with a mutex.
3.2.3 Spotting race conditions inherent in interfaces
Consider a stack:
template<typename T,typename Container=std::deque<T> >
class stack
{
public:
explicit stack(const Container&);
explicit stack(Container&& = Container());
template <class Alloc> explicit stack(const Alloc&);
template <class Alloc> stack(const Container&, const Alloc&);
template <class Alloc> stack(Container&&, const Alloc&);
template <class Alloc> stack(stack&&, const Alloc&);
bool empty() const;
size_t size() const;
T& top();
T const& top() const;
void push(T const&);
void push(T&&);
void pop();
void swap(stack&&);
};
In order for a thread to safely pop a node:
- firstly you need to ensure that you’re preventing concurrent accesses to three nodes:
the node being deleted (node2) and the nodes on either side (node 1 and 3). - secondly you need to ensure that you’re preventing concurrent accesses to three interfaces:
empty(),top() and pop().
think about the reason for this whole problem in term of multi-level-invariant shown below:
// to maitain level 1 invarirant, lock concurrent accesss to stack varaibles inside each interface
// to maitain level 2 invariant, lock concurrent accesss to stack interfaces inside caller scope
stack<int> s;
if(!s.empty()) //1
{
int const value=s.top(); //2
s.pop(); //3
do_something(value);
}
calling top() on an empty stack is undefined behavior. With a shared stack object, this call sequence is no longer safe, because there might be a call to pop() from another thread that removes the last element in between the call to empty() and the call to top()._This is yet another race condition and far more insidious than the undefined behavior of the empty() / top() race;
the use of a mutex internally to protect the stack contents doesn’t prevent it; it’s a consequence of the interface. This problem is not unique to a mutex-based implementation; it’s an interface problem, so the race conditions would still occur with a lock-free implementation.
A more radical change to the interface that combines the calls to top() and pop() under the protection of the mutex can resolved PRC but a combined call can lead to issues if the copy constructor for the objects on the stack can throw an exception.
Why? Assume you have stack<vector<int>>
. If the pop() function was defined to return the value popped,
as well as remove it from the stack,you have a potential problem: the value being popped is returned to the caller only
after the stack has been modified, but the process of copying the data to return to the caller might throw an exception.
If this happens, the data just popped is lost; it has been removed from the stack, but the copy was unsuccessful!
So the designers of the std::stack interface helpfully split the operation in two: get the top element ( top() ) and then remove it from the stack ( pop() ), so that if you can’t safely copy the data, it stays on the stack. If the problem was lack of heap memory, maybe the application can free some memory and try again.
Unfortunately, it’s precisely this split that you’re trying to avoid in eliminating the race condition! Thankfully, there are alternatives, but they aren’t without cost.
- PASS IN A REFERENCE
pass a reference to a variable in which you wish to receive the popped value as an argument in the call to pop():void pop(std::vector<int>& result); std::vector<int> result; some_stack.pop(result);
-
RETURN A POINTER
return a pointer to the popped item rather than return the item by value.
The advantage here is that pointers can be freely copied without throwing an exception, so you’ve avoided Cargill’s exception problem.
The disadvantage is that returning a pointer requires a means of managing the memory allocated to the object, and for simple types such as integers, the overhead of such memory manage- ment can exceed the cost of just returning the type by value - provide both of 2 and 3
Flexibility should never be ruled out, especially in generic code
Based on suggestions shown above, this is an thread-safe-stack:
#include <exception>
#include <memory>
#include <mutex>
#include <stack>
struct empty_stack: std::exception
{
const char* what() const throw() {};
};
template<typename T>
class threadsafe_stack
{
private:
std::stack<T> data;
mutable std::mutex m;
public:
threadsafe_stack(){}
threadsafe_stack(const threadsafe_stack& other)
{
// 1 This stack implementation is actually copyable—the copy constructor
// locks the mutex in the source object and then copies the internal stack.
// You do the copy in the constructor body rather than the member initializer
// list in order to ensure that the mutex is held across the copy.
std::lock_guard<std::mutex> lock(m);
data = other.data;
}
threadsafe_stack& operator=(const threadsafe_stack&)=delete;
void push(T new_value)
{
std::lock_guard<std::mutex> lock(m);
data.push(new_value);
}
std::shared_ptr<T> pop()
{
std::lock_guard<std::mutex> lock(m);
//2 Check for empty before trying to pop value
if(data.empty()) throw empty_stack();
//3 allocate return value before pop it out
std::shared_ptr<T> const res(std::make_shared<T>(data.top()));
data.pop();
return res;
}
void pop(T& value)
{
std::lock_guard<std::mutex> lock(m);
//4 some threads remove element from backdoor interfaces eg, call data.pop()
if(data.empty()) throw empty_stack();
value=data.top();
data.pop();
}
bool empty() const
{
std::lock_guard<std::mutex> lock(m);
return data.empty();
}
Problems with mutexes can also arise from:
- locking at too large a granularity
the extreme situation is a single global mutex that protects all shared data. - locking at too small a granularity
the protection doesn’t cover the entirety of the desired operation (this is problem )
One issue with fine-grained locking schemes is that sometimes you need more than one mutex locked in order to protect all the data in an operation.
if you end up having to lock two or more mutexes for a given operation, there’s another potential problem lurking in the wings: deadlock. This is almost the opposite of a race condition: rather than two threads racing to be first, each one is waiting for the other, so neither makes any progress.


class: middle, center # Basic Rust Syntax ### This presentation will give you a quick overview of basic Rust syntax --- class: middle, left # Variables `let` introduces new variables: ```rust let x = 5; ``` Variables are immutable by default ```rust let x = 5; x += 1; ``` ```text error[E0384]: cannot assign twice to immutable variable `x` | let x = 5; | - first assignment to `x` | x += 1; | ^^^^^^ cannot assign twice to immutable variable ``` in order to modify them, you need to say they're `mut`able: ```rust let mut x = 5; x += 1; ``` --- class: middle, left # Basic Types Rust is statically typed, but infers types for you. You can write them out if you'd like: ```rust let x = 5; let x: i32 = 5; ``` Rust has a few primitive types: * **Booleans**: are *true* and *false* * **Integers**: are both signed and unsigned. *u8*/*i8*, *u16*/*i16*, *u32*/*i32*, *u64*/*i64*, and *u128*/*i128*. * **Floating point numbers**:, *f32* and *f64* * **Tuples**: are for grouping different types together *(i32, f64, i8)* * **Arrays**: that are fixed size *[u32; 3]* is the type of *[1, 2, 3]* * **References**: like pointers but safer. *&i32* is the type of *&5* * **Slices**: refer to parts of an array *&[u8]* * **char**: is a single Unicode Scalar Value, and uses single quotes *'🦀'* * **&str**: is an immutable UTF-8 string *"this is a crab: 🦀"* --- class: middle, left # Functions Here's a small function that adds one to a number: ```rust fn add_one(x: i32) -> i32 { x + 1 } ``` * `fn` declares a function, and the name `add_one` follows. * `()`s show you the parameter list; you must write the names and types of your parameters; Rust won't infer these! * The arrow `->` gives the return type. You can only return one thing, but don't forget, tuples work: `-> (i32, i32)` * The body goes inside curly braces `{}`, and lines end with a semicolon `;` * "everything is an expression"; so the last line is the return value, no `;`. You can use `return` explicitly if you prefer, or to return early: ```rust fn add_one(x: i32) -> i32 { return x + 1; } ``` --- class: middle, left # Printing to the Screen The `println!` macro will let you print to the screen: ```rust println!("Hello, world!"); ``` You can do formatted print with `{}`: ```rust println!("Here's a number: {} and another: {}", 42, 100); ``` You can debug print with `{:?}`: ```rust println!("Display: {}", "hello"); // prints "Display: hello" println!("Debug: {:?}", "hello"); // prints "Debug: "hello"" ``` --- class: middle, left # Comments Rust has two main kinds of comments. Regular comments for your own use: ```rust // Put whatever you'd like here, Rust doesn't care ``` And doc comments: ```rust /// This comment documents the `foo` function. /// /// You can use the `rustdoc` tool via `cargo doc` to generate /// HTML documentation from these comments! fn foo() { // ... } ``` --- class: middle, left # `if` expressions The `if` expression lets you do something if something is true or false, and `else` is there too: ```rust if something { println!("it was true!"); } else { println!("it was false"); } ``` Because `if` is an expression, you can use it in all kinds of places: ```rust let power = if too_powerful { 0 } else { 100 }; ``` Now `power` will be `0` or `100` based on the `too_powerful` variable's value. --- class: middle, left # `for` and `while` Loops `for` loops will let you iterate over a range or collection: ```rust for i in 0..5 { println!("{}", i); } let list = [1, 5, 3, 17]; for i in &list { println!("{}", i); } ``` `while` loops loop until a condition is met: ```rust let mut done = false; let mut i = 0; while !done { // do stuff with i if i > 5 { done = true; } } ``` --- class: middle, left # Structs and enums Structs let you group multiple primitive types together into one big type: ```rust struct Point { x: i32, y: i32, } let origin = Point { x: 0, y: 0, }; ``` Enums are similar, but you can only have one of the variants at a time: ```rust enum TrafficLight { Green, Yellow, Red, } let light = TrafficLight::Green; ``` Enums are way more powerful than this, but that's for another set of slides! --- class: middle, left # Methods Methods are like functions, but take a special `self` parameter and can be called with method syntax: ```rust struct Point { x: i32, y: i32, } impl Point { fn print(&self) { println!("({}, {})", self.x, self.y); } } let origin = Point { x: 0, y: 0 }; point.print(); // prints "(0, 0)" ```


--- layout: post status: publish published: true title: Blogging Engine Recommendations? author: display_name: Tomas Restrepo login: tomasr email<EMAIL_ADDRESS>url: http://winterdom.com/ author_login: tomasr author_email<EMAIL_ADDRESS>author_url: http://winterdom.com/ wordpress_id: 554 wordpress_url: http://winterdom.com/2005/02/bloggingenginerecommendations date: '2005-02-20 07:39:42 +0000' date_gmt: '2005-02-20 07:39:42 +0000' categories: - Blogging tags: [] comments: [] ---
I've been lately considering changing blogging engines (for some things, Movable Type is a little bit too inflexible for my taste, although it has worked very nicely for the past two years). Can anyone recommend a choice? The one thing that has been holding me back on doing this is, of course, breaking the URLs and links accumulated to my entries over all this time...
I've been considering either DasBlog or .Text. What do you guys prefer? Any tips on migrating my existing content over to the new engine? Also, how hard is it to create new templates for either one (as I'd like to put something that resembles my existing templates in place). Any feedback is welcome :)


There are many different factors that influence whether a team wins an NFL game. One would think the better team always wins but that is not always the case. And what makes a team better than another anyway? Input the values and learn how much better your team could have been with a different quarterback or a better defense.
To check the stats of you favorite players, visit Pro Football Reference
Every field and its importance will be explained within the form.
{{ predictionErrors }}