Thoms Kühne<EMAIL_ADDRESS>Kinaseblender uses a heuristic search algorithm to find those combination of producers that produce the the maximum number of different products. For example, when used for experiment planing producers might be cell lines and products might be proteins.
Download the current version http://github.com/ThomasKuehne/kinaseblender/raw/master/kinaseblender-current.jar
Ensure that Java >= 6 is installed.
Depending on your OS installation double click on
kinaseblender-current.jar or execute java -jar
kinaseblender-current.jar
in a shell.
(red) Read from Clipboard: Tries to interpret the current clipboard's content. MS Excel, OpenOffice.org and plain text files with TAB separators are known to work. For the data format see Data.
(green) Selector: Choose any of the available views.
(yellow) About: Display the author's contact info and the license.
(magenta) Write to Clipboard: Copy the current view to the system clipboard.
All cells with blue text can be clicked on for further details.
The following chapters use sample.txt / sample.ods(OpenOffice.org) / sample.xls(MS Office).
| Farm | Garden | Pond | Steppe | Woods | |
| Grass | 1 | 5 | 0 | 0 | 0 |
| Lavender | 0 | 12 | 0 | 0 | 0 |
| Mistletoe | 0 | 0 | 0 | 0 | 8 |
| Peyote | 0 | 1 | 0 | 2 | 0 |
| Water Lily | 0 | 3 | 20 | 0 | 0 |
| Wheat | 40 | 0 | 0 | 0 | 0 |
| White sage | 0 | 8 | 0 | 0 | 0 |
The input data has to be formatted with sources(green), products(red) and the amount(blue). Amount cells with no content, non-positive numbers or non-numeric content are ignored. If the same source appears in different columns their data is merged(logical OR). The same is true for product rows.
Open any of: sample.txt, sample.ods, sample.xls. Select the content, copy it to the clipboard and press “Read from Clipboard” in Kinaseblender:
This view displays Kinaseblender's raw interpretation of the imported data.
(red) product names
(green) source names
(yellow) amount
Open the selector and choose “Source”:
This view provides a short overview over the sources.
(red) source name
(green) total amount of products produces by this source
(yellow) number of different products produces by this source
(magenta) product names
Open the selector and choose “Products”:
This view displays provides a short overview over the products.
(red) product name
(green) total amount of product produces by all sources
(yellow) number of different sources producing this product
(magenta) source names
Open the selector and choose “Required Sources”:
This view displays provides a short overview over how many sources are required to produce a certain number of different products.
(red) number of sources used for the combination(s)
(green) number of different products produced by this combination
(yellow) number of different combination having the same number of sources and products
(magenta) There are 2(yellow) different source combinations with 2(red) sources each producing 6(green) different products.
Open the selector and choose “Unique Count”:
This view displays provides a detailed overview over the best combinations.
(red) number of sources used for the combination
(green) number of different products produced by this combination
(yellow) number of products produced by only one source in this combination
(magenta) number of products produced by more than one source in this combination
(blue) number unique products produced by the various sources
(turquoise) The best combination with 3(red) sources produce 7(green) different products. 6 (yellow) of the products are produced by only one source. 1 (magenta) product is produced by at least two sources. Garden, Wood and Farm contribute 4, 1 and 1 (blue) unique products to the combination.
Open the selector and choose “Unique Count”. Click on the last column header “Farm”:
This view details a single source.
(red) name of the product
(green) amount produced by this source
Open the selector, choose “Products” and click on “Grass”:
This view details a single product.
(red) name of the source
(green) amount produced by this source
Open the selector and choose “Unique Count”. Click on the second 6 in the “Products” column:
This view details a single combination.
(red) product name
(green) total amount produced
(yellow) number of sources producing this product
(magenta) number of the sources
(blue) number unique products produced by the various sources
(turquoise) Click on “What if >>” to use this combination as a basis for a “What If” view.
Open the selector and choose “What if”:
This view allows the user to create custom source combinations.
(red) source name
(green) checked sources will be included in analysis
(yellow) click on “Show >>” do display a Combination View for the selected combination.
Open the selector and choose “Next Best: 1 Sources”:
This view provides sub-optimal intermediate results from the heuristic search algorithm.
(red) number of sources used for the combination
(green) number of different products produced by this combination
(yellow) number of products produced by only one source in this combination
(magenta) number of products produced by more than one source in this combination
(turquoise) number unique products produced by the various sources


Across: 1. see 27 4. As 30 was on 14/9/01... very sensible! (8) 10,30. Despite losing wings, Gregan set to feature in Australia's high-flying game (3 6) 11. Final fate of 30: with time running out, I quit toil and strife? (11) 12. Natural confusion after second world war intelligence from enigma (5) 13. After pub, nude and so drunk, slurs (9) 14. Puts in new form of harness I developed (10) 17. Customs take drug toys regularly (4) 19. Pink unusual (4) 20. see 28 23. Accomplished blending of smart fuel (9) 25. Major in pursuit of genuine dominion (5) 27,1ac. TAA was one, 30 its "rival" (largely in name), enjoying said prohibition of likely intrusion, competing young startups (3 8 6) 28,20. An aria Denzel W performed for late 30 owner (3 3 7) 29. Musical "End of Earth, a Paradise Lost" he wrote of island of 30's last resort and town from whence 30 first carried people (8) 30. see 10 Down: 1. Chief of cabin crew has seconds of rum and tequila chaser (7) 2. Lacking mass to ignite (5) 3. Company gets a spell, sadly a total break (8) 5. Lacking love, ignore corruption in period of rule (5) 6. Customs taking first couple of Frankfurters perhaps (6) 7. In ghastly tundra, die as desiccated water dweller, mojama perhaps (5 4) 8. Gutless dummy with unpleasant line in authority (7) 9. Without real leader, half of quad taken in by service that flies like an eagle (8) 15. Major upset as reformist reformed! (9) 16. Getting cosy with northern police force, missing Cameron from Geelong (8) 18. Military force retraction of soldier's 22 to superior and newspaper (8) 19. Chance to settle the score with vicious harm etc. (7) 21. Disastrous "red time" penalty (7) 22. Compromise and lie, saying no (6) 24. Big book of oil production (5) 26. Disgrace one's 18 perhaps (5)


Type the word "barrelroll" into thin air
Go ahead, type it.
How to use
Simply include barrelroll.min.js on your site, like so:
<script src="barrelroll.min.js"></script>
To not interrupt the loading of your page, put it just before the closing </body>
tag.
The file is 714 bytes gzipped.
Technically, this is an aileron roll, but sssch.


--- layout: post authors: ["Greg Wilson"] title: "Instructor Training Statistics" date: 2013-08-23 time: "15:00:00" tags: ["Instructor Training"] ---
We started running an online training course for Software Carpentry instructors last fall. It's been going pretty well:
An average completion rate of 40% is pretty low compared to most university courses, but it compares favorably with the 5-10% completion rates of most MOOCs, and 9 of the 29 who dropped out of the first four rounds re-enrolled in a later round. Almost everyone who tells us why they dropped out blames real life getting in the way, but there's undoubtedly sampling bias in that: some people just disappear and stop responding to email.
The curriculum is now pretty stable (though we'll continue to tweak it based on feedback from learners and lab meetings), and feedback from people who've gone through it has mostly been positive. If you'd like to take part in a future round, please get in touch.


| Fig 1 |
Absolute long-term trends 1901–2000 in mean annual surface a ... |
| Fig 2 |
Long-term trends 1901–2000 in mean annual surface air temper ... |
| Fig 3 |
Absolute long-term trends 1901–2000 in mean annual surface a ... |
| Fig 4 |
Long-term trends 1901–2000 in the parameters total number of ... |
| Fig 5 |
Direction and magnitude d → of observed relative changes for ... |
| Fig 6 |
Long-term trends 1901–2000 in heat indicators per case city. ... |
| Fig 7 |
Histograms of the relative frequency (%) of the magnitude of ... |


SweetFreeStuff.com
///////////////////////////////////////////
Free Subscription to Redbook Magazine
Posted: 12 Nov 2015 05:00 AM PST
http://feedproxy.google.com/&edburner&utm_medium=email
The post Free Subscription to Redbook Magazine appeared first on
SweetFreeStuff.com.
///////////////////////////////////////////
Free Curel Itch Defense Sample Kit
Posted: 12 Nov 2015 04:10 AM PST
http://feedproxy.google.com/&edburner&utm_medium=email
Free Curel Itch Defense Sample Kit
The post Free Curel Itch Defense Sample Kit appeared first on
SweetFreeStuff.com.
///////////////////////////////////////////
Free 2016 Quality Aircraft Accessories Calendar
Posted: 12 Nov 2015 03:04 AM PST
http://feedproxy.google.com/&edburner&utm_medium=email
Free 2016 Quality Aircraft Accessories Calendar
The post Free 2016 Quality Aircraft Accessories Calendar appeared first on
SweetFreeStuff.com.
///////////////////////////////////////////
Free TCT 2016 Daily Bible Reading Calendar
Posted: 12 Nov 2015 02:50 AM PST
http://feedproxy.google.com/&edburner&utm_medium=email
Add to cart and check out. Free TCT 2016 Daily Bible Reading Calendar
The post Free TCT 2016 Daily Bible Reading Calendar appeared first on
SweetFreeStuff.com.
///////////////////////////////////////////
FREE EquateTM Options Pad and Liner Sample Kit
Posted: 11 Nov 2015 11:59 PM PST
http://feedproxy.google.com/&edburner&utm_medium=email
Click on Get a Free Sample. FREE EquateTM Options Pad and Liner Sample Kit
The post FREE EquateTM Options Pad and Liner Sample Kit appeared first on
SweetFreeStuff.com.
///////////////////////////////////////////
Free Purina ALPO Meal Helpers Dog Food Sample
Posted: 11 Nov 2015 07:14 PM PST
http://feedproxy.google.com/&edburner&utm_medium=email
FREE Purina ALPO Meal Helpers Dog Food Sample
The post Free Purina ALPO Meal Helpers Dog Food Sample appeared first on
SweetFreeStuff.com.


Languages like C++ and Java have very useful facilities that allow a stack
trace to be collected and displayed in a variety of ways. In Java, a snapshot
of the current stack trace can be taken simply by constructing a
Throwable
object, and the trace can be displayed using the
printStackTrace()
method.
Throwable t = new Throwable(); t.printStackTrace(System.out);
C++ offers similar facilities, and because of this, both these languages can provide useful information when an unexpected failure occurs and is detected. For example, assertions maybe placed in the code with the failure action being to display the current stack trace to help the programmer debug the cause.
Unfortunately C offers no such inbuilt luxury, and as such, debugging without a debugger or other logging mechanism maybe a little more difficult in the first instance. This interests me as I've worked as an embedded engineer creating software for consumer devices which are extensively field tested containing code that makes extensive use of assertion macros. I decided to investigate stack unwinding in order to enable better information to be gathered from devices that have failed in the field, with a goal to supporting stack tracing without the need for expensive or cumbersome supporting hardware.
Therefore I decided to make an ARM stack unwinder that would be suitable to run on an embedded target to provide stack trace capabilities for C, similar to those already enjoyed by other languages.
Since the target is an embedded processor in a consumer device, there are some restrictions on how the solution can be engineered and what options are available. At the same time, knowing the target processor is likely to be an ARM7 or similar processor using the ARM and Thumb Instruction Set Architectures allows the solution to be targeted specifically to this family of RISC processors.
The restrictions imposed by the embedded target are as follows:
Since storage is at a premium on these devices, I decided to forego use of debug tables as these would need embedding on the target and would be large, even if compressed. Since code runs from FLASH, I also have to be careful that the solution does not try and patch any code - one stack unwinding approach described in the ARM APCS document is to 'patch' function entries and exits and to then execute code to cause the stack adjustments to be made and stack frames unwound. (Patching code in FLASH is not easy since FLASH can generally only be erased in blocks and then written once i.e. it is not truly random access. Additionally erasing any block of FLASH could potentially permanently damage the device until it is reprogrammed, so that is a risk and complexity best avoided if at all possible).
Finally the form factor devices usually don't bring out connectors for debugging such as JTAG. This may sound weird, but all the pins on the package inside the device have a use and JTAG is usually multiplexed with something that is generally more useful, and exposing debug interfaces is also considered a security issue and frowned upon in the industry. Additionally having less external connectors makes Electrostatic Discharge (ESD) protection simpler as well as having other small benefits. And in any case, Java requires no debugger to grab a stack trace, so why should C?
Given the above restrictions, I decided that the best approach is to write a small model of the ARM processor which can interpret the code and look for the tell-tale signs of functions returning to divine the call stack. Yup, I decided to write a model ARM processor to run on the ARM to interpret the code with the aim of unwinding the stack, as opposed to producing bit exact interpretation of the code. Implementing the model ARM provides a couple of challenges that are laid out in the following subsections.
All functions look pretty much the same. They have a prologue, a main body and an epilogue. The compiler generates the prologue and epilogue on almost all functions (IRQ handling functions can be an explicit exception to this) to setup and teardown the stack frame used during the function body for things such as local variables. Debug tables can give details about the location of function prologues and epilogues to assist debuggers in interpreting the stack at any time, but I don't have these, so have to locate them automatically.
Since this is targeted at ARM processors, only ARM functions need to be considered. Looking at a few epilogues, it can be seen that they generally look the same and take the format shown in the following examples:
ADD sp,#0x28 POP {r4-r6,pc}
ADD sp,sp,#0x28 LDMFD sp!,{r4-r6,pc}
The examples show a stack adjustment to remove storage allocated for locals, then a restoration of the corrupted registers as required by the ARM ABI, and the restoration of the program counter (PC) from the stack effectively executing the return. The return is very similar and can be detected easily regardless of processor operating mode (Thumb or ARM), although this raises an interesting question. The examples show a return that is only suitable if the function is always called from code in the same operating mode as the function itself i.e. the Thumb return code can only be used if returning to Thumb code, and the same is also true for ARM code. Practically it is sometimes the case that ARM code may call Thumb functions and vice versa, and this is known as interworking. Fortunately the ARM ABI also describes interworking and more examples can be generated to show function epilogues used when interworking is required.
ADD sp,#0x28 POP {r4-r6} POP {r3} BX r3
ADD sp,sp,#0x28 LDMFD sp!,{r4-r6,lr} BX lr
With interworking, the BX
instruction is used to enable the
processor mode to be changed at the same time as returning from the function.
In each case, the return address is restored to a register before being used
with the BX
instruction to cause the return, where the least
significant bit of the return address is used to indicate the desired
processor mode once the branch has been taken. So we now have a good idea
of what we need to detect in order to determine where a function exits -
the reading of a return address from the stack, it being loaded into the
PC either directly by the load, or via a BX
instruction.
The first thing in the model ARM is therefore to store not only register contents, but a bit of data about where the contents originated from. To do this, I've made a couple of types for my model ARM to use.
typedef enum { REG_VAL_INVALID = 0x00, REG_VAL_FROM_STACK = 0x01, REG_VAL_FROM_MEMORY = 0x02, REG_VAL_FROM_CONST = 0x04, REG_VAL_ARITHMETIC = 0x80 } RegValOrigin; typedef struct { Int32 v; RegValOrigin o; } RegData;
Creating an array of RegData
structures then allows the register
file to be emulated. The Program Counter (PC) and Stack Pointer (SP) can be
added to the register file to give the model a basis to interpret code.
At this point, two basic loops are added to the model - one to interpret Thumb
code, and one to interpret ARM code and decoding for the POP
and
LDMFD
instructions are added respectively. When a value is loaded
to a register, the RegValOrigin
can now be updated to indicate that
the data originated on the stack, REG_VAL_FROM_STACK
, making it
easy to spot a function returning when a BX
is encountered for
such a tracked register. Interpretation of BX
is therefore
added to both the ARM and Thumb modes, faithfully checking the LSB of the
branch address to change the interpretation mode between ARM and Thumb as
needed.
At this point, the model ARM is capable of detecting the return from a
function. This is a good start, but it needs to handle the stack adjustment
if it is to be able to unwind more than one stack frame. In the examples seen
so far, the stack adjust has just been the addition of
0x28
to the stack pointer, although this will not always be the
case. Depending on the amount of stack data utilised by a function, the stack
adjust maybe for a different value, and unfortunately not all adjustments can
be accommodated by a single instruction. The following shows an odd C function
and the generated assembly.
int testStackResize(void) { char biggie[0x81111]; char *c = biggie; int t; sprintf(biggie, "Hello"); t = 0; while(*c) { t += *c; c++; } runFunc(); return t; }
testStackResize PROC LDR r3,|L1.364| + 56 PUSH {r4,r5,lr} ADD sp,r3 MOV r0,sp MOV r4,sp ADR r1,|L1.364| + 60 BL __0sprintf MOV r5,#0 B |L1.202| |L1.198| ADD r5,r0,r5 ADD r4,#1 |L1.202| LDRB r0,[r4,#0] CMP r0,#0 BNE |L1.198| LDR r0,|L1.364| + 68 LDR r0,[r0,#0] ; runFunc BL __call_via_r0 LDR r3,|L1.364| + 56 MOV r0,r5 NEG r3,r3 ADD sp,r3 POP {r4,r5} POP {r3} BX r3
This fictional function is far from pretty, and the epilogue is somewhat
more complicated. The important instructions are the LDR
into
r3 from a constant memory address, then the NEG
operation before
the stack adjust. Interlaced with this is an instruction to move the function's
return value into r0 in accordance with the ABI. This requires the model ARM not
only to interpret a number of new instructions, but also provokes thought about
how the compiler generates awkward constant values.
In ARM and Thumb mode there are a number of ways in which to generate a constant value, and the model ARM will need to be able to interpret them all. Worse still is the possibility that the desired constant, or some part of it, has already been created for use by the function body an that the compiler will use this already constructed value. This means that the model not only needs to be able to interpret any instructions that can be used to generate constant values, but that it needs to be able to look outside the function epilogue and into the function body too. Therefore the model ARM becomes yet more sophisticated and now attempts to interpret every instruction of the program, starting at the PC and SP values from where the stack trace is required, and stopping when some to be determined criteria is met.
Clearly it is desirable for the model ARM is to remain small, and so only the
subset of instructions that are needed for stack unwinding should be
implemented. The required instructions that have been identified so far
are those that are involved in constant value generation, stack adjusting
and returning. The question is what to do when an instruction that is
not understood is encountered. The solution to this is simple - invalidate
all state and continue the interpretation! As seen earlier, the
registers also have a status attached to their value, one status being
REG_VAL_INVALID
. Upon an uninterpreted instruction being
found, all registered values, with the exception of the PC and SP are
therefore invalidated.
Now that register values can be invalid, the rules of arithmetic also have
to change to propagate this meta data. For example, a simple addition of
two registers to yield a value in a third should produce a result with
status REG_VAL_INVALID
if either of the inputs is invalid.
Additionally a register MOV
should copy not only the register
value, but the status too. The following code fragment from the ARM
interpreting loop shows how the propagation of the register status
data is handled for Data Processing instructions.
/* Propagate register validity */ switch(arithOp) { case 0: /* AND: Rd := Op1 AND Op2 */ case 1: /* EOR: Rd := Op1 EOR Op2 */ case 2: /* SUB: Rd:= Op1 - Op2 */ case 3: /* RSB: Rd:= Op2 - Op1 */ case 4: /* ADD: Rd:= Op1 + Op2 */ case 12: /* ORR: Rd:= Op1 OR Op2 */ case 14: /* BIC: Rd:= Op1 AND NOT Op2 */ if(!M_IsOriginValid(state->regData[rn].o) || !M_IsOriginValid(op2origin)) { state->regData[rd].o = REG_VAL_INVALID; } else { state->regData[rd].o = state->regData[rn].o; state->regData[rd].o |= op2origin; } break; case 5: /* ADC: Rd:= Op1 + Op2 + C */ case 6: /* SBC: Rd:= Op1 - Op2 + C */ case 7: /* RSC: Rd:= Op2 - Op1 + C */ /* CPSR is not tracked */ state->regData[rd].o = REG_VAL_INVALID; break; case 8: /* TST: set condition codes on Op1 AND Op2 */ case 9: /* TEQ: set condition codes on Op1 EOR Op2 */ case 10: /* CMP: set condition codes on Op1 - Op2 */ case 11: /* CMN: set condition codes on Op1 + Op2 */ break; case 13: /* MOV: Rd:= Op2 */ case 15: /* MVN: Rd:= NOT Op2 */ state->regData[rd].o = op2origin; break; }
Now that the model is attempting to interpret all instructions, the handling of conditional code needs to be considered. Specifically the model must meet the following requirements:
ARM instructions employ conditional guarding, meaning that condition codes
can be attached to most instructions such that they are only executed if the
condition is met. Thumb mode uses conditional branch instructions, BNE
BEQ
etc..., to achieve a similar goal, and in both cases the
Status Register (SR) holds the condition flags which determine if a branch is
taken or an ARM instruction executed. Tracking the SR would apply overhead
and make the model more complex, as will any sort of branch analysis to find
infinite loops and function exits. Therefore I make the following
assumptions, to simplify the model ARM.
It seems highly unlikely that the function epilogue will contain conditional code and the 'stack moves once' rule of the ABI means that there is no risk of needing to conditionally correct the stack depending on the path taken through the function. Unconditional branches must always be taken since without them it is possible that interpretation could wander into another function or data area. Ignoring conditional branches also greatly simplifies the interpreter, but introduces a risk that some loops may appear infinite, as the following example shows.
int loop() { while(1) { int v = getch(); if(v == EOF) { break; } else if(v == 10) { printf("\n"); } else { printf("%c", v); } } return funcB(); }
loop PROC PUSH {r4,lr} |L1.2| BL getch CMP r0,#0 BEQ |L1.32| CMP r0,#0xa BNE |L1.22| ADR r0,|L1.36| BL __0printf B |L1.2| |L1.22| MOV r1,r0 ADR r0,|L1.36| + 4 BL __0printf B |L1.2| |L1.32| POP {r4,pc} DCW 0000 |L1.36| DATA DCB "\n\0\0\0" DCB "%c\0\0" ENDP
In the above example, the BEQ
needs to be taken in order to
reach the function epilogue. Without understanding of the Status Register,
the model ARM cannot do this, so instead gets stuck in the loop - this is
the first caveat of the scheme. Accepting for the moment that this type of
construct may occur (although I personally would try to avoid writing such
C code as it misses the purpose of the while statement!), a scheme for
detecting an infinite loop is required. I opt simply to count the number
of instructions since a function return was discovered, and to stop the
interpretation if some predefined limit is exceeded. This is very simple,
and has little overhead, although may take longer to determine that
unwinding is stuck than a more analytical approach would allow.
At this point, the model ARM should be capable of unwinding most stacks, has the ability to interpret all the code that could appear in a function epilogue and can interpret and detect returning to a register value sourced from the stack. The interpreter has a simple method to blunder into most function epilogues and also has a primitive method of detecting when it is stuck in an infinite loop. A little polish can be applied to trap cases such as the branching to a register whose value is invalid and the scheme is basically working. However, there are a couple of surprises yet...
So far the model ARM has been built to concentrate on unwinding the stack frames by interpretation of code leading up to and including the function epilogues - the prologue has not needed consideration. However, there is an optimisation that can be supplied by a compiler that causes prologues to become significant. The optimisation is 'tail calling' but is not specific to ARM architectures.
Tail calling is when a function always calls another function as the last thing that it does before returning. The compiler can spot this pattern and instead of generating return code from the first function, it can call the second function in such a way that its return code will return to the original caller.
void tailCall(int v) { v *= v; printf("%d", v); tailFunc(v); }
tailCall PROC STMFD sp!,{r4,lr} MUL r4,r0,r0 MOV r1,r4 ADR r0,|L1.524| BL __0printf MOV r0,r4 LDMFD sp!,{r4,lr} B tailFunc ENDP
In this case, the Link Register (LR) is restored from the stack, but instead
of the commonly seen BX
, an unconditional branch is made to
tailFunc()
, such that tailFunc()
will instead
return to the value placed in the LR. It's a small optimisation
that saves a word and a few cycles, but it complicates the interpretation
performed by the model ARM.
To accommodate this, the model ARM must either be aware of tail calling and ignore it, or must additionally be able to interpret function prologues. Detecting the tail call would not be impossible, the pattern or restoring the Link Register from the stack and then unconditionally branching is detectable, but there could be a small risk of misdetection if the LR were used in a function body for any purpose such as temporary storage or arithmetic.
Interpreting a function prologue is much the same as interpreting an epilogue
and the same instructions will be used to generate the constant value for
the stack adjust. However, whereas previously all values were being read
from memory and the stack, some values are now stored to the stack to save
state before the function executes. This could potentially damage the stack
on an executing system, so a small hash table to store memory addresses and
their values is implemented to store stack data instead; before reading from
memory the hash table is inspected, and if a value is found it is used in
place of the value from the device memory. Since function prologues are
likely to start with a PUSH
or STMFD
instruction,
there is also the possibility of an invalid register value being stored to
memory, so the memory hash has to allow for storage of some state data to
prevent an invalid register value becoming valid if it is PUSH
ed
and then POP
ed from the stack. Finally, to prevent the memory
hash needing to be large or risk overflowing, it is periodically purged of
data stored at addresses that are above the current top of the stack.
And there we have it - a scheme performing a kind of abstract interpretation of ARM or Thumb code in order to unwind the stack frames. However, while small, this method of abstract interpretation is not quite perfect. There are a number of situations where it will not work, although the general case so far suggests that it works very well in practice. Still, there are limitations, and these are best listed.
The problem of infinite loops could be dealt with by adding a random element to interpretation. For example, if the model suspects itself to be stuck in an infinite loop (a large number of instructions have been interpreted with no function epilogue being found), it may start randomly taking conditional branches in an attempt to 'chance upon' the function epilogue. While more sophisticated methods of exiting infinite loops, such as tracking the PC and marking branch history, could be implemented, they would require more memory and complexity for something that has rarely been found to cause a problem in practical usage of the unwinder.
A greater problem with no solution is that of tail calling masking functions
from the unwound stack. If the interpretation is started from a function
that was tail called, the function that made the tail call will be omitted
from the unwound stack. In example 8, unwinding started from
tailFunc()
or a sub-function thereof would omit to report
tailCall()
since the return path would not pass through that
function. In hindsight it may have been better to run the model ARM
backwards, although this presents different problems.
The following shows the amount of code and data occupied by the unwinder when compiler using RVCT2.1, compiled to Thumb code with -O2. The totals show that under 3k of ROM is used to implement the model ARM, which is very acceptable for my application.
| Code | (inc. data) | RO Data | RW Data | ZI Data | Library Member Name |
|---|---|---|---|---|---|
| 44 | 0 | 0 | 0 | 0 | unwarminder.o |
| 182 | 0 | 0 | 0 | 0 | unwarm.o |
| 904 | 68 | 0 | 0 | 0 | unwarm_arm.o |
| 1198 | 60 | 0 | 0 | 0 | unwarm_thumb.o |
| 300 | 0 | 0 | 0 | 0 | unwarmmem.o |
| 2628 | 128 | 0 | 0 | 0 | Totals |
The unwinding code is implemented in a handful of files, and a single header
file named unwarminder.h
needs to be included to access the
functionality. Accessing to the system memory from the unwinder is
abstracted through callbacks that must be implemented by the 'client'
code, and this allows reads to be validated such that unwinding is
stopped if alignment or the address being read is at fault. The client
code passes a small structure of function pointers to the unwinder to
equip it with the callbacks required to read memory and report return
addresses.
The function that starts the unwinding is given as follows:
UnwResult UnwindStart(Int32 spValue, const UnwindCallbacks *cb, void *data);
The cb
structure gives the callbacks to allow memory
accesses and return address reporting, while the data
pointer can take any value and is passed to the reporting function
(cb->report()
) such that it may store state if required.
The spValue
gives the stack pointer value at which to
start unwinding; the PC value is determined automatically as it is
effectively passed to the function via the Link Register and so can
be retrieved. When using RVCT, the compiler intrinsic function
__current_sp()
allows the SP value to be read into a
variable, so a call to start unwinding typically looks something
like the following:
const UnwindCallbacks cliCallbacks = { ... }; CliStack results; Int8 t; UnwResult r; results.frameCount = 0; r = UnwindStart(__current_sp(), &cliCallbacks, &results);
Finally, the implementation is not aware of any OS or memory protection
or management schemes that maybe in use on the target. The system on which
this has been tested is simply configured with a flat memory map and has
few restrictions on memory access, and the RTOS used poses no restrictions
either. It maybe the case that to use this on other targets the MMU or
MPU has to be reconfigured or disabled before unwinding is started, or the
functions used by the unwinder to access the memory specially constructed
to ensure that memory protections will not cause a problem. Should the
unwinder request access to addresses that are genuinely invalid, the
client functions for memory access can return FALSE
to indicate
that the memory cannot be accessed, and unwinding will terminate.
The source code for the stack unwinder is available for free download and I'm making it PUBLIC DOMAIN. This means that there is no copyright and anyone is able to take a copy for free and use it as they wish, with or without modifications, and in any context they like, commercially or otherwise. The only limitation is that I don't guarantee that the software is fit for any purpose or accept any liability for its use or misuse - the software is without warranty.
Having said all this, the software has been ran under Valgrind and tested both in PC simulations (using ARMSD) and on ARM7TDMI and ARM920T targets.
The download package is available here (right-click, Save As...):
This package contains the source code for the unwinder as well as two 'clients'
that allow the unwinder to be exercised. The first client is contained in two
files, client.c
and client.h
and can be built to
produce an image that can be executed either on an ARM target or in an emulator
and demonstrates the unwinding of the stack from which the unwinder is called.
The second client is the 'simulation' client, simclient.c
and
simclient.h
, which uses two memory images that are also supplied
and contain a snapshot of a call stack and executable code which allows
interpretation by the unwinder on a PC, where PC tools can also be used to
debug the unwinder. The memory images supplied cannot however be ran on a
target since I've zero'd the areas of code that are not needed to demonstrate
the unwinder such that the ARM runtime is not present in binary form.


| Opcode | Instruction | Op/En | 64-Bit Mode | Compat/Leg Mode | Description |
| 0F 35 | SYSEXIT | NP | Valid | Valid | Fast return to privilege level 3 user code. |
| REX.W + 0F 35 | SYSEXIT | NP | Valid | Valid | Fast return to 64-bit mode privilege level 3 user code. |
| Op/En | Operand 1 | Operand 2 | Operand 3 | Operand 4 |
| NP | NA | NA | NA | NA |
Executes a fast return to privilege level 3 user code. SYSEXIT is a companion instruction to the SYSENTER instruction. The instruction is optimized to provide the maximum performance for returns from system procedures executing at protections levels 0 to user procedures executing at protection level 3. It must be executed from code executing at privilege level 0.
With a 64-bit operand size, SYSEXIT remains in 64-bit mode; otherwise, it either enters compatibility mode (if the logical processor is in IA-32e mode) or remains in protected mode (if it is not).
Prior to executing SYSEXIT, software must specify the privilege level 3 code segment and code entry point, and the privilege level 3 stack segment and stack pointer by writing values into the following MSR and general-purpose registers:
The IA32_SYSENTER_CS MSR can be read from and written to using RDMSR and WRMSR.
While SYSEXIT loads the CS and SS selectors with values derived from the IA32_SYSENTER_CS MSR, the CS and SS descriptor caches are not loaded from the descriptors (in GDT or LDT) referenced by those selectors. Instead, the descriptor caches are loaded with fixed values. See the Operation section for details. It is the responsibility of OS software to ensure that the descriptors (in GDT or LDT) referenced by those selector values correspond to the fixed values loaded into the descriptor caches; the SYSEXIT instruction does not ensure this correspondence.
The SYSEXIT instruction can be invoked from all operating modes except real-address mode and virtual-8086 mode.
The SYSENTER and SYSEXIT instructions were introduced into the IA-32 architecture in the Pentium II processor. The availability of these instructions on a processor is indicated with the SYSENTER/SYSEXIT present (SEP) feature flag returned to the EDX register by the CPUID instruction. An operating system that qualifies the SEP flag must also qualify the processor family and model to ensure that the SYSENTER/SYSEXIT instructions are actually present. For example:
IF CPUID SEP bit is set THEN IF (Family = 6) and (Model < 3) and (Stepping < 3) THEN SYSENTER/SYSEXIT_Not_Supported; FI; ELSE SYSENTER/SYSEXIT_Supported; FI; FI;
When the CPUID instruction is executed on the Pentium Pro processor (model 1), the processor returns a the SEP flag as set, but does not support the SYSENTER/SYSEXIT instructions.
IF IA32_SYSENTER_CS[15:2] = 0 OR CR0.PE = 0 OR CPL ≠ 0 THEN #GP(0); FI; IF operand size is 64-bit THEN RSP ← RCX; RIP ← RDX; ELSE RSP ← ECX; RIP ← EDX; FI; IF operand size is 64-bit THEN CS.Selector ← IA32_SYSENTER_CS[15:0] + 32; ELSE CS.Selector ← IA32_SYSENTER_CS[15:0] + 16; FI; CS.Selector ← CS.Selector OR 3; (* Set rest of CS to a fixed value *) CS.Base ← 0; CS.Limit ← FFFFFH; CS.Type ← 11; CS.S ← 1; CS.DPL ← 3; CS.P ← 1; IF operand size is 64-bit THEN CS.L ← 1; CS.D ← 0; ELSE CS.L ← 0; CS.D ← 1; FI; CS.G ← 1; CPL ← 3; SS.Selector ← CS.Selector + 8; (* Set rest of SS to a fixed value *) SS.Base ← 0; SS.Limit ← FFFFFH; SS.Type ← 3; SS.S ← 1; SS.DPL ← 3; SS.P ← 1; SS.B ← 1; SS.G ← 1;
None.
| #GP(0) | If IA32_SYSENTER_CS[15:2] = 0. If CPL ≠ 0. |
| #UD | If the LOCK prefix is used. |
| #GP | The SYSEXIT instruction is not recognized in real-address mode. |
| #UD | If the LOCK prefix is used. |
| #GP(0) | The SYSEXIT instruction is not recognized in virtual-8086 mode. |
Same exceptions as in protected mode.
| #GP(0) | If IA32_SYSENTER_CS = 0. If CPL ≠ 0. If RCX or RDX contains a non-canonical address. |
| #UD | If the LOCK prefix is used. |


Welcome to my space. 欢迎光临
This is a personal website for Yuesong Wang. I'm currently a Computer Science graduate student in University of California, Santa Barbara.
I mainly use this place to record some technical problems and its corresponding solution.


| 057:015 Khan | : |
So this Day no ransom shall be taken from you (hypocrites), nor of those who disbelieved, (in the Oneness of Allah Islamic Monotheism). Your abode is the Fire, that is the proper place for you, and worst indeed is that destination. |
| 057:015 Maulana | : |
So this day no ransom will be accepted from you, nor from those who disbelieved.  Your home is the Fire; that is your patron, and a hapless journey's end. |
| 057:015 Rashad | : |
"Therefore, today no ransom can be taken from you, nor from those who disbelieved.  |
| 057:015 Sarwar | : |
So on this day no ransom will be accepted from you nor from the disbelievers. Your dwelling will be fire. It will be your friend and a terrible end". |
| 057:015 Shakir | : |
So today ransom shall not be accepted from you nor from those who disbelieved; your abode is the fire; it is your friend and evil is the resort. |
| 057:015 Sherali | : |
`So this day no ransom shall be accepted from you, nor from those who disbelieved.   |
Concepts/Themes Covered: أركان الإسلام > التوحيد > الكافرون > ندم الكفار Pillars of Islam> Islamic> The Disbelievers> The Disbelievers' Repent الإيمان > الإيمان بالله > النفاق Faith> Belief In Allah> Hypocrisy الإيمان > الغيب > النار > أسماء النار > بئس المصير Faith> The Unseen World> Hell-Fire>Hell Names> Bad End الإيمان > الغيب > النار > أصحاب النار Faith> The Unseen World> Hell-Fire>Hell Fellows
This tool uses eight English parallel translations for the Holy Quran imported from Mr. Clay Smith. You can also visit Qurany Concepts for browsing the Quran themes or topics. If you want to search the Holy Quran for keywords, please visit Qurany Keywords.


<script src="RGraph.common.core.js"></script> <script src="RGraph.line.js"></script>Put this where you want the chart to show up:
<div style="text-align: center"> <canvas id="cvs" width="900" height="300">[No canvas support]lt/canvas> </div>This is the code that generates the chart - it should be placed AFTER the canvas tag(s):


Good enough is PerfectHow many times do we ask ourselves this question? what is good enough? others might call it - what is the MVP? In the session, I will cover some key questions and guidelines on how to decide what is MVP, including examples - all in 5 minutes!


Here's a summary of all the startup-related work going on. Other people on the team are also blogging updates on their individual projects:
- Ryan Flint: This Week in Perf - Aug. 14th Edition
- David Dahl: Looking for Dead Code
- Drew Willcoxon: Startup As usual, for the details, check out the Startup Project wiki page.
Progress
- PGO for SQLite, MozStorage and Places: Landed on the Places branch. The test failures seen when PGO first landed are not there (yay), but the Talos boxes don't show any clear wins (boo).
- Dead Code Hunting: Even though he's supposed to be on vacation, David has got the full browser.xul environment pulled in for analysis. More info in his post (linked above). Still a lot of false-positives in the detection code.
- Startup timeline: Vlad's been working with the NSPR owner, and the latest patch has review, so almost there.
- XPCOM component combining: No progress from me, but Florian Quèze attached a shell script to knit the components together!
- XPT Linking on Mac: Drew has confirmed big wins from this, split it off into it's own bug. More detailed notes from him on his wiki page.
JARification
- Taras' core IO improvements to how JAR file contents are read have landed, as well as the combining of all chrome into browser and toolkit JARs (this morning!).
- Ryan is looking at putting the components directory into a JAR so that it reaps the same benefits as the chrome directories.
Testing/Measurement
- Met with Alice to talk about various test scenarios, and the deployment process
- Started a guide for taking a Talos test from idea to production
- Initial steps on automatedly testing cold-startup, figuring out platform-specific calls, and what Talos changes are needed
- Discussing approaches to micro-benchmarking the browser UI
Next Steps
- Enable PGO on mozilla-central, get nightly tester feedback
- Once the startup timeline lands, get an actual timeline to analyze
- Reduce false-positives on the dead-code report, document installation and usage, develop plan for continuous integration
- Work with Ted to get a patch for JS component combining into the packaging process
- Figure out if there's a win in jar'ing /components or if we just need to fix fastload to not touch the files as much
- Get XPT linking landed
- File bugs and get the Talos changes in Alice's queue for cold-startup testing
- Finish the Talos test development guide
- Talk with Ryan Doherty about the reporting side of microbenchmarking [UPDATE: added Drew's blog post]


Vmware Updates Vcenter Server 6 0 U3c And Other Products Esx Virtualization
How To Download And Install Vcenter Server Root Certificates To Avoid Web Browser Certificate Warnings 2108294 Vmware Kb
Vmware Vcenter Server 7 0 0b Build 16386292 Filecr
Vmware Vcenter Server 7 0 0b Free Download
Https Www Vmware Com Content Dam Digitalmarketing Vmware En Pdf Techpaper Vmware Vcenter Server 6 Deployment Guide Pdf
Vcenter Appliance Download Akhorse
Vmware Vcenter Server 7 0 0b Build 16386292 Filecr
Vmware Vcenter Server 7 0 0b Free Download
Vmware Vcenter Server 6 0 Vegalopride
Manually Patch Vmware Vcenter Server Vcsa With Iso Virtualization Howto
Vsphere 7 0 Download Now Available Esx Virtualization
Download Vmware Vcenter Server 6 0 Newfindmy
How To Install Vmware Vcenter Server 6 7 For Windows Xpertstec
How To Install Vcenter Server 5 5 In Windows 7 Os Srijit Banerjee S Blog
How To Download Esxi And Vcenter Server 6 5 Youtube
Vmware Vcenter Server 7 0 0b Build 16386292 Filecr
Vmware Lic File Download
Vmware Vsphere 6 Free Download
How To Import Default Vcenter Server Appliance Vmca Root Certificate And Refresh Ca Certificate On Esxi Vgeek Tales From Real It System Administration Environment
Vcenter Server Appliance 6 0 Reference Poster
Download Vsphere 7 0 Get Ready For Innovation
Vsphere Client 6 7 Download And Features
Updating Vcenter Server Appliance 6 0 To Update 1 Vmware Vsphere Blog
Vxrail Vcenter Serverログバンドル Vc Support 作成 Dell Community
Vmware Esxi Client Mac Download Peatix
Patching Update Vmware Vcenter Server Appliance From A Zipped Update Bundle Web Server Vgeek Tales From Real It System Administration Environment
Download Vcenter Support Assistant 5 5 Eric Sloof Ntpro Nl
Download Vmware Vcenter Server 6 0 Allyeasysite
Vmware Esxi Free Download Configuration And License Virtualization Howto
Introducing Vsphere 6 7 What S New In Vcenter Server 6 7 Techcrumble


Creating and Customizing Rails Generators & Templates¶ ↑
Rails generators are an essential tool if you plan to improve your workflow. With this guide you will learn how to create generators and customize existing ones.
After reading this guide, you will know:
-
How to see which generators are available in your application.
-
How to create a generator using templates.
-
How Rails searches for generators before invoking them.
-
How Rails internally generates Rails code from the templates.
-
How to customize your scaffold by creating new generators.
-
How to customize your scaffold by changing generator templates.
-
How to use fallbacks to avoid overwriting a huge set of generators.
-
How to create an application template.
First Contact¶ ↑
When you create an application using the rails
command, you
are in fact using a Rails generator. After that, you can get a list of all
available generators by just invoking rails generate
:
$ rails new myapp $ cd myapp $ bin/rails generate
You will get a list of all generators that comes with Rails. If you need a detailed description of the helper generator, for example, you can simply do:
$ bin/rails generate helper --help
Creating Your First Generator¶ ↑
Since Rails 3.0, generators are built on top of Thor. Thor provides powerful
options for parsing and a great API for manipulating files. For instance,
let's build a generator that creates an initializer file named
initializer.rb
inside config/initializers
.
The first step is to create a file at
lib/generators/initializer_generator.rb
with the following
content:
class InitializerGenerator < Rails::Generators::Base def create_initializer_file create_file "config/initializers/initializer.rb", "# Add initialization content here" end end
NOTE: create_file
is a method provided by
Thor::Actions
. Documentation for create_file
and
other Thor methods can be found in Thor’s
documentation
Our new generator is quite simple: it inherits from
Rails::Generators::Base
and has one method definition. When a
generator is invoked, each public method in the generator is executed
sequentially in the order that it is defined. Finally, we invoke the
create_file
method that will create a file at the given
destination with the given content. If you are familiar with the Rails
Application Templates API, you'll feel right at home with the new
generators API.
To invoke our new generator, we just need to do:
$ bin/rails generate initializer
Before we go on, let's see our brand new generator description:
$ bin/rails generate initializer --help
Rails is usually able to generate good descriptions if a generator is
namespaced, as ActiveRecord::Generators::ModelGenerator
, but
not in this particular case. We can solve this problem in two ways. The
first one is calling desc
inside our generator:
class InitializerGenerator < Rails::Generators::Base desc "This generator creates an initializer file at config/initializers" def create_initializer_file create_file "config/initializers/initializer.rb", "# Add initialization content here" end end
Now we can see the new description by invoking --help
on the
new generator. The second way to add a description is by creating a file
named USAGE
in the same directory as our generator. We are
going to do that in the next step.
Creating Generators with Generators¶ ↑
Generators themselves have a generator:
$ bin/rails generate generator initializer create lib/generators/initializer create lib/generators/initializer/initializer_generator.rb create lib/generators/initializer/USAGE create lib/generators/initializer/templates
This is the generator just created:
class InitializerGenerator < Rails::Generators::NamedBase source_root File.expand_path("../templates", __FILE__) end
First, notice that we are inheriting from
Rails::Generators::NamedBase
instead of
Rails::Generators::Base
. This means that our generator expects
at least one argument, which will be the name of the initializer, and will
be available in our code in the variable name
.
We can see that by invoking the description of this new generator (don't forget to delete the old generator file):
$ bin/rails generate initializer --help Usage: rails generate initializer NAME [options]
We can also see that our new generator has a class method called
source_root
. This method points to where our generator
templates will be placed, if any, and by default it points to the created
directory lib/generators/initializer/templates
.
In order to understand what a generator template means, let's create
the file lib/generators/initializer/templates/initializer.rb
with the following content:
# Add initialization content here
And now let's change the generator to copy this template when invoked:
class InitializerGenerator < Rails::Generators::NamedBase source_root File.expand_path("../templates", __FILE__) def copy_initializer_file copy_file "initializer.rb", "config/initializers/#{file_name}.rb" end end
And let's execute our generator:
$ bin/rails generate initializer core_extensions
We can see that now an initializer named core_extensions was created at
config/initializers/core_extensions.rb
with the contents of
our template. That means that copy_file
copied a file in our
source root to the destination path we gave. The method
file_name
is automatically created when we inherit from
Rails::Generators::NamedBase
.
The methods that are available for generators are covered in the final section of this guide.
Generators Lookup¶ ↑
When you run rails generate initializer core_extensions
Rails
requires these files in turn until one is found:
rails/generators/initializer/initializer_generator.rb generators/initializer/initializer_generator.rb rails/generators/initializer_generator.rb generators/initializer_generator.rb
If none is found you get an error message.
INFO: The examples above put files under the application's
lib
because said directory belongs to $LOAD_PATH
.

They can be configured in config/application.rb
, these are
some defaults:
config.generators do |g| g.orm :active_record g.template_engine :erb g.test_framework :test_unit, fixture: true end
Before we customize our workflow, let's first see what our scaffold looks like:
$ bin/rails generate scaffold User name:string invoke active_record create db/migrate/20130924151154_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml invoke resource_route route resources :users invoke scaffold_controller create app/controllers/users_controller.rb invoke erb create app/views/users create app/views/users/index.html.erb create app/views/users/edit.html.erb create app/views/users/show.html.erb create app/views/users/new.html.erb create app/views/users/_form.html.erb invoke test_unit create test/controllers/users_controller_test.rb invoke helper create app/helpers/users_helper.rb invoke jbuilder create app/views/users/index.json.jbuilder create app/views/users/show.json.jbuilder invoke assets invoke coffee create app/assets/javascripts/users.js.coffee invoke scss create app/assets/stylesheets/users.css.scss invoke scss create app/assets/stylesheets/scaffolds.css.scss
Looking at this output, it's easy to understand how generators work in Rails 3.0 and above. The scaffold generator doesn't actually generate anything, it just invokes others to do the work. This allows us to add/replace/remove any of those invocations. For instance, the scaffold generator invokes the scaffold_controller generator, which invokes erb, test_unit and helper generators. Since each generator has a single responsibility, they are easy to reuse, avoiding code duplication.
Our first customization on the workflow will be to stop generating stylesheet, JavaScript and test fixture files for scaffolds. We can achieve that by changing our configuration to the following:
config.generators do |g| g.orm :active_record g.template_engine :erb g.test_framework :test_unit, fixture: false g.stylesheets false g.javascripts false end
If we generate another resource with the scaffold generator, we can see that stylesheet, JavaScript and fixture files are not created anymore. If you want to customize it further, for example to use DataMapper and RSpec instead of Active Record and TestUnit, it's just a matter of adding their gems to your application and configuring your generators.
To demonstrate this, we are going to create a new helper generator that simply adds some instance variable readers. First, we create a generator within the rails namespace, as this is where rails searches for generators used as hooks:
$ bin/rails generate generator rails/my_helper create lib/generators/rails/my_helper create lib/generators/rails/my_helper/my_helper_generator.rb create lib/generators/rails/my_helper/USAGE create lib/generators/rails/my_helper/templates
After that, we can delete both the templates
directory and the
source_root
class method call from our new generator, because
we are not going to need them. Add the method below, so our generator looks
like the following:
# lib/generators/rails/my_helper/my_helper_generator.rb class Rails::MyHelperGenerator < Rails::Generators::NamedBase def create_helper_file create_file "app/helpers/#{file_name}_helper.rb", <<-FILE module #{class_name}Helper attr_reader :#{plural_name}, :#{plural_name.singularize} end FILE end end
We can try out our new generator by creating a helper for products:
$ bin/rails generate my_helper products create app/helpers/products_helper.rb
And it will generate the following helper file in app/helpers
:
module ProductsHelper attr_reader :products, :product end
Which is what we expected. We can now tell scaffold to use our new helper
generator by editing config/application.rb
once again:
config.generators do |g| g.orm :active_record g.template_engine :erb g.test_framework :test_unit, fixture: false g.stylesheets false g.javascripts false g.helper :my_helper end
and see it in action when invoking the generator:
$ bin/rails generate scaffold Article body:text [...] invoke my_helper create app/helpers/articles_helper.rb
We can notice on the output that our new helper was invoked instead of the Rails default. However one thing is missing, which is tests for our new generator and to do that, we are going to reuse old helpers test generators.
Since Rails 3.0, this is easy to do due to the hooks concept. Our new helper does not need to be focused in one specific test framework, it can simply provide a hook and a test framework just needs to implement this hook in order to be compatible.
To do that, we can change the generator this way:
# lib/generators/rails/my_helper/my_helper_generator.rb class Rails::MyHelperGenerator < Rails::Generators::NamedBase def create_helper_file create_file "app/helpers/#{file_name}_helper.rb", <<-FILE module #{class_name}Helper attr_reader :#{plural_name}, :#{plural_name.singularize} end FILE end hook_for :test_framework end
Now, when the helper generator is invoked and TestUnit is configured as the
test framework, it will try to invoke both
Rails::TestUnitGenerator
and
TestUnit::MyHelperGenerator
. Since none of those are defined,
we can tell our generator to invoke
TestUnit::Generators::HelperGenerator
instead, which is
defined since it's a Rails generator. To do that, we just need to add:
# Search for :helper instead of :my_helper hook_for :test_framework, as: :helper
And now you can re-run scaffold for another resource and see it generating tests as well!
Customizing Your Workflow by Changing Generators Templates¶ ↑
In the step above we simply wanted to add a line to the generated helper,
without adding any extra functionality. There is a simpler way to do that,
and it's by replacing the templates of already existing generators, in
that case Rails::Generators::HelperGenerator
.
In Rails 3.0 and above, generators don't just look in the source root
for templates, they also search for templates in other paths. And one of
them is lib/templates
. Since we want to customize
Rails::Generators::HelperGenerator
, we can do that by simply
making a template copy inside lib/templates/rails/helper
with
the name helper.rb
. So let's create that file with the
following content:
module <%= class_name %>Helper attr_reader :<%= plural_name %>, :<%= plural_name.singularize %> end
and revert the last change in config/application.rb
:
config.generators do |g| g.orm :active_record g.template_engine :erb g.test_framework :test_unit, fixture: false g.stylesheets false g.javascripts false end
If you generate another resource, you can see that we get exactly the same
result! This is useful if you want to customize your scaffold templates
and/or layout by just creating edit.html.erb
,
index.html.erb
and so on inside
lib/templates/erb/scaffold
.
Scaffold templates in Rails frequently use ERB tags; these tags need to be escaped so that the generated output is valid ERB code.
For example, the following escaped ERB tag would be needed in the template
(note the extra %
)…
<%Q%= stylesheet_include_tag :application %>
…to generate the following output:
<%Q= stylesheet_include_tag :application %>
Adding Generators Fallbacks¶ ↑
One last feature about generators which is quite useful for plugin
generators is fallbacks. For example, imagine that you want to add a
feature on top of TestUnit like shoulda does. Since
TestUnit already implements all generators required by Rails and shoulda
just wants to overwrite part of it, there is no need for shoulda to
reimplement some generators again, it can simply tell Rails to use a
TestUnit
generator if none was found under the
Shoulda
namespace.
We can easily simulate this behavior by changing our
config/application.rb
once again:
config.generators do |g| g.orm :active_record g.template_engine :erb g.test_framework :shoulda, fixture: false g.stylesheets false g.javascripts false # Add a fallback! g.fallbacks[:shoulda] = :test_unit end
Now, if you create a Comment scaffold, you will see that the shoulda generators are being invoked, and at the end, they are just falling back to TestUnit generators:
$ bin/rails generate scaffold Comment body:text invoke active_record create db/migrate/20130924143118_create_comments.rb create app/models/comment.rb invoke shoulda create test/models/comment_test.rb create test/fixtures/comments.yml invoke resource_route route resources :comments invoke scaffold_controller create app/controllers/comments_controller.rb invoke erb create app/views/comments create app/views/comments/index.html.erb create app/views/comments/edit.html.erb create app/views/comments/show.html.erb create app/views/comments/new.html.erb create app/views/comments/_form.html.erb invoke shoulda create test/controllers/comments_controller_test.rb invoke my_helper create app/helpers/comments_helper.rb invoke jbuilder create app/views/comments/index.json.jbuilder create app/views/comments/show.json.jbuilder invoke assets invoke coffee create app/assets/javascripts/comments.js.coffee invoke scss
Fallbacks allow your generators to have a single responsibility, increasing code reuse and reducing the amount of duplication.
Application Templates¶ ↑
Now that you've seen how generators can be used inside an application, did you know they can also be used to generate applications too? This kind of generator is referred as a “template”. This is a brief overview of the Templates API. For detailed documentation see the Rails Application Templates guide.
gem "rspec-rails", group: "test" gem "cucumber-rails", group: "test" if yes?("Would you like to install Devise?") gem "devise" generate "devise:install" model_name = ask("What would you like the user model to be called? [user]") model_name = "user" if model_name.blank? generate "devise", model_name end
In the above template we specify that the application relies on the
rspec-rails
and cucumber-rails
gem so these two
will be added to the test
group in the Gemfile
.
Then we pose a question to the user about whether or not they would like to
install Devise. If the user replies “y” or “yes” to this question, then the
template will add Devise to the Gemfile
outside of any group
and then runs the devise:install
generator. This template then
takes the users input and runs the devise
generator, with the
user's answer from the last question being passed to this generator.
Imagine that this template was in a file called template.rb
.
We can use it to modify the outcome of the rails new
command
by using the -m
option and passing in the filename:
$ rails new thud -m template.rb
This command will generate the Thud
application, and then
apply the template to the generated output.
Templates don't have to be stored on the local system, the
-m
option also supports online templates:
$ rails new thud -m https://gist.github.com/radar/722911/raw/
Whilst the final section of this guide doesn't cover how to generate the most awesome template known to man, it will take you through the methods available at your disposal so that you can develop it yourself. These same methods are also available for generators.
Generator methods¶ ↑
The following are methods available for both generators and templates for Rails.
NOTE: Methods provided by Thor are not covered this guide and can be found in Thor’s documentation
gem
¶ ↑
Specifies a gem dependency of the application.
gem "rspec", group: "test", version: "2.1.0" gem "devise", "1.1.5"
Available options are:
-
:group
- The group in theGemfile
where this gem should go. -
:version
- The version string of the gem you want to use. Can also be specified as the second argument to the method. -
:git
- The URL to the git repository for this gem.
Any additional options passed to this method are put on the end of the line:
gem "devise", git: "git://github.com/plataformatec/devise", branch: "master"
The above code will put the following line into Gemfile
:
gem "devise", git: "git://github.com/plataformatec/devise", branch: "master"
gem_group
¶ ↑
Wraps gem entries inside a group:
gem_group :development, :test do gem "rspec-rails" end
add_source
¶ ↑
Adds a specified source to Gemfile
:
add_source "http://gems.github.com"
inject_into_file
¶ ↑
Injects a block of code into a defined position in your file.
inject_into_file 'name_of_file.rb', after: "#The code goes below this line. Don't forget the Line break at the end\n" do <<-'RUBY' puts "Hello World" RUBY end
gsub_file
¶ ↑
Replaces text inside a file.
gsub_file 'name_of_file.rb', 'method.to_be_replaced', 'method.the_replacing_code'
Regular Expressions can be used to make this method more precise. You can
also use append_file
and prepend_file
in the same
way to place code at the beginning and end of a file respectively.
application
¶ ↑
Adds a line to config/application.rb
directly after the
application class definition.
application "config.asset_host = 'http://example.com'"
This method can also take a block:
application do "config.asset_host = 'http://example.com'" end
Available options are:
-
:env
- Specify an environment for this configuration option. If you wish to use this option with the block syntax the recommended syntax is as follows:
application(nil, env: "development") do "config.asset_host = 'http://localhost:3000'" end
git
¶ ↑
Runs the specified git command:
git :init git add: "." git commit: "-m First commit!" git add: "onefile.rb", rm: "badfile.cxx"
The values of the hash here being the arguments or options passed to the specific git command. As per the final example shown here, multiple git commands can be specified at a time, but the order of their running is not guaranteed to be the same as the order that they were specified in.
vendor
¶ ↑
Places a file into vendor
which contains the specified code.
vendor "sekrit.rb", '#top secret stuff'
This method also takes a block:
vendor "seeds.rb" do "puts 'in your app, seeding your database'" end
lib
¶ ↑
Places a file into lib
which contains the specified code.
lib "special.rb", "p Rails.root"
This method also takes a block:
lib "super_special.rb" do puts "Super special!" end
rakefile
¶ ↑
Creates a Rake file in the lib/tasks
directory of the
application.
rakefile "test.rake", "hello there"
This method also takes a block:
rakefile "test.rake" do %Q{ task rock: :environment do puts "Rockin'" end } end
initializer
¶ ↑
Creates an initializer in the config/initializers
directory of
the application:
initializer "begin.rb", "puts 'this is the beginning'"
This method also takes a block, expected to return a string:
initializer "begin.rb" do "puts 'this is the beginning'" end
generate
¶ ↑
Runs the specified generator where the first argument is the generator name and the remaining arguments are passed directly to the generator.
generate "scaffold", "forums title:string description:text"
rake
¶ ↑
Runs the specified Rake task.
rake "db:migrate"
Available options are:
-
:env
- Specifies the environment in which to run this rake task. -
:sudo
- Whether or not to run this task usingsudo
. Defaults tofalse
.
capify!
¶ ↑
Runs the capify
command from Capistrano at the root of the
application which generates Capistrano configuration.
capify!
route
¶ ↑
Adds text to the config/routes.rb
file:
route "resources :people"
readme
¶ ↑
Output the contents of a file in the template's
source_path
, usually a README.
readme "README"


Re-usable, serializable priority queue implementation
SplPriorityQueue acts as a heap; on iteration, each item is removed from the queue. If you wish to re-use such a queue, you need to clone it first. This makes for some interesting issues if you wish to delete items from the queue, or, as already stated, iterate over it multiple times.
This class aggregates items for the queue itself, but also composes an "inner" iterator in the form of an SplPriorityQueue object for performing the actual iteration.
| package |
Default |
|---|
__clone() : void
contains(mixed $datum) : boolean
mixed
boolean
count() : integer
integer
extract() : mixed
mixed
getIterator() : \Zend\Stdlib\SplPriorityQueue
SplPriorityQueue acts as a heap, which typically implies that as items are iterated, they are also removed. This does not work for situations where the queue may be iterated multiple times. As such, this class aggregates the values, and also injects an SplPriorityQueue. This method retrieves the inner queue object, and clones it for purposes of iteration.
\Zend\Stdlib\SplPriorityQueue
getQueue() : \Zend\Stdlib\SplPriorityQueue
hasPriority(integer $priority) : boolean
integer
boolean
insert(mixed $data, integer $priority = 1) : \Zend\Stdlib\PriorityQueue
Priority defaults to 1 (low priority) if none provided.
mixed
integer
\Zend\Stdlib\PriorityQueue
isEmpty() : boolean
boolean
process(\Zend\Config\Config $config) : \Zend\Config\Config
| Throws |
|
|---|
\Zend\Config\Config
\Zend\Config\Config
processValue(mixed $value) : mixed
mixed
mixed
remove(mixed $datum) : boolean
This is different than \extract(); its purpose is to dequeue an item.
This operation is potentially expensive, as it requires re-initialization and re-population of the inner queue.
Note: this removes the first item matching the provided item found. If the same item has been added multiple times, it will not remove other instances.
mixed
boolean
False if the item was not found, true otherwise.
serialize() : string
string
setInternalQueueClass(string $class) : \Zend\Stdlib\PriorityQueue
Please see \getIterator() for details on the necessity of an internal queue class. The class provided should extend SplPriorityQueue.
string
\Zend\Stdlib\PriorityQueue
toArray(integer $flag = self::EXTR_DATA) : array
By default, returns only the item data, and in the order registered (not sorted). You may provide one of the EXTR_* flags as an argument, allowing the ability to return priorities or both data and priority.
integer
array
top() : mixed
mixed
unserialize(string $data) : void
EXTR_DATA
EXTR_PRIORITY
EXTR_BOTH
queueClass : string
| var |
|---|
string
items : array
| var |
|---|
array
queue : \Zend\Stdlib\SplPriorityQueue


Error messages
Error messages are typically displayed in the form of compiler errors. They occur when the code cannot be successfully compiled, and typically indicate issues such as syntax errors or semantic errors. They can occur at different stages in the compilation process, possibly with the file and line number where the error occurred (when this information can be retrieved), as well as a brief description of the error.
The compiler is organized in several stages:
- starting from the DSP source code, the parser builds an internal memory representation of the source program (typically known as an Abstract Source Tree) made here of primitives in the Box language. A first class of errors messages are known as syntax error messages, like missing the
;
character to end a line, etc. - an expression in the Box language is then evaluated to produce an expression in the Signal language where signals as conceptually infinite streams of samples or control values. The box language actually implements the Faust Block Diagram Algebra, and not following the connections rules will trigger a second class of errors messages, the box connection errors. Other errors can be produced at this stage when parameters for some primitives are not of the correct type.
- the pattern matching meta language allows to algorithmically create and manipulate block diagrams expressions. So a third class of pattern matching coding errors can occur at this level.
- signal expressions are optimized, type annotated (to associate an integer or real type with each signal, but also discovering when signals are to be computed: at init time, control-rate or sample-rate..) to produce a so-called normal-form. A fourth class of parameter range errors or typing errors can occur at this level, like using delays with a non-bounded size, etc.
- signal expressions are then converted in FIR (Faust Imperative Representation), a representation for state based computation (memory access, arithmetic computations, control flow, etc.), to be converted into the final target language (like C/C++, LLVM IR, Rust, WebAssembly, etc.). A fifth class of backend errors can occur at this level, like non supported compilation options for a given backend, etc.
Note that the current error messages system is still far from perfect, usually when the origin of the error in the DSP source cannot be properly traced. In this case the file and line number where the error occurred are not displayed, but an internal description of the expression (as a Box of a Signal) is printed.
Syntax errors
Those errors happen when the language syntax is not respected. Here are some examples.
The following program:
box1 = 1
box2 = 2;
process = box1,box2;
will produce the following error message:
errors.dsp : 2 : ERROR : syntax error, unexpected IDENT
It means that an unexpected identifier as been found line 2 of the file test.dsp. Usually, this error is due to the absence of the semi-column ;
at the end of the previous line.
The following program:
t1 = _~(+(1);
2 process = t1 /<PHONE_NUMBER>;
will produce the following error message:
errors.dsp : 1 : ERROR : syntax error, unexpected ENDDEF
The parser finds the end of the definition (;
) while searching a closing right parenthesis.
The following program:
process = ffunction;
will produce the following error message:
errors.dsp : 1 : ERROR : syntax error, unexpected ENDDEF, expecting LPAR
The parser was expecting a left parenthesis. It identified a keyword of the language that requires arguments.
The following program:
process = +)1);
will produce the following error message:
errors.dsp : 1 : ERROR : syntax error, unexpected RPAR
The wrong parenthesis has been used.
The following program:
process = <:+;
will produce the following error message:
errors.dsp : 1 : ERROR : syntax error, unexpected SPLIT
The <:
split operator is not correctly used, and should have been written process = _<:+;
.
The following program:
process = foo;
will produce the following error message:
errors.dsp : 1 : ERROR : undefined symbol : foo
This happens when an undefined name is used.
Box connection errors
Diagram expressions express how block expressions can be combined to create new ones. The connection rules are precisely defined for each of them and have to be followed for the program to be correct. Remember the operator priority when writing more complex expressions.
The five connections rules
A second category of error messages is returned when block expressions are not correctly connected.
Parallel connection
Combining two blocks A
and B
in parallel can never produce a box connection error since the 2 blocks are placed one on top of the other, without connections. The inputs of the resulting block-diagram are the inputs of A
and B
. The outputs of the resulting block-diagram are the outputs of A
and B
.
Sequencial connection error
Combining two blocks A
and B
in sequence will produce a box connection error if outputs(A) != inputs(B)
. So for instance the following program:
A = _,_;
B = _,_,_;
process = A : B;
will produce the following error message:
ERROR : sequential composition A:B
The number of outputs [2] of A must be equal to the number of inputs [3] of B
Here A = _,_;
has 2 outputs
while B = _,_,_;
has 3 inputs
Split connection error
Combining two blocks A
and B
with the split composition will produce a box connection error if the number of inputs of B
is not a multiple of the number of outputs of A
. So for instance the following program:
A = _,_;
B = _,_,_;
process = A <: B;
will produce the following error message:
ERROR : split composition A<:B
The number of outputs [2] of A must be a divisor of the number of inputs [3] of B
Here A = _,_;
has 2 outputs
while B = _,_,_;
has 3 inputs
Merge connection error
Combining two blocks A
and B
with the merge composition will produce a box connection error if the number of outputs of A
is not a multiple of the number of inputs of B
. So for instance the following program:
A = _,_;
B = _,_,_;
process = A :> B;
will produce the following error message:
ERROR : merge composition A:>B
The number of outputs [2] of A must be a multiple of the number of inputs [3] of B
Here A = _,_;
has 2 outputs
while B = _,_,_;
has 3 inputs
Recursive connection error
Combining two blocks A
and B
with the recursive composition will produce a box connection error if the number of outputs of A
is less than the number of inputs of B
, or the number of outputs of B
is less than the number of inputs of A
(that is the following connection rule is not respected). So for instance the following program:
A = _,_;
B = _,_,_;
process = A ~ B;
will produce the following error message:
ERROR : recursive composition A~B
The number of outputs [2] of A must be at least the number of inputs [3] of B. The number of inputs [2] of A must be at least the number of outputs [3] of B.
Here A = _,_;
has 2 inputs and 2 outputs
while B = _,_,_;
has 3 inputs and 3 outputs
Route connection errors
More complex routing between blocks can also be described using the route primitive. Two different errors can be produced in case of incorrect coding:
process = route(+,8.7,(0,0),(0,1));
will produce the following error message:
ERROR : invalid route expression, first two parameters should be blocks producing a value, third parameter a list of input/output pairs : route(+,8.7f,0,0,0,1)
And the second one when the parameters are not actually numbers:
process = route(9,8.7f,0,0,0,button("foo"));
will produce the following error message:
ERROR : invalid route expression, parameters should be numbers : route(9,8.7f,0,0,0,button("foo"))
Iterative constructions
Iterations are analogous to for(...)
loops in other languages and provide a convenient way to automate some complex block-diagram constructions. All par
, seq
, sum
, prod
expressions have the same form, take an identifier as first parameter, a number of iteration as an integer constant numerical expression as second parameter, then an arbitrary block-diagram as third parameter.
The example code:
process = par(+, 2, 8);
will produce the following syntax error, since the first parameter is not an identifier:
filename.dsp : xx : ERROR : syntax error, unexpected ADD, expecting IDENT
The example code:
process = par(i, +, 8);
will produce the following error:
filename.dsp : 1 : ERROR : not a constant expression of type : (0->1) : +
Pattern matching errors
Pattern matching mechanism allows to algorithmically create and manipulate block diagrams expressions. Pattern matching coding errors can occur at this level.
Multiple symbol definition error
This error happens when a symbol is defined several times in the DSP file:
ERROR : [file foo.dsp : N] : multiple definitions of symbol 'foo'
Since computation are done at compile time and the pattern matching language is Turing complete, even infinite loops can be produced at compile time and should be detected by the compiler.
Loop detection error
The following (somewhat extreme) code:
foo(x) = foo(x);
process = foo;
will produce the following error:
ERROR : stack overflow in eval
and similar kind of infinite loop errors can be produced with more complex code.
[TO COMPLETE]
Signal related errors
Signal expressions are produced from box expressions, are type annotated and finally reduced to a normal-form. Some primitives expect their parameters to follow some constraints, like being in a specific range or being bounded for instance. The domain of mathematical functions is checked and non allowed operations are signaled.
Automatic type promotion
Some primitives (like route, rdtable, rwtable...) expect arguments with an integer type, which is automatically promoted, that is the equivalent of int(exp)
is internally added and is not necessary in the source code.
Parameter range errors
Soundfile usage error
The soundfile primitive assumes the part number to stay in the [0..255] interval, so for instance the following code:
process = _,0 : soundfile("foo.wav", 2);
will produce the following error:
ERROR : out of range soundfile part number (interval(-1,1,-24) instead of interval(0,255)) in expression : length(soundfile("foo.wav"),IN[0])
Delay primitive error
The delay @
primitive assumes that the delay signal value is bounded, so the following expression:
import("stdfaust.lib");
process = @(ba.time);
will produce the following error:
ERROR : can't compute the min and max values of : proj0(letrec(W0 = (proj0(W0)'+1)))@0+-1
used in delay expression : IN[0]@(proj0(letrec(W0 = (proj0(W0)'+1)))@0+-1)
(probably a recursive signal)
[TO COMPLETE]
Table construction errors
The rdtable primitive can be used to read through a read-only (pre-defined at initialisation time) table. The rwtable primitive can be used to implement a read/write table. Both have a size computed at compiled time
The rdtable
primitive assumes that the table content is produced by a processor with 0 input and one output, known at compiled time. So the following expression:
process = rdtable(9, +, 4);
will produce the following error, since the +
is not of the correct type:
ERROR : checkInit failed for type RSEVN interval(-2,2,-24)
The same kind of errors will happen when read and write indexes are incorrectly defined in a rwtable
primitive.
Mathematical functions out of domain errors
Error messages will be produced when the mathematical functions are used outside of their domain, and if the problematic computation is done at compile time. If the out of domain computation may be done at runtime, then a warning can be produced using the -me
option (see Warning messages section).
Modulo primitive error
The modulo %
assumes that the denominator is not 0, thus the following code:
process = _%0;
will produce the following error:
ERROR : % by 0 in IN[0] % 0
The same kind of errors will be produced for acos
, asin
, fmod
, log10
, log
, remainder
and sqrt
functions.
FIR and backends related errors
Some primitives of the language are not available in some backends.
The example code:
fun = ffunction(float fun(float), <fun.h>, "");
process = fun;
compiled with the wast/wasm backends using: faust -lang wast errors.dsp
will produce the following error:
ERROR : calling foreign function 'fun' is not allowed in this compilation mode
and the same kind of errors would happen also with foreign variables or constants.
[TO COMPLETE]
Compiler option errors
All compiler options cannot be used with all backends. Moreover, some compiler options can not be combined. These will typically trigger errors, before any compilation actually begins.
[TO COMPLETE]
Warning messages
Warning messages do not stop the compilation process, but allow to get usefull informations on potential problematic code. The messages can be printed using the -wall
compilation option. Mathematical out-of-domain error warning messages are displayed when both -wall
and -me
options are used.


{% blocktrans %}
Prestashop-Sync Service is maintained by a small team of developers focused
on building powerful e-commerce systems.
If you wish to contact us, please write at<EMAIL_ADDRESS>or use a Contact Form below: {% endblocktrans %}
If you wish to contact us, please write at<EMAIL_ADDRESS>or use a Contact Form below: {% endblocktrans %}


In one of my tasks I needed do some work with objects.
Objects in code are similar to objects in real life in the sense that you refer to them by a name and associate certain preperties with them.
If you made an object to represent a ball, you might call it - 'ballObj'
and give it a property - 'shape'
with the value - 'round'
.
Now in most cases in code you use =
to signify you want to tie a value to what is called a variable (eg. round
), a container for that value (eg. shape
).
But in the case of objects you use something different called key-value pairs.
These make it easier to do certain things with objects that I wont get into but just know that with objects you dont use =
to link the two together you use :
.
This slipped my mind while working away and when I came to test my code... Errors ensued.
On first glance it seemed my code was all written correctly.
I wasn't missing any brackets - ( )
or semi-colons - ;
, which are the usual culprates.
So I checked out what the error messages had to say "Uncaught SyntaxError: Invalid shorthand property initializer"
.
It was telling me I'd used the wrong syntax =
instead of :
when writing my code.
Oops. Quick fix, just had to change the one character and my code worked as intended.
I let the differences in object syntax slip my mind while coding and was genuinly stumped as to why my code wouldn't run.
But by checking out the error message it became clear where I'd gone wrong.
This was a good reminder to myself and is to others, that even if you've learnt something in the past, you can't gaurentee you'll get it right everytime from then on out, we all make mistakes.
But taking the time to figure out where you went wrong can help lessen the chances you'll make it again in the future.
And remember - The Error Message
might seem daunting but it often has some great insight into what's gone wrong.
There was a function I needed to make that could take a string and capitalize the first letter of every word.
To the best of my knowledge JavaScript doesnt have a built in way to do this, however there is a function that will capitalize everything you give it.
So I figured I needed a way to pass that function .toUpperCase()
only the first letter of all the words in my sentence.
I managed to do this by taking the sentence (stored as a string) and using .split(" ")
,creating an array from the string with each word (detected by the presence of a blank space) in its own cell.
From here I ran a function taking the first character in each cell of the array cell[0]
, capitalizing it using the .toUpperCase()
function and then pairing it back together using string concatenation "H" + "ello" -> "Hello"
with the respective word minus that first character using cell.splice(1)
.
All of that was controlled by a map which allows you to call functions on each item in a collection, which in this case was the array made from the original string.
After all the words (cells) had been run through they were joined back into a string again using the .join(" ")
function, connecting the arrays cells with a sapace be each.
The process ran like this:
"hello world" -> ["hello", "world"] -> H + ello & W + orld -> ["Hello", "World"] -> "Hello World"
This is the actual code I wrote:
function capitalize (str){
return str.split(" ").map(x => x[0].toUpperCase() + x.slice(1)).join(" ");
}


Amazon Connect CCP call recording controls
Contact Details
Phone Number
Contact ID
Copy to clipboard
Copy
Recording Status
Start
Stop
Pause
Resume
Auth
Agent Details
Agent Name:
Current Status:
Routing Profile:
Queues :
Enter account number


Toggle navigation
ABOUT
SEAB2015
Brand For Humanity
Co-Partners/Organizers
PROJECTS
EVENTS
BLOG
CONTACT
JOIN US NOW!
CONTACT US AT
First Name
Last Name
D.O.B
Email Address
Invalid Email Address
Country of Origin
Country of Residence
Primary button


Stinky Tofu Projects
NATHAN
About Me
Projects
Contact
Resume
RESUME
CONTACT
phone
email
website
EDUCATION
schools
KEY SKILLS
LICENSES AND CERTIFICATIONS
OBJECTIVES
PROFESSIONAL EXPERIENCE
PROJECTS


{{Infobox prepared food | name = Pandeyuca | image = | caption = A traditional breakfast in Bogotá and the surrounding region consisting of hot chocolate, cheese, and two kinds of bread: almojábana (on left) and pan de yuca on right | alternate_name = | country = | region = | creator = | course = | type = Bread | served = | main_ingredient = Cassava starch, cheese | variations = | calories = | other = }}
Pan de yuca (Spanish for Cassava bread) is a type of bread made of cassava starch and cheese typical of southern Colombia and the Coast Region of Ecuador.
An 1856 watercolor by Manuel María Paz shows cassava bread being prepared by members of the Saliva people in Casanare Province.<ref>{{Cite web | last = Paz | first = Manuel María | authorlink = Manuel María Paz Delgado | title = Saliva Indian Women Making Cassava Bread, Province of Casanare | work = World Digital Library | accessdate = 2014-05-21 | url = http://www.wdl.org/en/item/9017 }}</ref>
{{Reflist}}
{{bread-stub}}


Jan Michael Laranjo
Email<EMAIL_ADDRESS>I am a computer programmer, facing every challenge and always acquiring new knowledge and skills.
- Skills
-
Languages
Java, C#, C++, C, Python, Kotlin
Frameworks
Angular, JUnit, Mockito, Spring, JPA, Hibernate, Espresso, Entityframework, Moq
- Work Experience
-
s IT Solutions(2019 - present)
Working in a department that is responsible for orchestration services
- Coordinating the outsourcing team in India
- Managing the build, release and deployment process of a microservice
- Developed a migration tool that migrates financial institutes into new institutes
MHE & Partners GmbH(2015 - 2019)
Participated in designing and developing a data warehouse tool for managing statistical metadata
- Development of an interface for exporting metadata into inhouse format for creating a database in STATCube
- Created a prototype interface for semi automated notification and transmission of metadata to co-workers
- Writing & Maintaining test suites for metadata dataware house application
- Development of different report systems
- Consulting>
- Education
-
University of Technologies Vienna (2019 - present)
"Software Engineering and Internet Computing" (Master of Science)
University of Technologies Vienna (2014 - 2019)
"Medieninformatik und Visual Computing" (Bachelor of Science)
Bachelor thesis: Development of an Android serious game prototype that focuses on embedding voice training and voice hygiene into the daily routine
HTBLuVA Wien Spengergasse (2007 - 2012)
Computer Science class with focus on media
- Hobbies
-
Traveling, Listening to audio books, programming


The Razer Phone 2 Is Just $299 Right Now
Amazon has the Razer Phone 2 on sale ahead of Black Friday for just $299. The Razer Phone 2 won't be any cheaper on Black Friday so now is the time to get one.
The regular price on the Razer Phone 2 (recently) has been $399. So it's not a very steep discount – still about 25-percent though – but definitely worth taking advantage of.
The Razer Phone 2 is a gaming smartphone. Though it was released over a year ago, so the specs are a bit out of date, but still very usable. Since Razer used the latest specs available at the time, the Razer Phone 2 is still very capable.
Advertisement
It sports a 5.7-inch Quad HD+ 120Hz display, powered by the Snapdragon 845 chipset, with 8GB of RAM and 64GB of storage. That's not a lot of storage, but at least this phone isn't $800 still, like the Google Pixel 4.
Unlike some of the newer gaming phones, this one is an LCD display, instead of an OLED display. It also has a higher refresh-rate than most of the other gaming phones. Coming in at 120Hz. There are many games that are available right now that do support this higher refresh-rate too. So you can really take advantage of it.
Razer also outfitted this phone with dual front-facing stereo speakers. These do support Dolby Atmos. Making it a really great multimedia device.
Advertisement
The bezels are still quite large on the Razer Phone 2. Part of the reasoning for this was to make it easier to hold when gaming, and they wanted it to stay at 16:9, since almost all games support that natively. And not the taller 18:9 or even 21:9 aspect ratio.
The Razer Phone 2 is available unlocked and will work on AT&T and T-Mobile in the US.
You can pick up the unlocked Razer Phone 2 from Amazon right now by clicking here.
Advertisement


8.13. Age-Off Iterators¶
This chapter provides documentation on how to configure the beta feature for data age-off via Accumulo iterators. Age-off allows administrators to set retention periods on data (e.g. 3 months) in order to automatically hide and delete data from tables without manually deleting features.
Currently there are two types of age-off supported - attribute based, and ingest-time based.
8.13.1. Installation¶
The age-off iterators are provided as part of the GeoMesa Accumulo Distributed Runtime jar which can be found in the Installing GeoMesa Accumulo chapter.
8.13.2. Requirements¶
Age-off iterators are applied to individual Accumulo tables - as such, to configure age-off on a simple feature
type, table sharing must be disabled. This may be accomplished by setting the user data string
geomesa.table.sharing='false'
on the simple feature type before calling createSchema
. This check may be
overridden by setting the system property geomesa.age-off.override=true
. This may be desirable for configuring
ingest time age-off on multiple simple feature types, or when it is known that only a single simple feature type
is present in a catalog. Note that configuring attribute-based age-off on multiple features in a shared catalog
will generally not work.
8.13.3. Configuration¶
Age-off can be configured through the GeoMesa command-line tools, using the configure-age-off
command.
See Accumulo Command-Line Tools for an overview of the command-line tools.
Warning
If age-off iterators have previously been configured manually, it is suggested to remove them before using any provided tools, in order to ensure consistency in naming and priority.
<IP_ADDRESS>. Viewing Current Age-Off¶
Any configured age-off iterators can be shown via the command line tools configure-age-off
command:
$ geomesa-accumulo configure-age-off -c test_catalog -f test_feature --list
INFO Attribute age-off: None
INFO Timestamp age-off: name:age-off, priority:10, class:org.locationtech.geomesa.accumulo.iterators.AgeOffIterator, properties:{retention=PT1M}
Note that this may not display any manually configured age-off iterators, as the iterator name may not match.
<IP_ADDRESS>. Ingest Time Age-Off¶
Ingest time age-off will use the timestamp associated with the Accumulo data value to validate retention.
Note
Ingest time age-off requires that the Accumulo tables are configured with system timestamps, instead of the default logical timestamps. See Accumulo Logical Timestamps for more information.
Ingest time age-off can be configured via the command line tools configure-age-off
command, without specifying
a date attribute:
$ geomesa-accumulo configure-age-off -c test_catalog -f test_feature --set --expiry '1 day'
This will remove any existing age-off configuration and replace it with the new specification.
<IP_ADDRESS>. Attribute Age-Off¶
Attribute age-off will use a date-type attribute to validate retention.
Attribute age-off can be configured via the command line tools configure-age-off
command by specifying
a date attribute:
$ geomesa-accumulo configure-age-off -c test_catalog -f test_feature --set --expiry '1 day' --dtg my_date_attribute
This will remove any existing age-off configuration and replace it with the new specification.
<IP_ADDRESS>. Removing Age-Off¶
Any configured age-off iterators can be cleared via the command line tools configure-age-off
command:
$ geomesa-accumulo configure-age-off -c test_catalog -f test_feature --remove
This will remove both attribute and ingest time age-off.
8.13.4. Statistics¶
As features are aged off, summary data statistics will get out of date, which can degrade query planning. For manageable data sets, it is recommended to re-analyze statistics every so often, via the stats-analyze command. If the data set is too large for this to be feasible, then stats can instead be disabled completely via geomesa.stats.generate.
8.13.5. Forcing Deletion of Records¶
The GeoMesa age-off iterators will not fully delete records until compactions occur. To force a true deletion of data on disk, you must manually compact a table or range. When compacting an entire table you should take care not to overwhelm your system. You may start a compaction through the Accumulo shell:
# compact a single table
compact -t geomesa.mycatalog_mytype_z2
# compact all tables for a catalog
compact -p geomesa.mycatalog.*


Account Page
My Progress
See your progress and how much you need to reach your target
Open
Your Progress
Reached:
Target
You need
more to reach your target.


//Demonstrates dynamic initialization of vars. //Static vars are, essentually, global vars. class Test { I32 time; U8 name[8]; }; Test g1[]={ {10,"Name1"}, {(tS%10.0)*100,"Name2"}, //Dynamic initialization {30,"Name3"} }; D(g1,sizeof(g1)); "Time 1:%d\n",g1[1].time; U0 Main1() { static Test s1[]={ {10,"Static1"}, {(tS%10.0)*100,"Static2"}, //Dynamic initialization {30,"Static3"} }; D(s1,sizeof(s1)); "Time 2:%d\n",s1[1].time; } Main1; /*Now, we'll use the data heap glbl option to force global vars onto the data heap. You can turn the data heap flag on and off within your programs, leaving ones which need initialization on the code heap. You can't dynamically initialize data heap glbls--they are consts. This might be a silly point, but might res in odd differences, perhaps from the order things are evaluated. Data heap glbls are good for AOT modules because they don't take-up room in the .BIN.Z file. */ #ifjit #exe {Option(OPTf_GLBLS_ON_DATA_HEAP,ON);}; Test g2[]={ {10,"name1"}, {(tS%10.0)*100,"name2"}, //No dynamic initialization--cvted to const {30,"name3"} }; D(g2,sizeof(g2)); "Time 3:%d\n",g2[1].time; U0 Main2() { static Test s2[]={ {10,"static1"}, {(tS%10.0)*100,"static2"}, //No dynamic initialization--cvted to const {30,"static3"} }; D(s2,sizeof(s2)); "Time 4:%d\n",s2[1].time; } Main2; #exe {Option(OPTf_GLBLS_ON_DATA_HEAP,ON);}; #endif '\n';


Concert in aid of teenager's Borneo conservation trip
by Gemma JarvisA concert is being held to raise money towards a conservation trip to Borneo to help the plight of indegenious people and wildlife struggling in today's climate.
Hazel Whittle, 16, from Woodbridge, is hosting an evening of Bornean entertainment including music performed by herself and friends as well as home cooked food to honour her forthcoming journey with Camps International.
Working to help plant trees, provide a kindergarten and a community hub for the isolated villagers in the Kinabatangan Valley in North East Borneo, Hazel is passionate about the plight of the area and said: "In this time when we face a climate emergency, this work has never been more important.
"I have always had a fascination with rainforest ecosystems and the amazing and diverse life forms they support.
"So when I heard there was an opportunity to join an expedition to Borneo with Camps International and be involved in conservation work as well as working alongside local communities, I thought this was an amazing opportunity to make a positive impact on such a special environment."
Hazel has raised £345 so far and is hoping to raise more with her concert held on Sunday, November 17 at Burness parish rooms, the Street, Melton.
Tickets cost £10 and are available at<EMAIL_ADDRESS>To donate, press here.


| 45 | (A) | Systenis of owt of ..... .... hym to Rome |
| 45 | (C) | ¶ Senscyvs of surreye sente hym to rome |
| 45 | (D) | Systynes of Surrie sent hym to Rome |
| 44 | (E) | ¶ Senstius of surry . sente hym to rome |
| (Ex) | ---- no text ---- | |
| 45 | (L) | sensteus out of surye sent hym to rome |
| 40 | (P) | Cytesens of surry sent hym to Rome |
| 45 | (U) | Senstius of Surre / sent him to Rome |
| (V) | ---- no text ---- |