◆ animateOptionChange:
| - (void) animateOptionChange: |
|
(int) |
viewNumber |
|
Shift UI elements to move UITextView to top of screen to accomodate keyboard.
◆ commitDataToUserData
| - (void) commitDataToUserData |
|
|
|
Actually commits data to UserData from User request.
◆ hideKeyboard
Called from custom Done button to return UI back to normal.
◆ increaseEthicals
| - (void) increaseEthicals |
|
|
|
Add designated amount to User's amount of ethicals.
◆ limitTextField:
| - (void) limitTextField: |
|
(NSNotification *) |
note |
|
Prevent User from entering more text than field allows.
◆ activeField
◆ backgroundImageView
| - (IBOutlet UIImageView*) backgroundImageView |
|
protected |
◆ cancelButton
| - (IBOutlet UIButton*) cancelButton |
|
protected |
cancel button for ViewController dismissal and entry deletion
◆ choiceDescriptionView
| - (IBOutlet UIView*) choiceDescriptionView |
|
protected |
UIView for shifting bottom parameter for keyboard.
◆ choiceKey
| - (NSMutableString*) choiceKey |
|
protected |
nsmanagedobject of current choice
◆ choiceParametersView
| - (IBOutlet UIView*) choiceParametersView |
|
protected |
UIView for hiding top parameters for keyboard.
◆ choiceTextField
overloaded text field for choice title
◆ currentUserChoice
determine if choice is complete
◆ descriptionInnerShadow
| - (IBOutlet UIImageView*) descriptionInnerShadow |
|
protected |
faux inner drop shadow for UITextView
◆ descriptionTextView
| - (IBOutlet UITextView*) descriptionTextView |
|
protected |
UITextView for choice's extended description.
◆ hideKeyboardButton
| - (IBOutlet UIButton*) hideKeyboardButton |
|
protected |
done button for UITextView keyboard dismissal
◆ isChoiceFinished
| - (BOOL) isChoiceFinished |
|
protected |
determine if screen shown is virtue or vice
◆ isVirtue
list of localized severity descriptions
◆ moralButton
| - (IBOutlet UIButton*) moralButton |
|
protected |
moral button list selection for ViewController dismissal
◆ moralHistoryButton
| - (IBOutlet UIButton*) moralHistoryButton |
|
protected |
moral history button which selects previous entries
◆ moralImageView
| - (IBOutlet UIImageView*) moralImageView |
|
protected |
◆ moralKey
string to hold primary key of current choice
◆ moralReferenceButton
| - (IBOutlet UIButton*) moralReferenceButton |
|
protected |
moral button which selects moral reference
◆ prefs
| - (NSUserDefaults*) prefs |
|
protected |
serialized user settings/state retention
◆ saveButton
| - (IBOutlet UIButton*) saveButton |
|
protected |
save button for ViewController dismissal
◆ severityLabel
| - (IBOutlet UILabel*) severityLabel |
|
protected |
UILabel for UISlider of choice's severity.
◆ severityLabelDescriptions
| - (NSMutableArray*) severityLabelDescriptions |
|
protected |
temporary overloaded text field for determining active field
◆ severitySlider
| - (IBOutlet UISlider*) severitySlider |
|
protected |
UISlider for choice's severity.
◆ choiceDetailViewController
◆ historyViewController
◆ virtueViceViewController
string to hold primary key of current moral
The documentation for this category was generated from the following file:


Send NXT
Send NXT to another address without using your NXT Wallet.
Amount of NXT to Send
Destination Address
Secret Phrase
Send
The cost of this transaction is 1 NXT.


Home
>
WCAG ARIA Techniques
aria-required
Source:
W3C ARIA techniques
Note: [*]denotes mandatory field
Login name:
[*]
Password
[*]


🎉 🎊
Your account has been created.
Now install the CLI to get started with Ops.
2 - Install The Ops CLI
Open the terminal app and install The Ops CLI using this command:
$ npm install -g @cto.ai/ops
3 - Sign In
Once installed, you must sign in to your account. Use the command:
$ ops account:signin
After signing in you're all set to start making and running Ops.
Book a 15 minute overview
Interested in how the Ops Platform could benefit your entire team?
Let's schedule 15 minutes to talk.
For detailed information on how to use the the Ops Platform, view the Overview page.
To learn how to create your own Ops, check out our Getting Started guide.


--- layout: default title: Haichao Miao's personal website ---
I am a Post-doctoral researcher at the Lawrence Livermore National Laboratory. My goal is to visualize large-scale data from complex scientifc domains and develop interactive tools for the exploration and analysis.
I moved to California and started my new Post-doctoral Researcher position at the Lawrence Livermore National Laboratory! Very excited to get started with the visualization of advanced material scans and large-scale dynamic microscopy images.
December 2020I will be a Topic Editor for the Frontiers in Bioinformatics. Together with Prof. Barbora Kozlikova and Prof. Michael Krone we announced a Special Issue on Visualization of Biomolecular Structures.
July 2020I started a new position at the Austrian Institute of Technology and joined the EU H2020 MARILIA project. The goal is to develop novel technology to enable fast detection of pathogens in water. I'll be working on the development of novel technolgoies for simulating and designing DNA-protein hybrid structures. It's good to switch focus from applied visualization research to molecular dynamics simulation and modeling.
June 2020Our software system Adenita for the interactive 3D modelling and visualization of DNA nanostructures was published in the Nucleic Acids Research Journal as a full paper. Adenita heavily relies on advanced multiscale visualization and scale-adaptive modifications, which we I published at IEEE SciVis 2017. It has always been my goal to publish my visualization reserach in the domain science as well. This tools is now being used by several research groups around the world that focus on DNA-based nanostructures.
November 2019I will giving a talk on "From In Silico to In Vitro: Modeling DNA Nanostructures" at the Cell Visualization Summit at KAUST, Saudi Arabia.
September 2019My student Max Sbardellati is presenting his paper on exploded views of large molecular structures at the 9th EG Workshop on Visual Computing for Biology and Medicine (VCBM) 2019 in Brno, Czechia. It's great to work together with young promising academics!
August 2019I successfully defended my PhD! After four years, this moment has been eagerly anticipated. I'm so grateful to have worked with and learned from my doctoral advisor Ivan Viola . Shout out to my co-advisors, it was a pleasure to have worked with them: Ivan Barisic, Tobias Isenberg, and Eduard Groeller.
July 2019Our paper on multiscale visualization of the 3D genome got accepted at IEEE SciVis 2019.
July 2019I am going to be tutorial chair at the 9th EG Workshop on Visual Computing for Biology and Medicine (VCBM) 2019 in Brno, Czech Republic and give a presentation on Visual Abstraction in DNA Nanotechnology.
May 2019I presented a poster on Interactive Visual Analysis for the Design of DNA Nanostructures at the NANTECH 2019 in Espoo, Finland.


Owusu Dankwah Eric
Graphic Designer
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing .


UK Musician Reunited With 310-Year-Old Violin Worth $320,000 Left on Train - Reports
MOSCOW (Sputnik) - An antique violin worth more than 250,000 British pounds ($320,000) left in a London train was returned to its owner, UK musician Stephen Morris, the Sky News broadcaster reported on Saturday.
The musician got on a train at the London Victoria station on 22 October at 10.58 p.m. and put a case with the instrument on the luggage rack located above the seats. He accidentally left the violin on the train when he got off at his stop.
On his Twitter, Morris confirmed the reunion with the precious musical instrument.
Morris had previously asked the UK media for help with finding a violin. The instrument was made in 1709 by luthier David Tecchler.
After losing the violin, Morris, who was leading the Royal Philharmonic Orchestra and has recorded with the likes of David Bowie and Steve Wonder, admitted that he was very upset by the loss and was only the temporary playing the instrument, hoping to transfer it to other musicians.


Person recognition
using Eigenfaces
A Project by Captain Mich
This is an App made for a University project that computes eigenfaces and recognize a person in a given database set
Project Division
Below we are going to divide the project in sections; we also assume that the database is just a folder with color pics inside
- 1. Main Activity
- 2. Create Database Class
- 3. Create Image Class
- 4. Create Eigenfaces Class and Task
- 5. Create Facial Recognition Class and Task
- 6. Create Camera Task to Take a Picture
Main Activity
To start, let's go to create a simple graphical interface for our app. It will be made by:
- A button to create the database
- A button to compute the eigenfaces
- A button to take a picture with the database set
- A button to compare the taken picture with the database set
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btn_check"
android:layout_width="352dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="16dp"
android:text="Check"
tools:layout_editor_absoluteX="148dp"
tools:layout_editor_absoluteY="409dp" />
<Button
android:id="@+id/btn_training"
android:layout_width="175dp"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/btn_check"
android:layout_alignParentBottom="true"
android:layout_marginBottom="129dp"
android:text="Training"
tools:layout_editor_absoluteX="148dp"
tools:layout_editor_absoluteY="409dp" />
<Button
android:id="@+id/btn_take_picture"
android:layout_width="352dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="71dp"
android:text="Take Picture"
tools:layout_editor_absoluteX="148dp"
tools:layout_editor_absoluteY="409dp" />
<Button
android:id="@+id/btn_load_db"
android:layout_width="175dp"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/btn_check"
android:layout_alignTop="@+id/btn_training"
android:text="Load DB"
tools:layout_editor_absoluteX="148dp"
tools:layout_editor_absoluteY="409dp" />
</RelativeLayout>
Then we need to link all the created buttons in the Main Activity of our app in order to be able to use them.Two methods are defined: one to initialize the elements of our interface, the other one to initialize the listeners of each button. Then, the two methods are called inside the onCreate.
public class MainActivity extends AppCompatActivity implements EigenfacesResultTask {
private Button btn_Load_Db = null;
private Button btn_Take_Picture = null;
private Button btn_Check = null;
private Button btn_Training = null;
private Context context = null;
public Database db = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
initViews();
initListeners();
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
/**
* This method is to initialize views
*/
private void initViews() {
btn_Load_Db = (Button) findViewById(R.id.btn_load_db);
btn_Take_Picture = (Button) findViewById(R.id.btn_take_picture);
btn_Check = (Button) findViewById(R.id.btn_check);
btn_Training = (Button) findViewById(R.id.btn_training);
}
/**
* This method is to initialize listeners
*/
private void initListeners() {
btn_Load_Db.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
btn_Training.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
btn_Take_Picture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
btn_Check.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
}
}
Database Class
For reasons of simplifications we are going to assume that the database is just a folder with a given set of color images of any dimension not bigger than 2 MB (simply for a speed time reason, especially on big databses). It's noticeable also that in a database there can be more than one face of a same person; each image should have the same light exposition and each face should be aligned. In our example we are going to take as database set 20 images made of 4 people in 5 different position.
In order to go through the next phases of the project we need to resize the images: we have chosen 256 x 256 pixels as default dimension. We also need to turn them into grayscale to reduce the computational cost of the implementation and compress as '.png' filetype. Let's go into the code:
public class Database {
private String DEFAULT_APP_IMAGEDATA_DIRECTORY;
private String lastImagePath = "";
/** Decodes the Bitmap from 'path' and returns it */
public Bitmap getImage(String path) {
Bitmap bitmapFromPath = null;
try {
bitmapFromPath = BitmapFactory.decodeFile(path);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return bitmapFromPath;
}
/** Returns the String path of the last saved image */
public String getSavedImagePath() {
return lastImagePath;
}
public boolean putImageWithFullPath(String fullPath, Bitmap theBitmap) {
return !(fullPath == null || theBitmap == null) && saveBitmap(fullPath, theBitmap);
}
public String setupFullPath(String imageName, String path) {
File mFolder = new File(Environment.getExternalStorageDirectory()+ path);
if (isExternalStorageReadable() && isExternalStorageWritable() && !mFolder.exists()) {
if (!mFolder.mkdirs()) {
Log.e("ERROR", "Failed to setup folder");
return "";
}
}
return mFolder.getPath() + '/' + imageName;
}
/** Check if external storage is writable or not */
public static boolean isExternalStorageWritable() {
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
}
/** Check if external storage is readable or not */
public static boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
return Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
}
/** Saves the Bitmap as a PNG file at path 'fullPath' */
private boolean saveBitmap(String fullPath, Bitmap bitmap) {
if (fullPath == null || bitmap == null)
return false;
boolean fileCreated = false;
boolean bitmapCompressed = false;
boolean streamClosed = false;
File imageFile = new File(fullPath);
if (imageFile.exists())
if (!imageFile.delete())
return false;
try {
fileCreated = imageFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
FileOutputStream out = null;
try {
out = new FileOutputStream(imageFile);
bitmapCompressed = bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (Exception e) {
e.printStackTrace();
bitmapCompressed = false;
} finally {
if (out != null) {
try {
out.flush();
out.close();
streamClosed = true;
} catch (IOException e) {
e.printStackTrace();
streamClosed = false;
}
}
}
return (fileCreated && bitmapCompressed && streamClosed);
}
public void createDatabase(){
String folder_path = Environment.getExternalStorageDirectory()+"/APP/DB_colors/";
String image_path = null;
File directory = new File(folder_path);
File[] files = directory.listFiles();
//Log.d("Files", "Size: "+ files.length);
if (files != null) {
for (int i = 0; i < files.length; i++) {
image_path = folder_path + files[i].getName().toString();
Bitmap temp = getImage(image_path);
Bitmap temp_bw = Image.createGrayScale(temp);
Bitmap resized_temp = Image.resizeImage(temp_bw);
putImageWithFullPath(setupFullPath(files[i].getName().toString().replace(".jpeg","") + "_bw.png", "/APP/DB_bw"), resized_temp);
}
}
}
public void createTrainingDatabase(Bitmap src, int numberOfImage){
putImageWithFullPath(setupFullPath("image_" + String.valueOf(numberOfImage) + "_eigen.png", "/APP/DB_Training"), src);
}
}
We created a public Database class made with some different methods, let's look at them in detail:
- getImage -> this method takes in input a file path and return ,if it is possible (see the try and catch block), the decoded file as a Bitmap
- getSaveImagedPath -> this method just gives us the path of the last saved image as a string
- isExternalStorageWritable -> this method is boolean, it check if external storage is writable or not
- isExternalStorageReadable -> this method is boolean, it check if external storage is readable or not
- setupFullPath -> this method is used to create our database grayscale folder; if the path is successfully created it is returned as a string.
- setupFullPathTraining -> this method is used to create our eigenfaces folder; if the path is successfully created it is returned as a string.
- saveBitmap -> this method is boolean, it save the Bitmap as a '.png' file at the given input path. It return true only if the file is created, the bitmap compression in '.png' is made and the stream is successfully closed.
- putImageWithFullPath -> this method take in input the path where you want to save the '.png' image and a Bitmap filetype; using the
saveBitmap
method, it save the image in the chosen path
- createDatabase -> this method combine some other methods of the Image class, that we will create after, to manipulate the image to satisfy our initial working conditions and finally save the grayscale image.
After checking if the database colors fold exists, we use theputImageWithFullPath
method in a for cycle to convert each any dimension colors image to a black and white 256 x 256 pixels '.png' image.
- createTrainingDatabase -> this method will be used in the next section to store the eigenfaces in a folder
To be sure that everything works correctly we need to add the writing permission on the AndroidManifest.xml
(it's possible to find it by following this path: 'app' -> 'manifest'):
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Image Class
We are now going to create a class to manage all the image manipulation that we need in our process
public class Image {
private static final String TAG="Image";
public static Bitmap resizeImage(Bitmap src){
if(src!=null)
return Bitmap.createScaledBitmap(src, 256, 256, true);
else
Log.e(TAG,"Error, file don't exist");
return null;
}
public static Bitmap createGrayScale(Bitmap src){
int width = src.getWidth();
int height = src.getHeight();
Bitmap dest = Bitmap.createBitmap(width, height,
Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(dest);
Paint paint = new Paint();
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0); //value of 0 maps the color to gray-scale
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
paint.setColorFilter(filter);
canvas.drawBitmap(src, 0, 0, paint);
return dest;
}
/** Decodes the Bitmap from 'path' and returns it */
public static Bitmap getImage(String path) {
Bitmap bitmapFromPath = null;
try {
bitmapFromPath = BitmapFactory.decodeFile(path);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return bitmapFromPath;
}
}
Let's look at them in detail:
- resizeImage -> this method takes in input a Bitmap and return it scaled
- createGrayScale -> this method takes as input a Bitmap and return it in grayscale. To be able to draw something we need the
drawBitmap
method of canvas class; this method need to work :
- A Bitmap object to hold the pixels
- A Rect object to represent the subset of the bitmap to be drawn
- A Rect object to represent that the bitmap will be scaled/translated to fit into
- A Paint object to describe the colors and styles for the drawing
We use the colorMatrixsetSaturation
method (set to 0 to map the grayscale) as filter for a paint ('it holds the style and color information about how to draw geometries, text and bitmaps' as described by the Android reference) object type. We finally pass it to the canvas object and get our black an white image
- getImage -> this method takes in input a String and return a Bitmap value from that path
Eigenfaces Class and Task
To manage the eigenfaces computation we are gonna work with asynchronous task. Let' see how an asynchronous task work
- Asynchronous Task
- The Android AsyncTask class allows you to perform background processing and then show the results on the UI of the main tread. It is usually used to perform short-term operations. Each asynchronous processing consists of about 4 steps that android executes consecutively and are :
-onPreExecute
: all the operations before the task;
-doInBackground
: the operations that the task must do;
-onProgressUpdate
: used to show the progress of the task;
-onPostExecute
: operations to be performed after the task;
So, first, let's create a class that extends and overrides the AsyncTask methods by calling it, then we are gonna need a constructor for our class ( we will also use in the code the two previuosly created classes ); finally we are going to call all the four steps of which we have spoken above
public class Eigenfaces extends AsyncTask <Context, Integer, Boolean> {
private Database db ;
private int imageSize;
private double M;
EigenfacesResultTask mCallback = null;
ProgressDialog myProgress = null;
private Context mContext;
public Eigenfaces(Context _context, Database db, int imageSize, EigenfacesResultTask myEFRT) {
mContext = _context;
this.db = db;
this.imageSize = imageSize;
this.M = 25; // number of database images
this.mCallback = myEFRT;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
//some code here ...
}
@Override
protected Boolean doInBackground(Context... params) {
//some code here ...
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
//some code here ...
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
//some code here ...
}
}
We can now go deeper in the code; we have to deal with the images, manipulate them. First of all, let's consider an image as a 'n x m' matrix, in our case we will have a square matrix of order 256, where each element of the matrix is composed by a value from 0 to 255 (the images are black and white). Called I1 the image of the first subject, we have a 256 x 256 matrix that we want to represent as a unique concatenated column vector that we are going to call Γ1 . So, let's add a method inside the Image class that take as input a Bitmap (matrix) and return a concatenated column vector of that image :
public static double[] getColumnVectorOfImage(Bitmap src, int imageSize){
Bitmap bitmap = src; // assign your bitmap here
int pixelCount = 0;
double[] bitmap_column = new double[imageSize];
for (int y = 0; y < bitmap.getHeight(); y++)
{
for (int x = 0; x < bitmap.getWidth(); x++)
{
int c = bitmap.getPixel(x,y); // the value returned is in two's complement so negative is OK
int A = (c >> 24) & 0xff;
int R = (c>> 16) & 0xff;
int G = (c >> 8) & 0xff;
int B = (c ) & 0xff;
int color = (A+R+G+B) / 4;
bitmap_column[pixelCount] = color;
pixelCount++;
}
}
return bitmap_column;
}
Iterate the process for all the images of our database and put all of them in a new set called S = {Γ1, Γ2, ..., ΓM}, where M is the number of all the database images.
What it is interests for us it is to consider the difference between each subject face of the database. So we need to calculate a new array that represent the face average , let's call it Ψ = (1/M) Σ Γi , where the sum goes from i= 1 to M).
Let's translate it into code as a new method that we will call calculateFaceAverage
for the Eigenfaces class (must be after the last step of the asynchronous call); it will take as input argument the set of all column arrays and the size of our image and it will return the array of face average as a double type :
private double[] calculateFaceAverage(int imageSize, List<double[]> set) {
double[] psi = new double[imageSize * imageSize];
for (int j = 0; j < imageSize * imageSize; j++) {
for (int k = 0; k < set.size(); k++) {
psi[j] += (1 / M) * set.get(k)[j];
}
}
return psi;
}
Go on considering again Γ1 and subtract to it the face average array
Φ1 = Γ1 - Ψ
Repeating the process for each face, focusing on the characteristic that make unique each subjet, we will obtain a new database. We store it in a 'n 2 x M' matrix. Called that matrix A , it will be the data set who will constitute our training set:
A = [Φ1, Φ2, ..., ΦM]
Let's do it through the code by adding a new method called subtractFaceAverageToAnImage
that will simply do the subtraction of two array element by element, adding the result to the A matrix of which we have spoken above
private double[][] subtractFaceAverageToAnImage(List<double[]> set, double[] phi) {
double[][] set_less_face_average = new double[set.size()][set.get(0).length];
for (int i = 0; i < set.size(); i++) {
for (int j = 0; j < set.get(i).length; j++) {
set_less_face_average[i][j] = set.get(i)[j] - phi[j];
}
}
return set_less_face_average;
}
The A space has n2 dimension, we have to reduce it by keeping the information of data dispersion intact. Let's build the covariance matrix:
C = (1/M) Σ Φ ΦT
where the sum goes from n = 1 to M and both of Φ are Φ n
It is easy to demonstrate that :
C = (1/M) A A T
To look for the main components of the space, we can look for the eigenvectors of C in order to reduce the computational cost. After calculating the eigenvalues of A A T , we can order them in descending order according to the eigenvectors associated with them. The eigenvectors (which we will also call eigenfaces ) associated with the larger eigenvalues will be the ones that most characterize the variance of the training set
To code this part we have made five different functions:
- transposeMatrix
: it computes the transposed of a matrix
- productOfTwoMatrix
: it computes the product of two matrix
- multiplyMatrixForANumber
: it multiplies each element of a matrix by a number
- productOfMatrixAndMatrixTranspose
: it computes the product AAT
- calculateEingenvalues
: it computes the eigenvalues
- calculateEingenvector
: it computes the eigenvector associated to the eigenvalues
private static double[][] transposeMatrix(double[][] m) {
double[][] temp = new double[m[0].length][m.length];
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[0].length; j++) {
temp[j][i] = m[i][j];
}
}
return temp;
}
private static double[][] productOfTwoMatrix(double[][] m1, double[][] m2) {
int m1_col = m1[0].length; // m1 columns length
int m1_row = m1.length; // m1 row length
int m2_col = m2[0].length; // m2 columns length
int m2_row = m2.length; // m2 row length
double[][] mResult = new double[m1_row][m2_col];
// check if it is possible to do matrix multiplication
if (m1_col != m2_row) {
return null;
} else {
for (int i = 0; i < m1_row; i++) {
for (int j = 0; j < m2_col; j++) {
for (int k = 0; k < m1_col; k++) {
mResult[i][j] += m1[i][k] * m2[k][j];
}
}
}
}
return mResult;
}
private static double[][] multiplyMatrixForANumber(double[][] m, double p) {
int m_col = m[0].length; // m1 columns length
int m_row = m.length; // m1 row length
double[][] mResult = new double[m_row][m_col];
for (int i = 0; i < m_row; i++) {
for (int j = 0; j < m_col; j++) {
mResult[i][j] = p * m[i][j];
}
}
return mResult;
}
public static double[][] productOfMatrixAndMatrixTranspose(double[][] set) {
double[][] covarianceMatrix = null;
double[][] set_transposed = transposeMatrix(set);
covarianceMatrix= (productOfTwoMatrix(set_transposed,set));
return covarianceMatrix;
}
public double[][] getEigenvaluesMatrix(double[][] m )
{
// construct a matrix from a copy of a 2-D array
Matrix A = constructWithCopy(m);
EigenvalueDecomposition e = A.eig();
// the block diagonal eigenvalues matrix
Matrix diagonal_eigenvalues_matrix = e.getD();
double temp_eigenvalues[][] = diagonal_eigenvalues_matrix.getArray();
return temp_eigenvalues;
}
public double[][] getEigenvectorsMatrix(double[][] m )
{
// construct a matrix from a copy of a 2-D array
Matrix A = constructWithCopy(m);
EigenvalueDecomposition e = A.eig();
// the eigenvector matrix
Matrix eigenvectors_matrix = e.getV();
double temp_eigenvectors[][] = eigenvectors_matrix.getArray();
return temp_eigenvectors;
}
- JAMA Library
- For the latest piece of code above, we have used an external library called JAMA ( that it can be easily downloadable at the following link -> JAMA ). The process to achieve our target is:
1. Use theconstructWithCopy
method to construct a matrix object by coping the input 2-D array;
2. create anEigenvalueDecomposition
object that construct the eigenvalue decomposition structure to access D and V;
3. compute the block diagonal matrix of eigenvalues by getting it from the previous structure withgetD()
;
4. compute the eigenvector matrix by getting it again from the eigenvalue decomposition structure withgetV()
;
5. finally we are gonna to convert it from a matrix object to a 2-d array with the methodgetArray()
.
Now it is possible to reduce the space dimension of our faces. In order to do that we have to chose a treshold value below which will be removed all the eigenfaces. [...] This part will be omitted in our application because of the small dimension of the initial dataset.
We can finally take our starting database's faces and project them in a new space in a way that each one is linear combination of the other 25 eigenfaces. Let's consider Φ1 which is the first subject less the face average and stored in the starting database, we want to project it in the new space. Let's call uk, where k go from 1 to 25, the eigenvectors corresponding to the eigenfaces. We will have:
ak,1 = uTk Φ1
Where ak,1 represents the k-th project's coefficient of the first subject and uki is the i-th components of uk (where i goes from 1 to 65536). At this point, the projection of Φ1 can be written as linear combination of the eigenfaces:
a1,1 u1 + a2,1 u2 + ... + a25,1 u25
Iterating this process again for each faces of our starting database, we will get their position into the space of the faces and we can start the facial recognition process. The matrix of projection coefficients of all faces will be composed from all the values of ak,i where the k-th values and the i-th does match in our case and it is equal to 25.
Following the code needed to compute it:
// m1 : Image less face average matrix
// m2 : eigenVectors matrix
public static double[][] calculateProjectionCoefficients(double[][] m1, double[][] m2){
int m1_col = m1[0].length; // m1 columns length
int m1_row = m1.length; // m1 row length
int m2_col = m2[0].length; // m2 columns length
int m2_row = m2.length; // m2 row length
double[][] coefficients = new double[m1_row][m2_row];
double[] phi = new double[m1_col];
double[] u = new double[m2_col];
for (int i = 0; i < m1_row; i++) {
for (int p = 0; p < m1_col; p++) {
// temp value for phi[i]; each time one row is stored
phi[p] = m1[i][p];
}
for(int j=0; j < m2_row; j++) {
for(int k=0; k < m2_col; k++){
// temp value for
u[k] = m2[j][k];
}
coefficients[i][j] = productOfTwoArray(u, phi);
}
}
coefficients = transposeMatrix(coefficients);
return coefficients;
}
public static double[][] calculateEigenfacesProjection(double[][] m1, double[][] m2, double[][] coefficients){
int m1_col = m1[0].length; // m1 columns length
int m1_row = m1.length; // m1 row length
double[][] result = new double[m1_row][m1_col];
result = productOfTwoMatrix(coefficients, m2);
return result;
}
We can now add all the pieces written above together and finally get out our eigenfaces calculation process. Let's analyze the code:
- Eigenfaces
: the constructor, it takes as input the context, the image size and an EigenfacesResultTask object to bring out the scope the final result that we will pass to the facial recognition function
- onPreExecute()
: it just displays out when the process starts
- doInBackground
: it computes the eigenfaces , saving them as pictures into the "Training_DB" folder and return through the EigenfacesResultTask interface the face average, the eigenvectors matrix and the projection coefficients matrix
- onPostExecute
: it displays out a Toast whenever the database is successfully created or not
- saveToDatabase
: this function simply transform the face's projection matrix into '.png' files
public class Eigenfaces extends AsyncTask <Context, Integer, Boolean> {
private EigenfacesResultTask mCallback = null;
private Database db = null;
private int imageSize;
private double M;
ProgressDialog myProgress = null;
private Context mContext;
public Eigenfaces(Context _context, int imageSize, EigenfacesResultTask myEFRT) {
mContext = _context;
this.imageSize = imageSize;
this.M = 25; // number of database images
this.mCallback = myEFRT;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
CharSequence text = "Start Eigenfaces Computation Process";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(mContext, text, duration);
toast.setGravity(Gravity.BOTTOM| Gravity.CENTER, 0, 200);
toast.show();
}
@Override
protected Boolean doInBackground(Context... params) {
List<double[]> s = new ArrayList<>(); // to store all the transposed images
double[] face_average = null; // face average array
double[][] s_less_face_average = null; // image less face average matrix
double[][] s_less_face_average_transpose = null; // image less face average matrix transpose
double[][] covarianceMatrix = null; // A^T * A
double[][] eigenvectorsMatrix_temp = null; // the eigenvectors matrix temp
double[][] eigenvaluesMatrix_temp = null; // the eigenvalues matrix
double[][] eigenvectorsMatrix_transpose = null; // the eigenvcetors matrix trasponse
double[][] eigenvectorsMatrix = null; // the eigenvectors matrix final
double[][] projection_coefficients; // the matrix of project coefficients
double[][] face_projection_matrix; // the face projection matrix
String folder_path = Environment.getExternalStorageDirectory() + "/APP/DB_bw/";
String image_path = null;
File directory = new File(folder_path);
File[] files = directory.listFiles();
if (files != null) {
for (int i = 0; i < files.length; i++) {
image_path = folder_path + files[i].getName().toString();
Bitmap image = Image.getImage(image_path);
// transpose the image into a column vector
double[] image_column = Image.getColumnVectorOfImage(image, 256 * 256);
// create the set S
s.add(image_column);
}
/** calculate average face */
face_average = calculateFaceAverage(256, s, M);
/** subtract face average to each image => A */
s_less_face_average_transpose = subtractFaceAverageToAnImage(s , face_average);
s_less_face_average = transposeMatrix(s_less_face_average_transpose);
/** calculate covariance matrix => A x A^T */
covarianceMatrix = productOfMatrixAndMatrixTranspose(s_less_face_average);
/** calculate the eigenvcetors and eigenvalues of A x A^T */
eigenvaluesMatrix_temp = getEigenvaluesMatrix(covarianceMatrix);
eigenvectorsMatrix_temp = getEigenvectorsMatrix(covarianceMatrix);
/** calculate Au */
eigenvectorsMatrix_transpose = productOfTwoMatrix(s_less_face_average, eigenvectorsMatrix_temp);
eigenvectorsMatrix = multiplyMatrixForANumber(transposeMatrix(eigenvectorsMatrix_transpose), 1/M);
/** compute face projection */
projection_coefficients = calculateProjectionCoefficients(transposeMatrix(s_less_face_average), eigenvectorsMatrix);
face_projection_matrix = calculateEigenfacesProjection(transposeMatrix(s_less_face_average), eigenvectorsMatrix, projection_coefficients);
// save it into db
saveToDatabase(face_projection_matrix);
mCallback.onTaskComplete(face_average, eigenvectorsMatrix, projection_coefficients);
return true;
}
return false;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
myProgress.setProgress(values[0]);
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if(result==true) {
CharSequence text = "Database Succesfull Created";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(mContext, text, duration);
toast.setGravity(Gravity.BOTTOM | Gravity.CENTER, 0, 200);
toast.show();
}
else
{
CharSequence text = "Database Not Created";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(mContext, text, duration);
toast.setGravity(Gravity.BOTTOM | Gravity.CENTER, 0, 200);
toast.show();
}
}
private static void saveToDatabase(double[][] matrixOfImages) {
Bitmap face_projection = null;
Database db = null;
db = new Database();
double[] column = new double[matrixOfImages[0].length]; // Here I assume a rectangular 2D array!
int index = matrixOfImages.length;
int[] column_final = new int[column.length];
for (int i = 0; i < index; i++) {
for (int j = 0; j < column.length; j++) {
column[j] = matrixOfImages[i][j];
}
double max_value = getMaxArrayValue(column);
double min_value = getMinArrayValue(column);
double scalar_coefficient = 255 / max_value;
for (int k = 0; k < column.length; k++) {
column[k] = column[k];
column[k] = scalar_coefficient * column[k];
}
// cast the Array to int Array
for (int m = 0; m < column_final.length; m++) {
int color = ((int) column[m] & 0xff) << 24 |
((int) column[m] & 0xff) << 16 |
((int) column[m] & 0xff) << 8 |
((int) column[m] & 0xff);
column_final[m] = color;
}
face_projection = Bitmap.createBitmap(column_final, 256, 256, Bitmap.Config.ARGB_8888);
db.createTrainingDatabase(face_projection, i);
}
}
}
Facial Recognition Class and Task
To understand if a new subject is present in the initial database, we have to consider its projection in the new space and calculate the distance compared to the other faces. If the value is close enough to one of the them, the recognition is made. Let's have a look to the process.
First of all we must choose an arbitrary threshold value: all the values below this one will be consider "close" enough to the new space and the image will be recognized as present in the database.
To choose the threshold properly we have to set our final goal; mostly common objectives are:
- Recognize a face in the initial database
- Recognize if a face is present or not in the database
For this project we have chosen to recognize if a face is present or not in our database.
Let's consider a new image 256 x 256 pixels (from now on we will call it Δ) which has the same starting conditions of our database; at this point we project Δ into eigenfaces space.
δk = ukT (Δ - Ψ)
(where k goes from 1 to 25)
In this way we have subtracted the face average Ψ to Δ and we have also calculated the projection coefficients; this gives us the new coordinates of Δ - Ψ into the new space. Let's call Ω the column vector that describes each eigenfaces weight for Δ :
ΩΔ = (δ1, δ2, ..., δ25)
It is now possible to calculate the distance between Δ and the eigenfaces space. We can call ΩΦjT the row vector of projection coefficients of Φj, the j-th image deprived of the face average. Let's consider the Euclidean's distance between the projection of Δ - Ψ and Φj
εj2 = ||ΩΔ - ΩΦj ||2
Let's calculate the distance compared to each faces of the starting database.
ε = min (εj2)
(where the min is calculate from 1 to 25)
At this point there can be two possible outcome:
1. ε > Θ
2. ε < Θ
(1) In this case we have that the Euclidean's distance between the new face's projection and anyone other face of the starting database projected into the eigenfaces space is bigger than the threshold value. That means the new face isn't recognized as present into the database
(2) In this case the facial recognition is achieved. The distance, infact, is less or equal to threshold value and that point out that the subject has been recognized.
Let's analyze the code:
public class FacialRecognition extends AsyncTask<Context, Integer, Boolean> {
private FacialRecognitionResultTask mCallback = null;
private Database db ;
ProgressDialog myProgress = null;
private Context mContext;
private double threshold_min = 0;
private double threshold_max;
private boolean flag = false;
private Bitmap input_pic;
private Bitmap input_pic_bw;
private Bitmap input_pic_bw_resized;
private int M;
private double epsilon;
private double min_epsilon_temp;
private double min_epsilon = Double.MAX_VALUE;
private double[][] epsilon_squared;
private double[] face_average;
private double[] image_less_face_average;
private double[][] eigenvectors_matrix;
private double[] projection_coefficients;
private double[][] projection_coefficients_db;
public FacialRecognition(Context _context, Bitmap pic, Database db, double[] faceAverage, double[][] eigenvectorsMatrix,
double[][] projectionCoefficientsDB, double numberOfPics, double thresholdValue,
FacialRecognitionResultTask myFRRT)
{
mContext = _context;
//this.mCallback = myFCRT;
this.M = (int)numberOfPics;
this.db = db;
this.input_pic = pic;
this.face_average = faceAverage;
this.eigenvectors_matrix = eigenvectorsMatrix;
this.threshold_max = thresholdValue;
this.projection_coefficients_db = projectionCoefficientsDB;
/* myProgress = new ProgressDialog(context);
myProgress.setTitle("Processing Data");
myProgress.setMessage("Please wait...");
myProgress.setMax(100);
myProgress.setIndeterminate(false); */
}
@Override
protected void onPreExecute() {
super.onPreExecute();
CharSequence text = "Start Facial Recognition Process";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(mContext, text, duration);
toast.setGravity(Gravity.BOTTOM| Gravity.CENTER, 0, 200);
toast.show();
}
@Override
protected Boolean doInBackground(Context... params) {
projection_coefficients = new double[M];
String folder_path = Environment.getExternalStorageDirectory() + "/APP/TestImage/";
String filename = null;
File directory = new File(folder_path);
for (File f : directory.listFiles()) {
if (f.isFile())
filename = f.getName();
}
if(threshold_max == 0){
flag = true;
return false;
}
// transpose the image into a column vector (delta)
if ("check_image.jpg".equals(filename)) {
input_pic = Image.rotateImage(input_pic, 270);
}
input_pic_bw = Image.createGrayScale(input_pic);
input_pic_bw_resized = Image.resizeImage(input_pic_bw);
double[] image_column = Image.getColumnVectorOfImage(input_pic_bw_resized, 256 * 256);
image_less_face_average = new double[image_column.length];
// subtract the face average to the image
for (int i = 0; i < image_column.length; i++) {
image_less_face_average[i] = image_column[i] - face_average[i];
}
/**double[][] m1 = convertSingleArrayTo2DMatrix(image_less_face_average, 256);
double[][] m2 = (transposeMatrix(eigenvectors_matrix));
projection_coefficients = productOfTwoMatrix(m1, m2);
**/
for(int i=0; i < M; i++)
{
projection_coefficients[i] = productOfTwoArray(eigenvectors_matrix[i] ,image_less_face_average);
}
epsilon_squared = new double[M][M];
for(int k=0; k < M; k++)
{
epsilon_squared[k] = calculateEuclideanDistance(projection_coefficients, projection_coefficients_db[k]);
min_epsilon_temp = getMinArrayValue(epsilon_squared[k]);
if(min_epsilon_temp < min_epsilon)
min_epsilon = min_epsilon_temp;
}
//epsilon = checkValue(min_epsilon);
epsilon = min_epsilon * Math.pow(10, 20);
if (epsilon > threshold_min && epsilon < threshold_max)
return true;
else
return false;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
myProgress.setProgress(values[0]);
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if(result==true) {
CharSequence text = "Your face match with the db. UNLOCK!\n" + "\t\t\t\t\t\t\t\t\t\t Epsilon: " + (int)epsilon;
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(mContext, text, duration);
toast.setGravity(Gravity.BOTTOM | Gravity.CENTER, 0, 200);
toast.show();
}
else
{
if (flag == true) {
CharSequence text = "Please select a valid SeekBar Value";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(mContext, text, duration);
toast.setGravity(Gravity.BOTTOM | Gravity.CENTER, 0, 200);
toast.show();
}
else{
CharSequence text = "Your face doesn't match with the db. Still LOCK. Try again.\n" + "\t\t\t\t\t\t\t\t\t\t Epsilon: " + (int)epsilon;
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(mContext, text, duration);
toast.setGravity(Gravity.BOTTOM | Gravity.CENTER, 0, 200);
toast.show();
}
}
}
}
public static double[] calculateEuclideanDistance(double[] a1, double[] a2){
double[] aResult = new double[a1.length];
for (int i = 0 ; i < a1.length ; i++)
{
aResult[i] = Math.pow(Math.abs(a1[i] - a2[i]), 2);
}
return aResult;
}
Camera Task
In order to capture a picture from our backfront camera, we are gonna use CAMERA 2 API .
It's important to notice that this API will only work with minSdkVersion: 21
or above; open the build.gradle file to check your currente version. First of all, we need to add the missing permission in the manifest adding this line of code:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.hardware.camera2.full"/>
Then we add TextureView
that it will manage the real time camera preview.
<TextureView
android:id="@+id/textureView"
android:layout_width="match_parent"
android:layout_height="match_parent"
<EMAIL_ADDRESS>Finally in order to gain some more space, we remove the top ActionBar by modifying the styles.xml file (res -> values)
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
Finally we can add the code on the main of our application :
private TextureView textureView;
// Check state orientation of output image
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
private String cameraId;
private CameraDevice cameraDevice;
private CameraCaptureSession cameraCaptureSessions;
private CaptureRequest.Builder captureRequestBuilder;
private Size imageDimension;
private ImageReader imageReader;
//Save to FILE
private File file;
private static final int REQUEST_CAMERA_PERMISSION = 200;
private boolean mFlashSupported;
private Handler mBackgroundHandler;
private HandlerThread mBackgroundThread;
CameraDevice.StateCallback stateCallBack = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
cameraDevice = camera;
createCameraPreview();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
cameraDevice.close();
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
cameraDevice.close();
cameraDevice = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
initListeners();
assert textureView != null;
textureView.setSurfaceTextureListener(textureListener);
}
/**
* This method is to initialize views
*/
private void initViews() {
textureView = (TextureView)findViewById(R.id.textureView);
btn_Training = (Button) findViewById(R.id.btn_training);
}
/**
* This method is to initialize listeners
*/
private void initListeners() {
btn_Take_Picture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
takePicture();
}
});
}
private void takePicture() {
if(cameraDevice == null)
return;
CameraManager manager = (CameraManager)getSystemService(Context.CAMERA_SERVICE);
try{
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
Size[] jpegSizes = null;
if(characteristics != null)
jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
.getOutputSizes(ImageFormat.JPEG);
// Capture image with custom size
int width = 640;
int height = 480;
if(jpegSizes != null && jpegSizes.length > 0)
{
width = jpegSizes[0].getWidth();
height = jpegSizes[0].getHeight();
}
ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
List<Surface> outputSurface = new ArrayList<>(2);
outputSurface.add(reader.getSurface());
outputSurface.add(new Surface(textureView.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(reader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
// Check orientation base on device
int rotation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, rotation);
// save the image
dir = new File(Environment.getExternalStorageDirectory()+ "/APP/TestImage/");
dir.mkdirs();
file = new File(Environment.getExternalStorageDirectory()+ "/APP/TestImage/check_image.jpg");
ImageReader.OnImageAvailableListener readListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
try{
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
}
catch (FileNotFoundException e){
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}
finally {
{
if(image != null)
image.close();
}
}
}
private void save(byte[] bytes) throws IOException {
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file);
outputStream.write(bytes);
}finally {
if(outputStream != null)
outputStream.close();
}
}
};
reader.setOnImageAvailableListener(readListener, mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
Toast.makeText(MainActivity.this,"Saved " + file,Toast.LENGTH_SHORT).show();
createCameraPreview();
}
};
cameraDevice.createCaptureSession(outputSurface, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
try {
session.capture(captureBuilder.build(), captureListener,mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
}
},mBackgroundHandler);
}catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void createCameraPreview() {
try{
SurfaceTexture texture = textureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
Surface surface = new Surface(texture);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(surface);
cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
if(cameraDevice == null)
return;
cameraCaptureSessions = session;
updatePreview();
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
Toast.makeText(MainActivity.this, "Changed", Toast.LENGTH_SHORT).show();
}
},null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void updatePreview() {
if(cameraDevice == null)
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
try{
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void openCamera() {
CameraManager manager = (CameraManager)getSystemService(Context.CAMERA_SERVICE);
try {
// change [0] = FRONT_CAMERA or [1] = BACK CAMERA
cameraId = manager.getCameraIdList()[1];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assert map != null;
imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];
// Check realtime permission if run higher API 23
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, REQUEST_CAMERA_PERMISSION);
return;
}
manager.openCamera(cameraId, stateCallBack, null );
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
openCamera();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
};
// Ctrl + O
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if(requestCode == REQUEST_CAMERA_PERMISSION)
{
if(grantResults[0] != PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this, " You can't use camera without permission", Toast.LENGTH_SHORT).show();
finish();
}
}
}
@Override
protected void onResume() {
super.onResume();
startBackgroundThead();
if(textureView.isAvailable())
openCamera();
else
textureView.setSurfaceTextureListener(textureListener);
}
@Override
protected void onPause() {
stopBackgroundThread();
super.onPause();
}
private void stopBackgroundThread() {
mBackgroundThread.quitSafely();
try {
mBackgroundThread.join();
mBackgroundThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void startBackgroundThead() {
mBackgroundThread = new HandlerThread("Camera Background");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}


2 Timothy 2:21
If a man therefore purge himself from these, he shall be a vessel unto honour, sanctified, and meet for the master's use, and prepared unto every good work.


A dashboard supports the usage of 'cromwell'. 'Cromwell' is a scientific workflow engine for command line users. This package utilizes 'cromwell' REST APIs and provides these convenient functions: timing diagrams for running workflows, 'cromwell' engine status, a tabular workflow list. For more information about 'cromwell', visit <http://cromwell.readthedocs.io>.
| Version: | 0.5.1 |
| Imports: | shiny, shinydashboard, stringr, httr, dplyr, DT |
| Published: | 2018-08-02 |
| Author: | Xiaowei Zhan |
| Maintainer: | Xiaowei Zhan <zhanxw at gmail.com> |
| License: | GPL-3 |
| NeedsCompilation: | no |
| Materials: | README |
| CRAN checks: | cromwellDashboard results |
| Reference manual: | cromwellDashboard.pdf |
| Package source: | cromwellDashboard_0.5.1.tar.gz |
| Windows binaries: | r-devel: cromwellDashboard_0.5.1.zip, r-release: cromwellDashboard_0.5.1.zip, r-oldrel: cromwellDashboard_0.5.1.zip |
| OS X binaries: | r-release: cromwellDashboard_0.5.1.tgz, r-oldrel: cromwellDashboard_0.5.1.tgz |
Please use the canonical form https://CRAN.R-project.org/package=cromwellDashboard to link to this page.


Submission Complete
Your Emergency Support Services File Number is: {{ registrationNumber }}
Thank you for submitting your online self-registration.
Next Steps
- Please keep a record of your Emergency Support Services File Number to receive emergency support services that can be provided up to 72 hours starting from the time connecting in with a local ESS Responder at a Reception Centre.
- After a need's assessment interview with a local ESS Responder has been completed, supports are provided to purchase goods and services if eligible.
- Any goods and services purchased prior to a need's assessment interview are not eligible for retroactive reimbursement.
- If you are under EVACUATION ALERT or DO NOT require emergency serves at this time, no further action is required.
- If you are under EVACUATION ORDER, and require emergency supports, proceed to your nearest Reception Centre. A list of open Reception Centres can be found at Emergency Info BC.
- If NO nearby Reception Centre is open and immediate action is required, please contact your Local Emergency Program for next steps.


Aspinall Leadership Team
| Form Class | Form Teacher | Student Leader |
|---|---|---|
| AP1 | Stefan Reussenzehn | Ayoub Ahmad |
| AP2 | Michael Hall | Cody Thomson |
| AP3 | Kate Hope | Joshua Leebody |
| AP4 | Richard Roe | Jack Maffey |
| AP5 | Michael South | Angus Faulks |
| AP6 | Nicole Bennett | Bradey Findlater |
| AP7 | Justin Zani | Peter Rowe |


Images are very important to beautify as well as to depict many complex concepts in simple way on your web page. This tutorial will take you through simple steps to use images in your web pages.
You can insert any image in your web page by using  tag. Following is the simple syntax to use this tag.

The  tag is an empty tag, which means that, it can contain only list of attributes and it has no closing tag.
To try following example, let's keep our HTML file test.htm and image file test.png in the same directory −
<!DOCTYPE html>   <title>Using Image in Webpage</title>
Simple Image Insert

You can use PNG, JPEG or GIF image file based on your comfort but make sure you specify correct image file name in src attribute. Image name is always case sensitive.
The alt attribute is a mandatory attribute which specifies an alternate text for an image, if the image cannot be displayed.
Usually we keep all the images in a separate directory. So let's keep HTML file test.htm in our home directory and create a subdirectory images inside the home directory where we will keep our image test.png.
Assuming our image location is "image/test.png", try the following example −
<!DOCTYPE html>   <title>Using Image in Webpage</title>
Simple Image Insert
   »
You can set image width and height based on your requirement using width and height attributes. You can specify width and height of the image in terms of either pixels or percentage of its actual size.
<!DOCTYPE html>   <title>Set Image Width and Height</title>
Setting image width and height
   »
By default, image will have a border around it, you can specify border thickness in terms of pixels using border attribute. A thickness of 0 means, no border around the picture.
<!DOCTYPE html>   <title>Set Image Border</title>
Setting image Border
   »
By default, image will align at the left side of the page, but you can use align attribute to set it in the center or right.
<!DOCTYPE html>   <title>Set Image Alignment</title>
Setting image Alignment
   »


4.1.6 Checking for a Package Configuration
The check_cfg method can be used to check for the existence of a package as
well as import any build options (e.g. include path, defines, libraries to link
against, etc...) required to use the package.
This method takes a Hash of options as its only argument.
Example calls:
configure do
check_cfg package: "zlib"
check_cfg program: "freetype-config", fail: false, set_define: "HAVE_FREETYPE"
end
<IP_ADDRESS> Options
<IP_ADDRESS>.1 :package
If the :package option is set to a value, the pkg-config program will be
used to look for package configuration flags for the specified package.
<IP_ADDRESS>.2 :program
If the :program option is given, the program specified will be used to look
for configuration flags.
<IP_ADDRESS>.3 :fail
If the :fail option is set to false , then the absence of the package or
program requested will not result in the configure option failing.
The :fail option defaults to true if the :set_define option is not
defined, and defaults to false if the :set_define option is defined.
<IP_ADDRESS>.4 :set_define
If set, a build define of the specified String will be added to the
CPPDEFINES construction variable array if the requested package is found.
<IP_ADDRESS>.5 :use
If not set, the library will be used by default in all Environment objects.
If set, the library will only be used in Environment objects that have a
matching :use flag set.
|


Require forgeries at the bottom of the file so Forgery works as a gem both within rails and outside of it.
Required Files
- forgery/file_reader
- forgery/dictionaries
- forgery/formats
- forgery/extend
- forgery/forgery
- forgery/version
- forgery/forgery_api
- forgery/forgery_railtie


2.4 The Least Squares Assumptions
OLS performs well under a quite broad variety of different circumstances. However, there are some assumptions which need to be satisfied in order to ensure that the estimates are normally distributed in large samples (we discuss this in Chapter @ref{tsdotoe}).
Key Concept 4.3
The Least Squares Assumptions
\[Y_i = \beta_0 + \beta_1 X_i + u_i \text{, } i = 1,\dots,n\] where
- The error term \(u_i\) has conditional mean zero given \(X_i\): \(E(u_i|X_i) = 0\).
- \((X_i,Y_i), i = 1,\dots,n\) are independent and identically distributed (i.i.d.) draws from their joint distribution.
- Large outliers are unlikely: \(X_i\) and \(Y_i\) have nonzero finite fourth moments.
Assumption 1: The Error Term has Conditional Mean of Zero
This means that no matter which value we choose for \(X\), the error term \(u\) must not show any systematic pattern and must have a mean of \(0\). Consider the case that, unconditionally, \(E(u) = 0\), but for low and high values of \(X\), the error term tends to be positive and for midrange values of \(X\) the error tends to be negative. We can use R to construct such an example. To do so we generate our own data using R’s built-in random number generators.
We will use the following functions:
- runif() - generates uniformly distributed random numbers
- rnorm() - generates normally distributed random numbers
- predict() - does predictions based on the results of model fitting functions like lm()
- lines() - adds line segments to an existing plot
We start by creating a vector containing values that are uniformly distributed on the interval \([-5,5]\). This can be done with the function runif(). We also need to simulate the error term. For this we generate normally distributed random numbers with a mean equal to \(0\) and a variance of \(1\) using rnorm(). The \(Y\) values are obtained as a quadratic function of the \(X\) values and the error.
After generating the data we estimate both a simple regression model and a quadratic model that also includes the regressor \(X^2\) (this is a multiple regression model, see Chapter ??). Finally, we plot the simulated data and add a the estimated regression line of a simple regression model as well as the predictions made with a quadratic model to compare the fit graphically.
# set a seed to make the results reproducible
set.seed(321)
# simulate the data
X <- runif(50, min = -5, max = 5)
u <- rnorm(50, sd = 5)
# the true relation
Y <- X^2 + 2 * X + u
# estimate a simple regression model
mod_simple <- lm(Y ~ X)
# predict using a quadratic model
prediction <- predict(lm(Y ~ X + I(X^2)), data.frame(X = sort(X)))
# plot the results
plot(Y ~ X)
abline(mod_simple, col = "red")
lines(sort(X), prediction)
The plot shows what is meant by \(E(u_i|X_i) = 0\) and why it does not hold for the linear model:
Using the quadratic model (represented by the black curve) we see that there are no systematic deviations of the observation from the predicted relation. It is credible that the assumption is not violated when such a model is employed. However, using a simple linear regression model we see that the assumption is probably violated as \(E(u_i|X_i)\) varies with the \(X_i\).
Assumption 2: Independently and Identically Distributed Data
Most sampling schemes used when collecting data from populations produce i.i.d.-samples. For example, we could use R’s random number generator to randomly select student IDs from a university’s enrollment list and record age \(X\) and earnings \(Y\) of the corresponding students. This is a typical example of simple random sampling and ensures that all the \((X_i, Y_i)\) are drawn randomly from the same population.
A prominent example where the i.i.d. assumption is not fulfilled is time series data where we have observations on the same unit over time. For example, take \(X\) as the number of workers in a production company over time. Due to business transformations, the company cuts job periodically by a specific share but there are also some non-deterministic influences that relate to economics, politics etc. Using R we can easily simulate such a process and plot it.
We start the series with a total of 5000 workers and simulate the reduction of employment with an autoregressive process that exhibits a downward movement in the long-run and has normally distributed errors:3
\[ employment_t = -5 + 0.98 \cdot employment_{t-1} + u_t \]# set seed
set.seed(123)
# generate a date vector
Date <- seq(as.Date("1951/1/1"), as.Date("2000/1/1"), "years")
# initialize the employment vector
X <- c(5000, rep(NA, length(Date)-1))
# generate time series observations with random influences
for (i in 2:length(Date)) {
X[i] <- -50 + 0.98 * X[i-1] + rnorm(n = 1, sd = 200)
}
#plot the results
plot(x = Date,
y = X,
type = "l",
col = "steelblue",
ylab = "Workers",
xlab = "Time")
It is evident that the observations on the number of employees cannot be independent in this example: the level of today’s employment is correlated with tomorrows employment level. Thus, the i.i.d. assumption is violated.
Assumption 3: Large Outliers are Unlikely
It is easy to come up with situations where extreme observations, i.e., observations that deviate considerably from the usual range of the data, may occur. Such observations are called outliers. Technically speaking, assumption 3 requires that \(X\) and \(Y\) have a finite kurtosis.4
Common cases where we want to exclude or (if possible) correct such outliers is when they are apparently typos, conversion errors or measurement errors. Even if it seems like extreme observations have been recorded correctly, it is advisable to exclude them before estimating a model since OLS suffers from sensitivity to outliers.
What does this mean? One can show that extreme observations receive heavy weighting in the estimation of the unknown regression coefficients when using OLS. Therefore, outliers can lead to strongly distorted estimates of regression coefficients. To get a better impression of this issue, consider the following application where we have placed some sample data on \(X\) and \(Y\) which are highly correlated. The relation between \(X\) and \(Y\) seems to be explained pretty good by the plotted regression line: all of the blue dots lie close to the red line and we have \(R^2=0.92\).
Now go ahead and add a further observation at, say, \((18,2)\). This observations clearly is an outlier. The result is quite striking: the estimated regression line differs greatly from the one we adjudged to fit the data well. The slope is heavily downward biased and \(R^2\) decreased to a mere \(29\%\)!
Double-click inside the coordinate system to reset the app. Feel free to experiment. Choose different coordinates for the outlier or add additional ones.
The following code roughly reproduces what is shown in figure 4.5 in the book. As done above we use sample data generated using R’s random number functions rnorm() and runif(). We estimate two simple regression models, one based on the original data set and another using a modified set where one observation is change to be an outlier and then plot the results. In order to understand the complete code you should be familiar with the function sort() which sorts the entries of a numeric vector in ascending order.
# set seed
set.seed(123)
# generate the data
X <- sort(runif(10, min = 30, max = 70))
Y <- rnorm(10 , mean = 200, sd = 50)
Y[9] <- 2000
# fit model with outlier
fit <- lm(Y ~ X)
# fit model without outlier
fitWithoutOutlier <- lm(Y[-9] ~ X[-9])
# plot the results
plot(Y ~ X)
abline(fit)
abline(fitWithoutOutlier, col = "red")


protected static final String |
GENERIC_ERROR |
"Generic error: %s" |
protected static final String |
INVALID_ENCODING |
"Encoding not accepted: %s" |
protected static final String |
INVALID_RECIPIENT |
"Invalid TO address: %s" |
protected static final String |
INVALID_REPLYTO |
"Invalid REPLY TO address: %s" |
protected static final String |
INVALID_SENDER |
"Invalid FROM address: %s" |
protected static final String |
MISSING_CONTENT |
"Email is not valid: missing content body" |
protected static final String |
MISSING_HOST |
"Can\'t send an email without host" |
protected static final String |
MISSING_RECIPIENT |
"Email is not valid: missing recipients" |
protected static final String |
MISSING_SENDER |
"Email is not valid: missing sender" |
protected static final String |
MISSING_SUBJECT |
"Email is not valid: missing subject" |
protected static final String |
MISSING_USERNAME |
"Can\'t have a password without username" |


Local or Remote Data Source
The data in the grid might come from a local or remote data source. If you define
grid.url
property, the grid will assume that your data source is remote. Otherwise, the data source is local (all records are stored in
grid.records) array. If data source is remote, the grid will:
- Pull records from the server on render
- Pull records from the server on reload
- Pull more records when user scrolls (if needed)
- Submit search to the server (user types in a search field)
- Submit sort to the server (user click on the column)
- Submit delete when user clicks and confirms delete operation
- Submit save when user clicks the save button
Below is the example of the grid with local data source.


Vim documentation: pi_spec
main help file*pi_spec.txt* For Vim version 7.2. Last change: 2006 Apr 24 by Gustavo Niemeyer This is a filetype plugin to work with rpm spec files. Currently, this Vim plugin allows you to easily update the %changelog section in RPM spec files. It will even create a section for you if it doesn't exist yet. If you've already inserted an entry today, it will give you the opportunity to just add a new item in today's entry. If you don't provide a format string (|spec_chglog_format|), it'll ask you an email address and build a format string by itself. 1. How to use it |spec-how-to-use-it| 2. Customizing |spec-customizing|
1. How to use it *spec-how-to-use-it* The spec_chglog plugin provides a map like the following: :map <buffer> <LocalLeader>c <Plug>SpecChangelog It means that you may run the plugin inside a spec file by pressing your maplocalleader key (default is '\') plus 'c'. If you do not have |spec_chglog_format| set, the plugin will ask you for an email address to use in this edit session. Every time you run the plugin, it will check to see if the last entry in the changelog has been written today and by you. If the entry matches, it will just insert a new changelog item, otherwise it will create a new changelog entry. If you are running with |spec_chglog_release_info| enabled, it will also check if the name, version and release matches. The plugin is smart enough to ask you if it should update the package release, if you have not done so. Setting a map *spec-setting-a-map* As you should know, you can easily set a map to access any Vim command (or anything, for that matter). If you don't like the default map of <LocalLeader>c, you may just set up your own key. The following line shows you how you could do this in your .vimrc file, mapping the plugin to the <F5> key: au FileType spec map <buffer> <F5> <Plug>SpecChangelog Note: the plugin will respect your desire to change the default mapping and won't set it. This command will add a map only in the spec file buffers.
2. Customizing *spec-customizing* The format string *spec_chglog_format* You can easily customize how your spec file entry will look like. To do this just set the variable "spec_chglog_format" in your .vimrc file like this: let spec_chglog_format = "%a %b %d %Y My Name<EMAIL_ADDRESS>Note that "%a %b %d %Y" is the most used time format. If you don't provide a format string, when you run the SpecChangelog command for the first time, it will ask you an email address and build the |spec_chglog_format| variable for you. This way, you will only need to provide your email address once. To discover which format options you can use, take a look at the strftime() function man page. Where to insert new items *spec_chglog_prepend* The plugin will usually insert new %changelog entry items (note that it's not the entry itself) after the existing ones. If you set the spec_chglog_prepend variable let spec_chglog_prepend = 1 it will insert new items before the existing ones. Inserting release info *spec_chglog_release_info* If you want, the plugin may automatically insert release information on each changelog entry. One advantage of turning this feature on is that it may control if the release has been updated after the last change in the package or not. If you have not updated the package version or release, it will ask you if it should update the package release for you. To turn this feature on, just insert the following code in your .vimrc: let spec_chglog_release_info = 1 Then, the first item in your changelog entry will be something like: + name-1.0-1cl If you don't like the release updating feature and don't want to answer "No" each time it detects an old release, you may disable it with let spec_chglog_never_increase_release = 1 Good luck!! top - main help file


Daily Digest #11
- Stream & Go: News Feeds for Over 300 Million End Users
- What Really Happened with Vista: An Insider’s Retrospective
- Chrome is turning into the new Internet Explorer 6
- Implications of Tech Stack Complexity for Executives
- Refactoring with Composed Method pattern
- How we design enterprise software
- Tutorial: Distributed Tracing in Ruby with OpenTracing
- Why Factories?
- How do Ruby & Python profilers work?
- Event-Driven Microservices with RabbitMQ and Ruby
- The Ruby 2.5.0 feature nobody talks about
- Asynchronous JavaScript: From Callback Hell to Async and Await
- Building Your First Node App Using Docker
- Paying Technical Debt - How To Rescue Legacy Code through Refactoring
- Announcing The Node.js Application Showcase
- Node v9.4.0 released
Tools & code
- Minimesos
- Redmine Security Scanner
- Polka – micro web server
- [Mongoose 5.0](http://m
Published on January 24, 2018


--- layout: post title: rough sketch date: '2015-09-21T18:30:28+02:00' categories: - Sketches picture_url: https://film-Storyboards.tumblr.com/post/129600581764/rough-sketch ---
Rough sketch.


Justice League's Deathstroke Joins the Call for #ReleaseTheSnyderCut
by Samuel GelmanFirst it was the heroes; now it's the villains.
Joe Manganiello, who cameoed as Deathstroke in Justice League, showed his support for the Snyder Cut with an Instagram post. "#releasethesnydercut," he writes. Accompanying his post is a series of photos from the film, including one Zack Snyder on set directing the scene.
Manganiello is the latest DCEU star to voice his support for the release of Zack Snyder's version of Justice League. Both Gal Gadot and Ben Affleck -- Wonder Woman and Batman -- took to social media to support the movement, as did Ray Fisher, aka Cyborg. Jason Momoa, who portrays Aquaman, demanded its release two weeks ago.
Click the button below to start this article in quick view.
The recent wave of support comes as Justice League celebrates its two-year anniversary. The film opened on Nov. 17, 2017, to mediocre reviews and was a moderate box office success.
Justice League is available digitally and on Blu-ray and DVD. The film stars Ben Affleck as Batman, Gal Gadot as Wonder Woman, Henry Cavill as Superman, Amy Adams as Lois Lane, Jason Momoa as Aquaman, Ezra Miller as The Flash, Ray Fisher as Cyborg, Jeremy Irons as Alfred Pennyworth, Diane Lane as Martha Kent, Ciarán Hinds as Steppenwolf, Jesse Eisenberg as Lex Luthor and J.K. Simmons as Commissioner Gordon.
https://schema.orgBreadcrumbListListItem1Homehttps://www.cbr.com/ListItem2Movieshttps://www.cbr.com/category/movies/ListItem3Movie Newshttps://www.cbr.com/category/movies/news-movies/ListItem4Justice League's Deathstroke Joins the Call for #ReleaseTheSnyderCuthttps://www.cbr.com/justice-league-deathstroke-release-the-snyder-cut/


High Earners
While JavaScript and HTML/CSS enjoy high popularity among
developers, niche programming languages such as Clojure
and F# guarantee a higher salary, but also require more
professional experience.
Entry Level
Programming languages such as Scala, Go, Elixir, Ruby, and
Rust are more favorable for career starters.


This is an implementation of the real-time algorithm Operational Transformation (or OT) written in Erlang. OT is an optimistic concurrency algorithm that lets clients apply operations to a document immediately as they are created, and only synchronizes the changes with the server after they have been made. If another client has altered the document while the first client was making the first operation, we can transform each operation so that the server and every client will converge to the same document state.
-module(ot).
-export([apply/2, transform/2]).
apply(State, {Type, Opts}) ->
apply_op(Type, Opts, State).
na: adds a value to a number.
{<<"na">>, [Path, Number]}
Where Number
is the value to add to the number at Path
.
apply_op(<<"na">>, [[], Number], N) ->
N + Number;
si: inserts a string.
{<<"si">>, [Path, String, Offset]}
Where String
is the text to insert at the index Offset
in the string
located at Path
.
apply_op(<<"si">>, [[], String, Offset], State) ->
<<Prefix:Offset/binary, Suffix/binary>> = State,
<<Prefix/binary, String/binary, Suffix/binary>>;
sd: deletes a string.
{<<"sd">>, [Path, String, Offset]}
Where String
is the text to delete, starting at the index Offset
, in the
string located at Path
.
apply_op(<<"sd">>, [[], String, Offset], State) ->
Size = size(String),
<<Prefix:Offset/binary, String:Size/binary, Suffix/binary>> = State,
<<Prefix/binary, Suffix/binary>>;
sr: replaces a string.
{<<"sr">>, [Path, OldString, NewString, Offset]}
Where NewString
is the text replacing OldString
, starting at Offset
,
in the string located at Path
.
apply_op(<<"sr">>, [[], OldString, NewString, Offset], State) ->
Size = size(OldString),
<<Prefix:Offset/binary, OldString:Size/binary, Suffix/binary>> = State,
<<Prefix/binary, NewString/binary, Suffix/binary>>;
A state is an erlang structure representing a document. It's close to the erlang representation of JSON structures in the jsx project.
In other words a state should respect the following mapping:
number: integer()
or float()
string: binary()
true, false and null: true
, false
and null
array: lists of any type above and/or objects
object: objects are represented by erlang proplists. The empty object
has the special representation [{}]
to differentiate it from the empty
list. The shorthand form of proplists are prohibited and the keys
must be encoded as binaries.
A path is a list of keys and/or indexes describing the location of an object inside a state. Keys traverse objects while indexes traverse arrays.
Example:
The path [<<"x">>, 2, <<"z">>]
would points to <<"value">>
in the
following state:
[{<<"x">>, [1, 2, [{<<"z">>, <<"value">>}]]}]
The equivalent JSON structure of this state would be:
{"x": [1, 2, {"z": "value"}]}
apply_op(Type, [[Key|Keys]|Opts], State) when is_binary(Key) ->
Value = proplists:get_value(Key, State),
NewValue = apply_op(Type, [Keys|Opts], Value),
lists:keyreplace(Key, 1, State, {Key, NewValue});
apply_op(Type, [[Index|Keys]|Opts], State) when is_integer(Index) ->
Value = lists:nth(Index + 1, State),
NewValue = apply_op(Type, [Keys|Opts], Value),
replace(Index, State, NewValue).
transform({<<"si">>, _Opts} = Op2, Op1) ->
transform_s(Op2, Op1);
transform({<<"sd">>, _Opts} = Op2, Op1) ->
transform_s(Op2, Op1).
transform_s({Type2, [Path|Opts2]}, {Type1, [Path|Opts1]}) ->
[String1, Offset1] = Opts1,
[String2, Offset2] = Opts2,
NewOpts =
if
Offset1 =< Offset2, Type1 =:= <<"si">> ->
[String2, Offset2 + size(String1)];
Offset1 =< Offset2, Type1 =:= <<"sd">> ->
[String2, Offset2 - size(String1)];
true -> % noop
[String2, Offset2]
end,
{Type2, [Path|NewOpts]}.
replace(0, [_Head|Tail], Value) ->
[Value|Tail];
replace(Index, [Head|Tail], Value) ->
[Head|replace(Index - 1, Tail, Value)].


Please use the search or navigation to locate the page. But don't let us stop you from continuing to guess blindly if that makes you happy.
(404)


Find the closesnt bike shop to your location!
Pick the service you want.
4 people around you can bake a cake
About this person


I came from here
1254 Patterson Street Houston, TX 77025
(+123)<PHONE_NUMBER> (+123)<PHONE_NUMBER>
www.google.com www.example.com


fun generateSet(owner: Player): List<Piece>
Generates a full set of Pieces for a given Player.
owner - Player
owner
Return A list containing the appropriate number of Pieces per Rank.


[§489N-4] Penalties. (a) Any person who violates this chapter shall be deemed to have engaged in an unfair or deceptive act or practice in the conduct of any trade or commerce within the meaning of section 480-2(a).
(b) A wilful violation of this chapter shall be punishable by a fine of up to $500 and up to thirty days imprisonment. [L 2003, c 149, pt of §1]


Have a question about projects, services, rates, or anything else? Feel free to get in touch and drop us a note.
Monday-Friday
9am-6pm, Central European Time
7am-1pm, U.S. Eastern Time


Pay prototype links
Admin tool prototype with filtering
Admin tool prototype with split refunds and transactions
Old admin prototype (filtering doesn’t work).
Shows double line entries for refunds.
Pay product page
Account creation and sign in also work from here. Click on ‘Not received an email?’ to get past the ‘Check your email’ part of the account creation flow.


We are Basel-based data scientists who have jointly spent over 30 years doing data science with R for both research and industry. We founded The R Bootcamp out of our passion for R and Data Science. Our Team of like-minded R enthusiasts hosts public and in-house Data Science courses in Switzerland and Germany. Our goal is to help you learn the skills needed to discover and communicate insights from data and join the data revolution.
In association with the Advanced Studies, University of Basel, we continuously offer three standalone, complementary courses. For beginners with no R or other programming experience we recommend to first complete R for Data Science. For detailed course description see Upcoming Bootcamps.
Our courses are composed of short, interactive presentations and longer hands-on practicals, during which you will work through step-by-step exercises designed to make you an active user of R. For every 5 participants there will be 1 instructor to ensure personalized support catering to your specific level and needs. Feel free to explore the open materials of our latest and previous courses. If you have any questions don't hesitate to send us a message. To learn about the latest courses, sign up for our mailing list.


click the controll menu below, you can controll crop, hue, brightness, take picture picture list no pictures


| 1 |
Open the
Application |
|
| 2 |
Tap
the "Next" button |
|
| 3 |
Tap
the "Next" button |
|
| 4 |
Tap
the "Next" button |
|
| 5 |
Tap
on the "Disable crash reports" button |
|
| 6 |
Tap
the "Next" button |
|
| 7 |
Tap
the "Done" button |
|
| 8 |
Tap
on the "Menu" button at the top left of the screen |
Select
"Export..." from left tray |
| 9 |
Tap
on the "Export" Menu item |
| 10 |
Tap
on the "Export To" Drpodown Menu |
Select
export to "Google Drive", format QIF, default value for
"Since" |
| 11 |
Tap
on the "Google Drive" Dropdown menu option |
| 12 |
Tap
on the account list item that indicates the Google Drive account you wish to
export to |
|
| 13 |
Tap
on the "Delete transactions after export" checkbox |
Check
"Delete transactions after export" |
| 14 |
Tap
on the "Export" button |
Tap
"EXPORT" |
|
|
|


Quened
1 project
$1500
Planning
4 projects
$4100
-
Landing pageSymu.co $1500
-
New websiteSymu.co $1500
-
Mobile AppSymu.co $1500
Design
4 projects
$5200
-
New websiteSymu.co $1500
-
New websiteSymu.co $1500
Development
3 projects
$4200
-
Mobile AppSymu.co $1500
-
New websiteSymu.co $1500
Testing
1 project
$1500
-
Landing pageSymu.co $1500
Completed
3 projects
$3700
-
Landing pageSymu.co $1500
-
New websiteSymu.co $1500