I have not written anything in a long time. I told myself I would be better about writing, but it’s been difficult. As we all know, the world has drastically changed since my last post in January. Covid. George Floyd. Presidential election. Online college. A hundred other things I am forgetting.
Part of the reason I haven’t written anything is because my posts are generally about classes, my computer science journey, my opinions on life and values, and random questions I answer. In short, they are really all about me. And how can I write about myself when there are clearly more important issues to be addressed? So then, do I talk about these bigger issues? I decided not to because I don’t know about these issues more than the average person. I don’t want people to be misinterpreting my words, or if I spread misinformation because I don’t know all the facts. Also, why would you be going to my website to read about these things? I am not a reliable news source. There is no “fact check” on my posts.
So what am I an expert on? I would say that I am only an expert in my experience. Which is what I write about. (Wow, how deep Teddy.) And recently, I’ve heard from Daniel Sloss that when your friend has someone close to them pass away, you should be your normal self around them. You need to be the same person, so that they can process the difference in their life. So that they can process the pain. They need to know that the person they grew up with is there for them, not this new fake person walking on eggshells. Of course, we should be empathetic and caring as well, but should that not already be in your current personality? So anyways, that is part of the reason I am writing again. Because sometimes people need to know that not everything has changed in the world. The sun still rises and sets. Tesla stock only goes up. And I write in my blog. And moreover, besides for my 3 readers, it’s for my sanity. So that I too have a rock in this drastically changing world.
Another part of why I haven’t written anything is because my life has changed quite a bit. Even before Covid, I was struggling with motivation issues among other things. I couldn’t sleep at night. I couldn’t find a reason to get out of bed. And Covid did not make that better. There have been quite a few changes in my relationships with people. I don’t talk to some people now that probably knew me better than anyone. People who I couldn’t have imagined not having in my life. Some of this is because of my choice, some by their choice. I’ve also gone from being a senior at college to working full time starting at the lowest level at my company. Things are different.
And I guess by my previous reasoning, this is all the more reason that I should have kept writing: to have something that’s the same throughout all of the changes. But I didn’t. I kept being too busy and preoccupied to write. The times I wasn’t too busy, I was too tired to write.
And I guess that’s how we get to my first point: You will never have time unless you make time for it.
I didn’t make time to write in my blog. I have quite a few ideas written down, but I never put in the time to flesh them out. So it never happened. After the Olympic trials, I stopped exercising. I know how important exercise is. But I never made time for exercise. So I never exercised. I told myself it was important to maintain my friendships since humans are social creatures, and it’s even more important during covid since it’s so easy to stop talking to people and just lay in bed looking at Youtube videos. But I never made the time for it.
I can list a bunch of other things I didn’t make time for. But you get the point. But recently (which means sometime from 3 months ago to maybe 5 minutes ago), I’ve been making the time to exercise.  I’ve been making time to walk with my parents every morning to have some family bonding time and get some sunlight. I’ve been making time to sleep.
My coach (who was a world champion) used to tell me that I had to come early to tournaments to warm up, I had to stretch before every match, I can’t forget my towel and should use it every 6 points, and these other 5 billion little things I had to do. And he told me that doing all of these little things that most other players neglect makes you more prepared to win than others.
One of the biggest challenges I’ve overcome is this exercising thing. Exercising for me when I was playing pingpong was easy, because it’s necessary in sports to be in top physical condition. Now that I’ve stopped playing pingpong competitively, it seemed kind of lame to me to exercise to keep in shape, maintain my mental health, and regulate my sleep schedule. But I guess in some ways, it is even more important now.
Furthermore, I had the same mentality for exercise that I had when I was playing competitively: I had to push myself to the limit, to be the best. But this is really hard, when there is nothing to compete for now. So I didn’t really have any motivation to run, because I would just disappoint myself in how much I could run, and I’d rather be disappointed in myself not running since that’s so much easier. One day, I told myself that it was okay to take breaks, and not push myself to the limit when I exercise, and the goal was just to get outside. And this shift in mentality is what made me more consistent at exercising. It relieved the stress that I couldn’t perform to my expectation.
So I guess that’s how we get to my second point: It’s okay to take breaks. It’s okay to not exhaust yourself to death. You don’t need that extra pressure and expectation on yourself.
Maybe I would’ve been better at pingpong if I didn’t feel like I had to push myself to the limit every time. Maybe it would have been more fun for me and I wouldn’t burn out.  Just to clarify, to be the best, you do have to push yourself past your limits. But it doesn’t happen in one day. It’s small gradual steps, and you should enjoy the process and have fun while doing it. And it is not fun if you have expectations to run 5 miles when you can’t even run 1. It’s okay to take breaks. It’s okay to walk.
Happiness takes effort.
I think that’s one of the strangest things that I’ve realized recently. At least, it applies to me. Some people don’t have to put in effort to be happy. Just like people’s mental strength sports. When Liu Guoliang (Grand Slam champion and head coach of the Chinese National Team now) was asked if he did any mental training for table tennis, he said (paraphrased), “We don’t do mental training. We just trust ourselves.” And I think the same is for happiness. For some people it comes more naturally than others. But like I said, I can only speak from my experience.
I don’t like the idea that happiness takes effort. It seems like it should be natural. Like...why is my natural state of being not happy? It seems to me like evolution messed up.
Why are good habits so easy to break, but bad habits so hard to break?
I always thought that some day I would just eventually realize I was happy. But if I don’t put in the time and the effort, I won’t be. I need to have a regular sleep schedule, exercise, go outside, limit social media use, talk to my friends, and all these other things so I have a fighting chance. So I guess that’s the third point. Happiness takes effort.
I don’t mind friends who don’t message me these days. I understand how hard it is to maintain friendships when everything is online. We are all going through our own personal struggles and dealing with our demons. That’s fine. What I do mind are people who always expect me to reach out first and complain that we don’t talk anymore when they never put in the effort to be the person to reach out first. If I wanted to talk to NPCs, I’d go play Dark Souls 2 or something.
 Recently, two of my former students told me how much of an impact I had on their learning for the class. There were also some Overheard at Berkeley posts about me that were very touching to read. I’ve had pingpong friends tell me how much I’ve not only been their inspiration in pingpong, but also how I’ve inspired them in life. I have handwritten letters from people who tell me they are so grateful they’ve met me, and that I am one of their role models. I guess this may sound like humble bragging. I don’t care how it sounds, because sometimes you have to share the small victories in your life.
And my first reaction is always confusion. Who? Me? Are you sure you didn’t write this to the wrong person? I’m just a kid trying to figure out how to live. I don’t know anything. If you want a real role model, you should find my mom. She knows everything.
And I also do my best to thank the people who have been my role models, who have been my inspiration, who have helped me through my journey. Mentors who’ve guided me through computer science when I didn’t even know if I wanted to do computer science, mentors at Freenome who took a risk on a goofball who puts memes in his technical presentations, my amazing CS170 TA who is the only reason I was also able to be inspire other kids in CS170, table tennis world champions who decided to coach me when no one even knew who I was in the table tennis community.
But I also can’t forget about the true champions: our friends and family that we interact with on a daily basis. People who check up on you to make sure you’re okay often, make conversations about random things, and enjoy each other’s presence. I asked one of my friends recently who are her role models, and she said that the perfect role model is probably Leslie Knope.
So I guess my final point is a quote by Leslie Knope: “It’s a lesson I have learned over and over again, but it bears repeating: no one achieves anything alone.”


{{{score}}}
{{{scoreBar}}}
| Attempts: | {{{qAttempts}}} |
| Score: | {{{qScore}}} |
{{#prevQNumber}} Previous question {{/prevQNumber}} {{^prevQNumber}} Previous question {{/prevQNumber}}
{{#nextQNumber}} Next question {{/nextQNumber}} {{^nextQNumber}} Next question {{/nextQNumber}}


To keep my discussion from wandering too far afield I left out a number of useful features of J. I will discuss some of them briefly here.
The Edit|Configure menu allows you to change the interpreter's settings. Look through the tabs to see what is available. Note especially the Folders tab, which lets you specify the folders Project Manager and Find In Files will use to organize your work.
In addition to the configuration variables, you can have startup commands executed whenever J starts, or you can specify a script in the command line that will run after J has been initialized. The startup sequence is described in detail here. If you just want to run some startup commands, jump to section 4.4.2 which describes the user startup file.
1. The command line is parsed into words. The words are assigned to the variable ARGV_z_. The first word is the name of the J executable. The subsequent words, the parameters, tell J what to do. The first parameter that is not a switch is the name of the command script which is the J script you want to execute.
2. If the first parameter is the -jijx switch, the normal J IDE window, where you type commands and see them executed, will not be created.  Except for creating the IDE window, the J startup sequence will be followed as described below, and the -jprofile switch will be honored.
3. If the command line contains the -jprofile switch, you are taking full control of J's startup. Your command script will be executed instead of J's normal start sequence. Make sure you get it right! If the command script is omitted, J will run ~system\extras\util\minijx.ijs which will give you something to start with.
4. If you don't specify the -jprofile switch, you get J's normal startup sequence which winds up by executing the command script. The normal startup sequence is contained in the script ~bin\profile.ijs, which goes through the following steps:
4.1. The variable SYSTEMFOLDERS_j_ is created, containing the paths J uses to get to your home directory, the system, etc. You can look at this variable after J has started to see what folders are defined. If you want to change these directories, you do so by creating the script ~bin\profilex.ijs. Use ~bin\profilex_template.ijs as the template for creating your custom script.
4.2. Normal startup continues by running ~system\extras\util\boot.ijs. This file begins by creating any missing directories referred to in SYSTEMFOLDERS; then it loads the J system files sysenv.ijs, stdlib.ijs, colib.ijs, and break.ijs from ~system\main. See below under "Seeing What Scripts Have Been Loaded" for how to get the complete list of scripts that are executed.
4.3. Next, if the J executable was Jconsole, the console window is created and the console startup file ~config/startup_console.ijs is executed. User customization is not performed.
4.4. If the J executable was not Jconsole, the user customization steps are performed:
4.4.1. The J IDE is loaded and the configuration files are executed. The configuration files are: (1) the system configuration file ~system\extras\config\stdcfg.ijs, (2) the user configuration file ~config\config.ijs, (3) the addons configuration file ~addons\config\config.ijs. These files are applied in order, with a later file's setting overriding any one from an earlier file. The user configuration file is the one that holds the settings from the Edit|Configure menu.
4.4.2. After configuration, the user startup file is executed. This file is named in the Edit|Configure|Startup menu, where a default is given that you may override. This file is where you put the definitions that you want executed every time J starts. The file is executed in the base locale.
4.5. Finally, the command script is loaded if there is one. Normally this is a file, but if the inline script indicator -js is given in place of the name of the command script, the words of ARGV_z_ following the -js are taken to be lines of J code, and they are put into the verb ARGVVERB which is used as the command script. The command script is executed in the base locale. If the command script is omitted, nothing is run.
5. When the startup sequence finishes, J may wait for user input. This input may come from a form, or, if -jijx was not specified, from the IDE window; but if neither of these sources of input exists, the interpreter will exit with no prompt. If your program expects input from another source, such as a timer or socket interrupt, you need to display a dummy form to keep J from terminating.
Public Names
The noun PUBLIC_j_ defines short names and the corresponding full form. The short names may be used in open or load verbs. Items of PUBLIC_j_ are lines of a table:
2 {. PUBLIC_j_
+--------+-----------------------------------+
|afm |~system\classes\plot\afm.ijs |
+--------+-----------------------------------+
|bigfiles|~system\packages\files\bigfiles.ijs|
+--------+-----------------------------------+
If you want to define your own names, you may add them to PUBLIC_j_ in your startup file. The easiest way to do this is to use the buildpublic_j_ verb:
buildpublic_j_ 0 : 0
langexten C:\myfiles\langexten
utils C:\myfiles\utils
)
After executing the lines above, I can open one of my files simply by typing
open 'langexten'
Seeing What Scripts Have Been Loaded
The foreign 4!:3 gives you a log of all the scripts that have been loaded since startup. You can use this at any time. If you run 4!:3 immediately after startup, it will show you the sequence of scripts run at startup:
4!:3''
+-----------------------+---------------------------...
|C:\j602\bin\profile.ijs|C:\j602\system\extras\util\...
+-----------------------+---------------------------...
That's a lot of files. If we open the boxes we can see the list more easily:
> 4!:3''
C:\j602\bin\profile.ijs
C:\j602\system\extras\util\boot.ijs
C:\j602\system\main\sysenv.ijs
C:\j602\system\main\stdlib.ijs
C:\j602\system\main\colib.ijs
C:\j602\system\main\break.ijs
C:\j602\system\main\winlib.ijs
C:\j602\system\extras\util\jadefull.ijs
C:\Documents \Henry Rich\j602-user\config\winpos.ijs
C:\j602\system\extras\config\scripts.ijs
C:\j602\system\extras\util\jijs.ijs
C:\j602\system\extras\util\cfgread.ijs
C:\j602\system\extras\config\colordef.ijs
C:\j602\system\extras\config\stdcfg.ijs
C:\Documents \Henry Rich\j602-user\config\config.ijs
...
Dyad # Revisited
x # y does not require that x be a Boolean list. The items of x actually tell how many copies of the corresponding item of y to include in the result:
1 2 0 2 # 5 6 7 8
5 6 6 8 8
Boolean x, used for simple selection, is a special case. If an item of x is complex, the imaginary part tells how many cells of fill to insert after making the copies of the item of y . The fill atom is the usual 0, ' ', or a: depending on the type of y, but the fit conjunction !.f may be used to specify f as the fill:
1j2 1 0j1 2 # 5 6 7 8
5 0 0 6 0 8 8
1j2 1 0j1 2 (#!.99) 5 6 7 8
5 99 99 6 99 8 8
Finally, a scalar x is replicated to the length of y . This is a good way to take all items of y if x is 1, or no items if x is 0 .
Boxed words to string: Monad ;:^:_1
;:^:_1 y converts y from a list of boxed strings to a single character string with spaces between the boxed strings.
;:^:_1 ('a';'list';'of';'words')
a list of words
Spread: #^:_1
x #^:_1 y creates an array with the items of y in the positions corresponding to nonzero items of the Boolean vector x, and fills in the other items. +/x must equal #y .
1 1 0 0 1 #^:_1 'abc'
ab c
You can specify a fill atom with !. :
1 1 0 0 1 #^:_1!.'x' 'abc'
abxxc
Choose From Lists Item-By-Item: monad m}
Suppose you have two arrays a and b and a Boolean list m, and you want to create a composite list from a and b using each item of m to select the corresponding item of either a (if the item of m is 0) or b (if 1). You could simply write
m {"_1 a ,. b
and have the answer. There's nothing wrong with that, but J has a little doodad that is faster and uses less space, as long as you want to assign the result to a name. You write
name =. m} a ,: b
(assignment with =: works too). This form does not create the intermediate result from dyad ,: . If name is the same as a or b, the whole operation is done in-place.
More than two arrays may be merged this way, using the form
name =. m} a , b , ... ,: c
in which each item of m selects from one of a, b, ..., c . The operation is not done in-place but it avoids forming the intermediate result.
Recursion with $: and Memoization with M.
In tacit verbs, recursion can be performed elegantly using the verb $:, which stands for the longest verb-phrase it appears in (that is, the largest anonymous verb, created by parsing the sentence containing the $:, whose execution resulted in executing the $:). Recursion is customarily demonstrated with the factorial function, which we can write as:
factorial =: (* factorial@<:) ^: (1&<)
factorial 4
24
factorial(n) is defined as n*factorial(n-1), except that factorial(1) is 1. Here we just wrote out the recursion by referring to factorial by name. Using $:, we can recur without a name:
(* $:@<:) ^: (1&<) 4
24
$: stands for the whole verb containing the $:, namely (* $:@<:) ^: (1&<) .
Recursive verbs often benefit from memoization, which is the technique of remembering the operands to a function and the results they produced, and then, if the function is later invoked with identical operands, returning the saved results rather than recomputing them. The technique is obviously applicable only to pure functions that have no side effects and whose result is completely specified by the operands. (In the cave paintings associated with the ancient culture known to archaeologists as PL/I, such a function was indicated with the rune reducible).
u M. is a verb identical to u, but memoized. When the memoized verb is executed, the result of a previous evaluation with the same operands may be returned. Whether a previous result will in fact be returned depends on the implementation of the interpreter. As of J6.02, the interpreter remembers only small nonnegative integral operands.
The memoization table is initialized when the phrase u M. is parsed. This means that memoization is ineffective if a sentence is parsed more than once:
for_i. 3 2 1 do. u M. i end.
will not be memoized because u M. is parsed each time it is executed. However, in each of the forms
mu =: u M.
for_i. 3 2 1 do. mu i end.
and
u"0 M. 3 2 1
the verb will be memoized.
x u/ y is x u"(lu,_) y where lu is the left rank of u . Thus, each cell of x individually, and the entire y, are supplied as operands to u .
The definition is simplicity itself, and yet many J programmers stumble learning it. I think the problem comes from learning dyad u/ by the example of a multiplication table.
The key is to note that each cell of x is applied to the entire y : cell, not item or atom. The rank of a cell depends on the left rank of u . The multiplication table comes from a verb with rank 0:
1 2 3 */ 1 2 3
1 2 3
2 4 6
3 6 9
You can control the result by specifying the rank of u :
(i. 2 2) ,"1/ 8 9
0 1 8 9
2 3 8 9
(i. 2 2) ,"0 _/ 8 9
0 8 9
1 8 9
2 8 9
3 8 9
These results follow directly from the definition of dyad u/ . fndisplay shows the details:
defverbs 'comma'
(i. 2 2) comma"1/ 8 9
+---------------+---------------+
|(0 1) comma 8 9|(2 3) comma 8 9|
+---------------+---------------+
(i. 2 2) comma"0 _/ 8 9
+-----------+-----------+
|0 comma 8 9|1 comma 8 9|
+-----------+-----------+
|2 comma 8 9|3 comma 8 9|
+-----------+-----------+
The cartesian product xxy of two sets x and y is the set of all combinations (a,b) where a is an element of x and b is an element of y . The cartesian product can be written in elementary J as ,"_1 _"_ _1 (or, if the items have rank 0, by the table adverb ,"0/), as seen in this example where we box each result:
'io' <@,"_1 _"_ _1 'nfd'
+--+--+
|in|on|
+--+--+
|if|of|
+--+--+
|id|od|
+--+--+
J has a verb to produce the cartesian product of any number of sets. Monad { takes a list of boxes y, where each box contains a set, and produces the cartesian product of the atoms of all the sets, with each combination boxed. The leading atom of the first set is concatenated with each atom of the second set in turn, each combination being boxed, and then the next atom of the first set is concatenated with each item of the second set, and so on until the first set is exhausted. Then, if there are more sets, each is processed in turn, with each atom of the new set being appended, inside the box, to each atom of the previous product. If you follow this description, you will see that the shape of the result will be ; $&.> y . To make sure you understand, verify for yourself the results of { 'pl';'aio';'ntp' and { (i. 2 3);(i. 3 2) .
I will just illustrate Boolean dyad m b. by example. m b. is a verb with rank 0. m, when in the range 0-15, selects the Boolean function:
9 b./~ 0 1
1 0
0 1
u/~ 0 1 is the function table with x values running down the left and y values running along the top. 9 is 1001 binary (in J, 2b1001), and the function table of 9 b. is 1 0 0 1 if you enfile it into a vector. Similarly:
, 14 b./~ 0 1
1 1 1 0
You can use m b. in place of combinations of Boolean verbs. Unfortunately, comparison verbs like > and <: have better performance than m b., so you may have to pay a performance penalty if you write, for example, 2 b. instead of >, even though they give the same results on Booleans:
>/~ 0 1
0 0
1 0
|
Equivalent J verbs for m b. for different values of m |
|||||||||||||||
|
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
|
0"0 |
*. |
> |
["0 |
< |
]"0 |
~: |
+. |
+: |
= |
]&-. |
>: |
[&-. |
<: |
*: |
1"0 |
Bitwise Boolean Operations on Integers and Characters
When m is in the range 16-31, dyad m b. specifies a bitwise Boolean operation in which the operation (m-16) b. is applied to corresponding bits of x and y . The operands may be integers or literal (either 8- or 16-bit).
For example, since 6 b. is exclusive OR, 22 b. is bitwise exclusive OR:
5 (22 b.) 7
2
The XOR operation is performed bit-by-bit.
Dyad 32 b. is bitwise left rotate: bits shifted off the end of the word are shifted into vacated positions at the other end.
Dyad 33 b. is bitwise unsigned left shift. x is the number of bits to shift y (positive x shifts left; negative x shifts right; in both cases zeros are shifted into vacated bit positions):
2 (33 b.) 5
20
Dyad 34 b. is bitwise signed left shift: it differs from the unsigned shift only when x and y are both negative (i. e. right shift of a negative number), in which case the vacated bit positions are filled with 1.
If you use shift and rotate, you may need to know the word-size of your machine. One way to do that is
>: 2 ^. | _1 (32 b.) 1
32
Operations Inside Boxes: u L: n, u S: n
u&.> is the recommended way to perform an operation on the contents of a box, leaving the result boxed. It is the idiom used most often by J coders and the first one to be supported by special code when performance improvements are made in the interpreter.
Sometimes your operations inside boxes require greater control than u&.> can provide. For example, you may need to operate on the innermost boxes where the boxing level varies from box to box. In these cases consider using u L: n which has infinite rank. It goes inside the operands and applies u to contents at boxing level n .
The monadic case u L: n y is the simpler one. It is defined recursively. If the boxing level of y is no more than n, the result is u y . Otherwise, u L: n is applied to each opened atom of y, and the result of that is boxed. The effect is that u is applied on each level-n subbox and the result replaces that subbox, with outer levels of boxing intact. For example,
]a =. 0;(1 2;3 4 5);<<6;7 8;9
+-+-----------+-----------+
|0|+---+-----+|+---------+|
| ||1 2|3 4 5|||+-+---+-+||
| |+---+-----+|||6|7 8|9|||
| | ||+-+---+-+||
| | |+---------+|
+-+-----------+-----------+
A boxed noun.
L. a
3
Its boxing level is 3.
# L:0 a
+-+-----+---------+
|1|+-+-+|+-------+|
| ||2|3|||+-+-+-+||
| |+-+-+|||1|2|1|||
| | ||+-+-+-+||
| | |+-------+|
+-+-----+---------+
The contents of each innermost box (where boxing level is 0) is replaced by the number of items there.
2&# L:1 a
+---+---------------------+-------------------+
|0
0|+---+---+-----+-----+|+-----------------+|
| ||1 2|1 2|3 4 5|3 4 5|||+-+-+---+---+-+-+||
| |+---+---+-----+-----+|||6|6|7 8|7 8|9|9|||
| | ||+-+-+---+---+-+-+||
| | |+-----------------+|
+---+---------------------+-------------------+
The atoms of each level-1 box are duplicated. Note that in the first box of a the scalar contents were duplicated, while in the second box it is the boxes that were duplicated. This behavior follows from the definition. The boxing level of a is 3, so each item
is opened and examined. The contents of the first two boxes have boxing level 0 and 1, so 2&# is applied to them; but in the first box those contents are the numbers while in the second box they are boxes. You must not think that L:1 operates only on boxes; what it does depends on the levels of the other boxes in the operand.
# L:2 a
+-+-+-+
|1|2|1|
+-+-+-+
Similarly for level-2 entities.
# L:3 a
3
Since a has boxing level 3, # L:3 a is equivalent to # a .
# L:_2 a
+-+-+---+
|1|2|+-+|
| | ||3||
| | |+-+|
+-+-+---+
Negative level -n means ((level of y) minus n). Note that this does not mean 'n levels up from the bottom of each branch of y'. That would result in u's being applied at different levels in the different items of y; instead, the level at which u is to be applied is calculated using the level of the entire y .
The dyadic case x u L: n y is similar, but you need to know how the items of x and y correspond. During the recursion, as long as both x and y have a higher boxing level than the one specified in n, the atoms of x and y are matched as they would be matched in processing a verb with rank 0 0 (with replication of cells if necessary). If either operand is at the specified level, it is not changed as the items of the other operand only are opened. When both operands are at or below the specified boxing level, u is applied between them. The results of each recursion are boxed; this will give each the deeper boxing level of the two operands at each application of u .An example:
(0 1;<2;3) +L:0 (10 20)
+-----+-------------+
|10 21|+-----+-----+|
| ||12 22|13 23||
| |+-----+-----+|
+-----+-------------+
y was passed through and applied to each level-0 entity.
(0 1;<2;3) +L:0 (<<10 20)
+-------+-------------+
|+-----+|+-----+-----+|
||10 21|||12 22|13 23||
|+-----+|+-----+-----+|
+-------+-------------+
Once again y was applied to each entity, but because it has boxing level 2, all the results have boxing level 2.
The conjunction S: is like L:, but instead of preserving the boxing of the operands it accumulates all results into a list:
(0 1;<2;3) +S:0 (<<10 20)
10 21
12 22
13 23
Like a diamond earring that adds a sparkle to any outfit, the fit conjunction !. is a general-purpose modifier whose interpretation is up to the verb it modifies. We have seen !.f used to specify the fill atom for a verb, and to alter the formatting of monad ": . Its other important use is in specifying the comparison tolerance for comparisons. A comparison like x = y calls two operands equal if they are close, where close is defined as differing by no more than the comparison tolerance times the magnitude of the larger number. If you want exact comparison, you can set the comparison tolerance to 0 using !.0 :
1 (=!.0) 1.000000000000001
0
1 = 1.000000000000001
1
Tolerant comparison is used in the obvious places--verbs like dyad =, dyad >, and dyad -:--and also in some unobvious ones, like the verbs monad ~., monad ~:, and dyad i., and the adverb /. . For all of these you can specify comparison tolerance with !.f . You may wonder whether an exact comparison using !.0 is faster than a tolerant comparison. The answer is yes, but often not by much. There is one important exception: if the comparison is used for finding equal items whose rank is greater than 0 (or are complex numbers), exact comparison can be much faster. So, if x has rank 2 or higher, it's worth the trouble to write x u/.!.0 y or x i.!.0 y; similarly use ~.!.0 y, ~:!.0 y, and x e.!.0 y if y has rank greater than 0.
i.!.0 uses a completely different algorithm from dyad i. . If performance analysis shows that dyad i. is taking a lot of time, you might get an improvement by using i.!.0, even if what you are comparing is not numeric.
The f in !.f can be no larger than about 2^_34 . The reason for this is that there is much special code in J for handling integer operands, and for speed it assumes that comparison tolerance cannot affect integer comparisons.
The foreign 9!:19 y can be used to change the default comparison tolerance, and 9!:18 '' will return the current setting.
Right Shift: Monad |.!.f
One of my personal favorites is the infinite-rank verb monad |.!.f , defined as _1&(|.!.f); in other words it shifts y right one place, discarding the last item and shifting an item of fs into the first position.
Generalized Transpose: Dyad |:
Dyad |: has rank 1 _ . x |: y rearranges y so that the axes given in x become the last axes of the result. So, if y has rank 3, 0 |: y puts the axes of y into the order 1 2 3 0 and 0 2 |: y puts them into the order 1 3 0 2 . For example:
i. 2 3 4
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
16 17 18 19
20 21 22 23
0 |: i. 2 3 4
0 12
1 13
2 14
3 15
4 16
5 17
6 18
7 19
8 20
9 21
10 22
11 23
Formally, putting the axes into an order p means that (<p{x) { p |: y is the same as (<x) { y . I wish I could give you an intuitive definition but I can't.
An item of x can be negative to count axes from the end. The Dictionary shows how you can use boxed x to take elements along diagonals of y .
Monad i: and Dyad i:
Monad i: is like monad i., but its interval is centered on 0 rather than starting at 0:
i: 5
_5 _4 _3 _2 _1 0 1 2 3 4 5
i: _5
5 4 3 2 1 0 _1 _2 _3 _4 _5
Monad i: can also take a complex operand to specify a different spacing between items of the result.
Dyad i: is like dyad i., but it gives the index of the last occurrence (or #x if there is none).
Fast String Searching: s: (Symbols)
If you find your program taking a lot of time matching strings, you can create symbols representing the strings and then match the symbols rather than the strings themselves. The interpreter uses special code to make symbol-matching very fast.
Symbol is an atomic data type (like numeric, literal, and box). In a noun of the symbol type, each atom represents a boxed character string. You create a symbol with monad s: which has infinite rank. s: y takes an array of boxed strings y and creates an array of symbols of the same shape as y :
]sym =. s: 2 2$'abc';'def';'ghi';'jk'
`abc `def
`ghi `jk
$sym
2 2
The '`' characters are a clue that sym is an array of symbols. The value of the top-left atom of sym is not '`abc' or 'abc'; it is a value understood only by the interpreter. The interpreter chooses to display the text associated with the symbol, but that text is actually stored in the interpreter's private memory.
y in s: y can be a character string which is chopped into pieces using the leading character as a separator; each piece is then converted to a symbol. This is a handy way of creating a short list of symbols:
s: '`abc`ghi'
`abc `ghi
Symbols can be operands of any verb that does not perform arithmetic; in addition, comparison between symbols is allowed with 'less than' defined to mean 'earlier in alphabetical order'.
a =. s: '`abc`def`ghi`jk'
defines a list of 4 symbols.
a i. s:<'ghi'
2
We create a symbol to represent 'ghi' and find that in the list.
a i. <'ghi'
4
Note: the boxed string <'ghi' is not a symbol, so it is not found in the list.
Dyad s: has a number of forms for operating on symbols. The only one of interest to us here is 5 s: y which converts each symbol in y to its corresponding boxed string:
5 s: 3 1 { a
+--+---+
|jk|def|
+--+---+
When a string is converted to a symbol, the interpreter allocates internal resources to hold the string's value and other information. There is no way to tell the interpreter to free the resources for a single string; this can be a problem if your symbol table is large and changes dynamically. It is possible to clear the entire symbol table (using y=.0 s: 10 and 10 s: y), but doing so invalidates any symbols previously created by s: y .
If you would like to do high-speed matching but what you want to match is not a string, consider converting to strings using 5!:5 <'y' which converts the variable named y to string form.
Fast Searching: m&i.
x i. y usually starts by creating a hash table of x and y and then looks for matches in the hash. If you repeatedly use the same x, in other words if you are doing many lookups into the same table, the hash of x is recomputed at each invocation of i. . You can have the hash computed once by defining a search verb for the table with
search =: x&i.
The hash is computed when the verb is defined, and subsequent lookup via search y will be faster.
x 128!:3 y computes the CRC of the string y . x is the CRC polynomial, a Boolean list. Normally the initial CRC is _1 but you can specify a different initial value by making x a 2-element list of boxes of polynomial;initial_value .
If you define a CRC verb as
crc =: x&(128!:3)
then the interpreter will precompile the CRC polynomial for x, making subsequent CRC calculations faster.
2-byte unicode characters can be represented by variables that have the unicode atomic data type. Such variables are created by the verb u: . Its use is described in the Dictionary.
Designing user interfaces is quick and painless with J's Form Editor. The Lab named Form Editor will show you how.


Disgust
Scared
Surprise
Anger
Sad
Happy
Neutral
All
Select at least one data file below:
'; } ?>
P01_Emotion.csv
Line
Radar
Ribbon
Generate


We are now monitoring your URL and will notify you via an ugly email from<EMAIL_ADDRESS>if things go wrong. Have fun :P
<EMAIL_ADDRESS>Open Source Project Created With <3 By Anthony Kung


I am a yellow douche. I like the pee because I am yellow. My birth happened in America. At least for all I know it did. Playing, eating, and flying is great when I am sleeping. Rollercoasters are fun. Really fun. The log ride at Disney Land is my favorite ride there. When I go there for graduation, I will ride it all night long. While rides are fun, I do get hungry riding them, so I enjoy visiting the Black Bear Diner for breakfast, lunch, and dinner. Pizza, burgers, pancakes, and very large breakfasts are available everyday.


Introduction.
This HowTo describes the way of installing wifiBSD which supports the latest Atheros chips.
At the point of writing this HowTo support for atheros cards is avaliable in FreeBSD 5.1-CURRENT > only.
Firstly we need to cvsup to get the latest sources and drivers of FreeBSD.
We will need to create a virtual environment - jail.
The purpose of it is we can have one main FreeBSD system running -RELEASE or STABLE version and one jailed/virtual
version of Freebsd inside our actual system with the newest sources.
We'll also be overwriting some binaries of the base system with our custom, tuned binaries and it's much saver to do that in a "sandbox".
Preparing your soekris board.
Firstly we need to set up the soekris board.
Install minicom , start it up and press CTRL A and then O (still keeping the CTRL button pressed).
Scroll down to Serial port setup and then set the Bps/Par/Bits to 19200 8N1 (Press E) and set Hardware Flow Control to No (Press F).
Soekris boards use 19200 Bits as default.
Now we need to change that value to 9600.
When your 45xx starts to boot, press Ctl-P to stop the boot process and get to the BIOS command prompt.
Now type set ConSpeed=9600.
Set up the rest accoridingly:
Recommended BIOS settings for the net45xx
ConSpeed = 9600
ConLock = Enabled
BIOSentry = Disabled
PCIROMS = Disabled
PXEBoot = Disabled
FLASH = Primary
BootDelay = 2
BootPartition = Disabled
ShowPCI = Enabled
You may also set correct date, i.e date 2003/08/14
Installing jailed environment.
Firstly we need to build a new jail for our wifiBSD.
Get down fresh FreeBSD sources with cvsup and run this script.
Adjust it if needed:
#!/bin/sh
# jailsetup.sh version 0.1
# Jail setup script for wifiBSD based on FreeBSD 5.1 > by<EMAIL_ADDRESS><EMAIL_ADDRESS># Whom to notice.
wifibsd="$D/usr/wifibsd" # Installation dir of wifiBSD
if [ x"$1" = x ]
then
echo Usage: jailsetup.sh [dir]
echo example: jailsetup.sh /usr/jail
exit
fi
echo
echo It is your last chance to abort the process.
echo Press Enter to proceed or CTRL + C to abort
read ANYKEY
D=$1
if [ -f $D ]
then
echo Error. A file has the same name as the destination directory.
echo Please remove $D first.
exit
fi
if [ ! -d $D ]; then
echo The directory $D did not exist. We will create it now.
/bin/mkdir -p $D
sleep 3
echo $D Created. Proceeding...
else
echo Checking if the $D directory exists. It will be created if not.
echo Looks ok. Proceeding...
fi
# Do the code crunching
cd /usr/src
make world DESTDIR=$D
cd etc
make distribution DESTDIR=$D
mount_devfs devfs $D/dev
cd $D
ln -sf dev/null kernel
#Create some system files
touch $D/etc/fstab
cp /etc/resolv.conf $D/etc/resolv.conf
cp /etc/localtime $D/etc/localtime
# Let us create directory tree for the whole wifiBSD
if [ ! -d ${wifibsd} ]; then mkdir -p ${wifibsd} ;
mkdir $wifibsd/bin $wifibsd/dev $wifibsd/mnt $wifibsd/modules $wifibsd/proc $wifibsd/root $wifibsd/sbin $wifibsd/var
mkdir -p $wifibsd/boot/defaults
mkdir -p $wifibsd/etc/defaults $wifibsd/etc/mtree $wifibsd/etc/namedb $wifibsd/etc/ppp $wifibsd/etc/ssh $wifibsd/etc/ssl
mkdir -p $wifibsd/usr/bin $wifibsd/usr/lib/aout $wifibsd/usr/libexec $wifibsd/usr/local $wifibsd/usr/share/misc
ln -s /var/tmp/ $wifibsd/tmp
fi
echo
echo "Build of wifiBSD finished at `date +%d%m%Y` !" | mail -s "jail build of wifiBSD complete: `date +%d%m%Y`" $email
When you're done, run:
# chroot /usr/jail
Modify the "set prompt" line in /usr/jail/root/.cshrc if you want to be reminded of the fact that you're inside the jail
by the shell prompt:
# set prompt = "wifiBSD %~ %# "
Still in chrooted env, edit your /etc/rc.conf
network_interfaces=""
sendmail_enable="NONE"
inetd_enable="YES"
inetd_flags="-wW -a <IP_ADDRESS>"
rpcbind_enable="NO"
hostname="jail.wifiBSD.org"
cron_enable="NO"
syslogd_enable="NO"
portmap_enable="NO"
sshd_enable="YES"
Note: The IP which inetd will bind to is the same IP which is/will be used by your jail setup.
Now edit your /etc/ssh/sshd_config and change #ListenAddress <IP_ADDRESS> to ListenAddress <IP_ADDRESS>
Change also #PermitRootLogin no to PermitRootLogin yes. This is for us to be able to login to our jail enviroment from our host.
Now you can logout from your jail system and create an IP alias for your nic:
# ifconfig fxp0 inet <IP_ADDRESS> netmask <IP_ADDRESS>
Change your /etc/rc.conf to make the IP alias permanent by adding following line:
ifconfig_fxp0_alias0="inet <IP_ADDRESS> netmask <IP_ADDRESS>"
Edit the /etc/ssh/sshd_config file being still outside of the jail and bind ssh to your actual IP, the same way as above.
Run killall -HUP sshd.
Create a startup file for our jail in /usr/local/etc/rc.d/ and call it i.e jail.sh
#! /bin/sh
/sbin/mount_devfs devfs /usr/jail/dev/
/usr/sbin/jail /usr/jail jail <IP_ADDRESS> /bin/sh /etc/rc
Now run chroot /usr/jail again.
Run sh /etc/rc to start and check things. You will also see public/private being generated.
Set root's pass running passwd root.
Log out and run /usr/local/etc/rc.d/jail.sh
Now you should be able to ssh in to your jail as root. The point in doing this is you cannot su - in jail enviroment.
One could of course run sudo.
Login to your jail and run cvsup command to get down the source tree of FreeBSD.
Making the directory tree.
We'll put together our whole wifiBSD installation in one directory,
so in the end we could theoretically just copy everything from that directory over to the flash card.
I'll leave it up to you where you're going to create this directory;
mine is /usr/local/wifibsd and the rest of the guide assumes that yours is, too (just make sure you got about 100 MB of space left on the partition where you
create it).
That done, we need to populate this directory with some standard subdirectories (bin, dev, etc, usr, and so on).
You could use mtree to populate it with empty directories, but I prefer to do it manually.
Here is the tree of directories you have to mkdir:
.
|-- bin
|-- boot
| `-- defaults
|-- dev
|-- etc
| |-- defaults
| |-- mtree
| |-- namedb
| |-- ppp
| |-- ssh
| `-- ssl
|-- mnt
|-- modules
|-- proc
|-- root
|-- sbin
|-- tmp -> /var/tmp
|-- usr
| |-- bin
| |-- lib
| `-- aout
| |-- libexec
| |-- local
| |-- sbin
| `-- share
| `-- misc
`-- var
Permissions are 0755 (root.wheel) for all directories except /proc (0555). You may also want to chmod 0700 /root, but that is a matter of personal
taste. :)
Don't forget the link from /tmp to /var/tmp - it's important as the root file system will later be mounted read-only (we'll provide a memory file
system for /var).
Rebuilding the boot loader.
The net4501 BIOS seems to have a little bug in its serial console emulation - if you boot a standard FreeBSD bootloader on it, it will spread the
characters (e.g. the "swoosh" (- \ | / - ...) all over your terminal. When the kernel boots, things are normal again, but it may be important to see
the error messages in case the bootloader cannot boot the kernel. To fix this, we have to recompile the boot loader (don't worry, it's easy and quick).
Note: you'll need to have the developer distribution installed on your base system to recompile the boot loader - just the kernel sources is not
sufficient. You can install the developer distribution with /stand/sysinstall. If you can't/don't want to recompile the boot loader, you can download a
precompiled boot loader (for 5.1-CURRENT) here. gunzip it and throw it in /boot/loader. Don't forget to chmod 555 it.
Edit /sys/boot/i386/libi386/Makefile and comment out the line that reads:
CFLAGS+= -DTERM_EMU
Leave the editor, and run:
# cd /sys/boot
# make clean && make && make install
Of course this will also change the boot loader of your base FreeBSD system to not use terminal emulation, but that doesn't hurt much.
Importand! Set CPUTYPE=i486 in your /etc/make.conf for soekris boards! Otherwise your loader will compile for pentium architecture and soekris will never boot.
Dynamic vs. static executables
In a normal FreeBSD installation, the binaries in /bin and /sbin are linked statically, which means they do not depend on any libraries in order to work.
This makes them much bigger, though, and you can save several MBs (about 6.7 MB with my binary set) by linking them dynamically, too.
Since we keep everything on one partition, they would still be usable in single-user mode because the libraries are available.
The only disadvantage is that if your libraries get
corrupted, you won't be able to do much on the system to fix it.
Decide for yourself whether you want them to be dynamically linked. If you do, edit /etc/make.conf and add the line
NOSHARED=no
to it. Then cd to /usr/src/bin and type make clean && make && make install. Do the same for /usr/src/sbin. Voila`.
NOTE: if you actually run "make install" with NOSHARED=no set on a real FreeBSD system (not in a jail as explained in chapter 1.1), you should really make
sure that your /usr directory is in your root partition (not in a separate partition). Otherwise your next reboot will fail horribly because /sbin/init is
linked dynamically but the required libraries can't be found (since the other partitions are not mounted at that time, yet).
If you feel like saving another 400 KB (with my binary set), you can do the same for /usr/src/usr.bin, because a few binaries in there (bzip2, gzip and tar
among others) are also linked statically by default.
Copying the binaries over.
I made a little shell script that reads a
file which lists all the necessary binaries and copies them over, recreating the proper hard links in the process (for example, /bin/ln and /bin/link are the
same file, but if you copy them over with cp, you end up with two copies of ln/link on your wifiBSD file system, thus wasting a lot of space).
Get wifibsd.sh, wifibsd.subr and my list of binaries, wifibsd.files.
Now edit the variables if needed and execute wifibsd.sh
# ./wifibsd.sh
wifibsd.sh will read the list of files in wifibsd.files and copy them from your system in / into your wifiBSD root file system in /usr/wifibsd. My file list
contains a reasonable amount of binaries tuned to sacrifice the least amount of functionality for my purpose, but still fit well on a CF card. Things like
perl and sendmail are missing, however, because I don't really need them. If you do, change wifibsd.files to reflect your requirements.
If you feel like saving almost 200 KB, you can copy the stripped-down termcap file from PicoBSD over the standard /usr/wifibsd/usr/share/misc/termcap file.
You'll find the replacement file in /usr/src/release/picobsd/mfs_tree/etc/termcap. The standard termcap file contains many terminal types that you probably
won't use anyway. There's also a stripped services file in /usr/src/release/picobsd/mfs_tree/etc/services. (suggested by Stuart Henderson)
Making the kernel.
# cd /sys/i386/conf
# config WIFIBSD
# cd /sys/i386/compile/WIFIBSD
# make depend && make
When it's done, you should have your kernel. We will now install it gzipped to save even more space:
# gzip -9 kernel
# mkdir -p /usr/wifibsd/boot/kernel
# cp kernel.gz /usr/wifibsd/boot/kernel
Copying the libraries
We did not copy all the essential libraries in /usr/lib yet. These are not listed in wifibsd.files because the list of required libraries depends on which
binaries you have installed. In an earlier version of this guide, we would just copy all libraries in /usr/lib and then remove those that we were sure would
not be required (e.g. *.a). That still left a lot of unnecessary libraries (about 5.9 MB with FreeBSD 4.6) lying around. If you use my file list
(wifibsd.files), the libraries that are absolutely necessary weigh in at 3.2 MB - so that means another 2.7 MB saved.
I wrote a script, wifibsd.sh (the same one as above), which walks through your wifiBSD tree and uses ldd on all binaries to extract a list of only those
libraries that are required for at least one binary in your wifiBSD system. Every requiered library was copied over then we run it the first time.
The only libraries that are still missing now are the PAM modules. Doing a
cp -p /usr/lib/pam* /usr/wifibsd/usr/lib
should fix that. If you don't want all PAM modules (you probably won't need Kerberos modules, for example), you should copy at least pam_deny, pam_permit,
pam_unix, pam_login_access and pam_nologin.
Finally, if you mkdir /usr/wifibsd/usr/lib/aout, you will avoid the warning message that appears otherwise.
That's it. Our libraries directory has been populated.
Populating /etc
Edit your /etc/rc.conf
hostname="wifibsd.wrs.no"
ifconfig_sis0="<IP_ADDRESS> netmask <IP_ADDRESS>"
kern_securelevel_enable="NO"
nfs_reserved_port_only="YES"
sendmail_enable="NONE"
sshd_enable="YES"
usbd_enable="NO"
inetd_enable="NO"
portmap_enable="NO"
diskless_mount="/etc/rc.d/diskless"
update_motd="NO"
varsize=8192
For FreeBSD 5.1 you have to edit /etc/rc.d/diskless to remove the check for an NFS mount.
Comment out following lines:
#dlv=`/sbin/sysctl -n vfs.nfs.diskless_valid 2> /dev/null`
#[ ${dlv:=0} -eq 0 ] && exit 0
Don't forget to edit /etc/newsyslog.conf to rotate log files more often and don't archive them. You probably won't want much logging anyway, since all your
log files will be lost when you reboot your machine.
.
.
.
Tar'ing everything up.
Because of the aforementioned inability of cp to reproduce hard links, we'll build a tar archive of our whole wifiBSD installation. Do the following:
# cd /usr/wifibsd
# tar cfvz /usr/wifibsd-0.1.tgz *
Of course, the name of the .tgz file is a matter of personal taste.
When it's done, you'll be left with a .tgz file that contains everything (well, almost) for your wifiBSD.
Generating the flash image.
Although we could use the CF card like a hard disk, disklabel and newfs it and explode our tar archive directly on it, I feel it's easier and faster to do
that task in a disk image and dd that directly onto the flash card - besides, it prolongs the life of the CF card by writing every sector only once.
We'll use vnconfig to get a virtual disk that we can disklabel. You will have to know the size of your flash card in sectors (512 byte units), but you cannot
figure this out without actually connecting the card to your machine (see the beginning of the next section for information on how to do this). Once you got
it connected, use the following command to find out the number of sectors:
# bsdlabel -rwn ad[n] auto | grep sectors/unit
...of course substituting the proper device number of your flash card for [n].
Hint: if disklabel reports errors like "No space left on device", try the following command first:
# dd if=/dev/zero of=/dev/ad[n] bs=1k count=20
This will erase any partition information that may already be present on the CF card.
Now we'll create a disk image of the same size, initially filled with zeroes:
# dd if=/dev/zero of=/usr/wifibsd-disk.bin bs=512 count=[number of sectors on your flash card]
# dd if=/dev/zero of=/usr/wifibsd-disk.bin bs=512 count=35000
Let's use this disk image file as a vn device so we can disklabel it:
# mdconfig -a -t vnode -u 0 -f /usr/wifibsd-disk.bin
Our new virtual disk has to be partitioned and the file system created. Use:
# bsdlabel -Brw md0 auto
# bsdlabel -e md0
You'll be dropped into your editor. Find the line that starts with c: and duplicate it, changing the c: to a: and the fstype to 4.2BSD. This is our root
partition, which will span over the whole slice. If you want a second partition (e.g. for configuration information), reduce the size of the a: slice by the
amount of space you want for your second partition, then make another line starting with e:, an offset equal to the size of a:, and a size equal to what you
subtracted from a:. Save.
Example of how my partitions look like:
# /dev/md0:
8 partitions:
# size offset fstype [fsize bsize bps/cpg]
a: 64256 0 4.2BSD 0 0
c: 64256 0 unused 0 0 # "raw" part, don't edit
Note that we don't have a swap partition - there's nowhere to put it. You can't put swap partitions on your flash card - it's way too slow and would soon ruin
your card. So you better make sure that you've got enough memory for your applications...
Now let's newfs and mount our partition:
# newfs -b 8192 -f 1024 -U /dev/md0a
# mount /dev/md0a /mnt
(if you made a second partition earlier on, don't forget to newfs that one, too). So we got our virtual disk mounted on /mnt, and we're now ready to explode
our .tgz onto it:
cd /mnt
tar xfvzP /usr/wifibsd.tgz
That's it. Let's clean up:
# cd /
# umount /mnt
# mdconfig -d -u 0
And the following config file:
/etc/defaults/pccard.conf
And add the following lines to it:
# Atheros reference design a/b/g card
card "Atheros Communications, Inc." "AR5001-0000-0000"
config auto "ath" ?
insert /etc/pccard_ether $device start
remove /etc/pccard_ether $device stop
Thanks to Rudi van Drunen for that info.
Copying everything to the flash card.
This is a bit tricky. You could netboot (with PXE) your net4501 with the CF card installed and copy everything over the network, but preparing a bootable FreeBSD
for this purpose isn't quite simple, either.
You'll need some kind of adapter in order to connect your CF card to your base system.
If your base system is a notebook, you can use a CF -> PCMCIA adapter (enable pccardd and you'll see the card as an ATAPI device, like for example ad8) or a
CF -> IDE adapter if it's a desktop machine.
Either way, you'll end up with an ad[n] device that represents the CF card (it behaves like an IDE hard disk).
We can now simply transfer the disk image we created in the previous step block-by-block onto our flash card:
# dd if=wifibsd-0.1.bin of=/dev/ad[n] bs=8k
(make sure you get the value for [n] right in this command or you might erase your hard disk!!!)
If you want to see the progress, type Ctrl-T.


Actual source code: ex31.c
petsc-3.8.0 2017-09-26
2: static char help[] = "Tests PetscGetFullPath().\n\n";
5: #include <petscsys.h>
7: /* for windows - fix up path - so that we can do diff test */
8: PetscErrorCode path_to_unix(char filein[])
9: {
11: size_t i,n;
14: PetscStrlen(filein,&n);
15: for (i=0; i<n; i++) {
16: if (filein[i] == '\\') filein[i] = '/';
17: }
18: return(0);
19: }
21: int main(int argc,char **argv)
22: {
23: char fpath[PETSC_MAX_PATH_LEN];
26: PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;
27: PetscGetFullPath("~/somefile",fpath,sizeof(fpath));
28: path_to_unix(fpath);
29: PetscPrintf(PETSC_COMM_WORLD,"%s\n",fpath);
30: PetscGetFullPath("someotherfile",fpath,sizeof(fpath));
31: path_to_unix(fpath);
32: PetscPrintf(PETSC_COMM_WORLD,"%s\n",fpath);
33: PetscFinalize();
34: return ierr;
35: }
39: /*TEST
41: test:
42: requires: !windows_compilers
43: filter: sed "s?$(pwd -P)??g" | sed "s?${HOME}??g"
45: test:
46: suffix: 2
47: requires: windows_compilers
48: output_file: output/ex31_1.out
49: filter: sed "s?`cygpath -m ${PWD}`??g" | sed "s?`cygpath -m ${HOME}`??g"
51: TEST*/


{% extends "csc_new/base.html" %} {% load static %} {% load email_obfuscator %} {% block head %}
The purpose of the CSC is to foster a community for RIT’s computing students and provide them with the resources and skills necessary to succeed, both academically and professionally.
For more details, please see our constitution.
Below, you can find the name, bio, and contact email for each of our current executive board members.
President - {{<EMAIL_ADDRESS>}}
I'm a fifth year computer science major. I like programming, video games, and being lazy.
Vice President - {{<EMAIL_ADDRESS>}}
Public Relations - {{<EMAIL_ADDRESS>}}
I'm a 2nd year Computer Science and Software Engineering double major. I like programming and art. Send me your best memes!
Public Relations - {{<EMAIL_ADDRESS>}}
I’m a 5th year computer science major with a minor in web development. I love to code and work on cool projects, so pitch an idea to me!
Public Relations - {{<EMAIL_ADDRESS>}}
I'm a first year computer science and economics double major. I like sports, video games and programming.
System Administrator - {{<EMAIL_ADDRESS>}}
I’m a fourth-year computer science major with a minor in computing security. I’m interested in math, puzzles, hiking, and cyber security.
Events - {{<EMAIL_ADDRESS>}}
I am a freshman majoring in Computer Science. I am interested in coding, problem solving, reading and playing the piano. My goal is to help the community more active and open to all RIT students who are interested in programming.
Treasurer - {{<EMAIL_ADDRESS>}}
I am a first year Computer Science Major. I enjoy programming, singing, and theater.
Secretary - {{<EMAIL_ADDRESS>}}
I am currently a second-year Computer Science major at RIT. Besides my passion for programming, I love singing and travelling around the world.


# -*- coding: utf-8 -*-
# This file is part of QuTiP: Quantum Toolbox in Python.
#
# Copyright (c) 2014 and later, Alexander J G Pitchford
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the QuTiP: Quantum Toolbox in Python nor the names
# of its contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
 IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
###############################################################################
# @author: Alexander Pitchford
# @email1<EMAIL_ADDRESS># @email2<EMAIL_ADDRESS># @organization: Aberystwyth University
# @supervisor: Daniel Burgarth
"""
Statistics for the optimisation
Note that some of the stats here are redundant copies from the optimiser
used here for calculations
"""
import numpy as np
import datetime
[docs]class Stats(object):
"""
Base class for all optimisation statistics
Used for configurations where all timeslots are updated each iteration
e.g. exact gradients
Note that all times are generated using timeit.default_timer() and are
in seconds
Attributes
----------
dyn_gen_name : string
Text used in some report functions.
Makes sense to set it to 'Hamiltonian' when using unitary dynamics
Default is simply 'dynamics generator'
num_iter : integer
Number of iterations of the optimisation algorithm
wall_time_optim_start : float
Start time for the optimisation
wall_time_optim_end : float
End time for the optimisation
wall_time_optim : float
Time elasped during the optimisation
wall_time_dyn_gen_compute : float
Total wall (elasped) time computing combined dynamics generator
(for example combining drift and control Hamiltonians)
wall_time_prop_compute : float
Total wall (elasped) time computing propagators, that is the
time evolution from one timeslot to the next
Includes calculating the propagator gradient for exact gradients
wall_time_fwd_prop_compute : float
Total wall (elasped) time computing combined forward propagation,
that is the time evolution from the start to a specific timeslot.
Excludes calculating the propagators themselves
wall_time_onwd_prop_compute : float
Total wall (elasped) time computing combined onward propagation,
that is the time evolution from a specific timeslot to the end time.
Excludes calculating the propagators themselves
wall_time_gradient_compute : float
Total wall (elasped) time computing the fidelity error gradient.
Excludes calculating the propagator gradients (in exact gradient
methods)
num_fidelity_func_calls : integer
Number of calls to fidelity function by the optimisation algorithm
num_grad_func_calls : integer
Number of calls to gradient function by the optimisation algorithm
num_tslot_recompute : integer
Number of time the timeslot evolution is recomputed
(It is only computed if any amplitudes changed since the last call)
num_fidelity_computes : integer
Number of time the fidelity is computed
(It is only computed if any amplitudes changed since the last call)
num_grad_computes : integer
Number of time the gradient is computed
(It is only computed if any amplitudes changed since the last call)
num_ctrl_amp_updates : integer
Number of times the control amplitudes are updated
mean_num_ctrl_amp_updates_per_iter : float
Mean number of control amplitude updates per iteration
num_timeslot_changes : integer
Number of times the amplitudes of a any control in a timeslot changes
mean_num_timeslot_changes_per_update : float
Mean average number of timeslot amplitudes that are changed per update
num_ctrl_amp_changes : integer
Number of times individual control amplitudes that are changed
mean_num_ctrl_amp_changes_per_update : float
Mean average number of control amplitudes that are changed per update
"""
def __init__(self):
self.reset()
def reset(self):
self.dyn_gen_name = "dynamics generator"
self.clear()
def clear(self):
self.num_iter = 0
# Duration attributes
self.wall_time_optim_start = 0.0
self.wall_time_optim_end = 0.0
self.wall_time_optim = 0.0
self.wall_time_dyn_gen_compute = 0.0
self.wall_time_prop_compute = 0.0
self.wall_time_fwd_prop_compute = 0.0
self.wall_time_onwd_prop_compute = 0.0
self.wall_time_gradient_compute = 0.0
# Fidelity and gradient function calls and computes
self.num_fidelity_func_calls = 0
self.num_grad_func_calls = 0
self.num_tslot_recompute = 0
self.num_fidelity_computes = 0
self.num_grad_computes = 0
# Control amplitudes
self.num_ctrl_amp_updates = 0
self.mean_num_ctrl_amp_updates_per_iter = 0.0
self.num_timeslot_changes = 0
self.mean_num_timeslot_changes_per_update = 0.0
self.num_ctrl_amp_changes = 0
self.mean_num_ctrl_amp_changes_per_update = 0.0
[docs] def calculate(self):
"""
Perform the calculations (e.g. averages) that are required on the stats
Should be called before calling report
"""
# If the optimation is still running then the optimisation
# time is the time so far
if self.wall_time_optim_end > 0.0:
self.wall_time_optim = \
self.wall_time_optim_end - self.wall_time_optim_start
try:
self.mean_num_ctrl_amp_updates_per_iter = \
self.num_ctrl_amp_updates / float(self.num_iter)
except:
self.mean_num_ctrl_amp_updates_per_iter = np.NaN
try:
self.mean_num_timeslot_changes_per_update = \
self.num_timeslot_changes / float(self.num_ctrl_amp_updates)
except:
self.mean_num_timeslot_changes_per_update = np.NaN
try:
self.mean_num_ctrl_amp_changes_per_update = \
self.num_ctrl_amp_changes / float(self.num_ctrl_amp_updates)
except:
self.mean_num_ctrl_amp_changes_per_update = np.NaN
def _format_datetime(self, t, tot=0.0):
dtStr = str(datetime.timedelta(seconds=t))
if tot > 0:
percent = 100*t/tot
dtStr += " ({:03.2f}%)".format(percent)
return dtStr
[docs] def report(self):
"""
Print a report of the stats to the console
"""
print("\n------------------------------------"
"\n---- Control optimisation stats ----")
self.report_timings()
self.report_func_calls()
self.report_amp_updates()
print("------------------------------------")
def report_timings(self):
print("**** Timings (HH:MM:SS.US) ****")
tot = self.wall_time_optim
print("Total wall time elapsed during optimisation: " +
self._format_datetime(tot))
print("Wall time computing Hamiltonians: " +
self._format_datetime(self.wall_time_dyn_gen_compute, tot))
print("Wall time computing propagators: " +
self._format_datetime(self.wall_time_prop_compute, tot))
print("Wall time computing forward propagation: " +
self._format_datetime(self.wall_time_fwd_prop_compute, tot))
print("Wall time computing onward propagation: " +
self._format_datetime(self.wall_time_onwd_prop_compute, tot))
print("Wall time computing gradient: " +
self._format_datetime(self.wall_time_gradient_compute, tot))
print("")
def report_func_calls(self):
print("**** Iterations and function calls ****")
print("Number of iterations: {}".format(self.num_iter))
print("Number of fidelity function calls: "
"{}".format(self.num_fidelity_func_calls))
print("Number of times fidelity is computed: "
"{}".format(self.num_fidelity_computes))
print("Number of gradient function calls: "
"{}".format(self.num_grad_func_calls))
print("Number of times gradients are computed: "
"{}".format(self.num_grad_computes))
print("Number of times timeslot evolution is recomputed: "
"{}".format(self.num_tslot_recompute))
print("")
def report_amp_updates(self):
print("**** Control amplitudes ****")
print("Number of control amplitude updates: "
"{}".format(self.num_ctrl_amp_updates))
print("Mean number of updates per iteration: "
"{}".format(self.mean_num_ctrl_amp_updates_per_iter))
print("Number of timeslot values changed: "
"{}".format(self.num_timeslot_changes))
print("Mean number of timeslot changes per update: "
"{}".format(self.mean_num_timeslot_changes_per_update))
print("Number of amplitude values changed: "
"{}".format(self.num_ctrl_amp_changes))
print("Mean number of amplitude changes per update: "
"{}".format(self.mean_num_ctrl_amp_changes_per_update))
class StatsDynTsUpdate(Stats):
"""
Optimisation stats class for configurations where all timeslots are not
necessarily updated at each iteration. In this case it may be interesting
to know how many Hamiltions etc are computed each ctrl amplitude update
Attributes
----------
num_dyn_gen_computes : integer
Total number of dynamics generator (Hamiltonian) computations,
that is combining drift and control dynamics to calculate the
combined dynamics generator for the timeslot
mean_num_dyn_gen_computes_per_update : float
# Mean average number of dynamics generator computations per update
mean_wall_time_dyn_gen_compute : float
# Mean average time to compute a timeslot dynamics generator
num_prop_computes : integer
Total number of propagator (and propagator gradient for exact
gradient types) computations
mean_num_prop_computes_per_update : float
Mean average number of propagator computations per update
mean_wall_time_prop_compute : float
Mean average time to compute a propagator (and its gradient)
num_fwd_prop_step_computes : integer
Total number of steps (matrix product) computing forward propagation
mean_num_fwd_prop_step_computes_per_update : float
Mean average number of steps computing forward propagation
mean_wall_time_fwd_prop_compute : float
Mean average time to compute forward propagation
num_onwd_prop_step_computes : integer
Total number of steps (matrix product) computing onward propagation
mean_num_onwd_prop_step_computes_per_update : float
Mean average number of steps computing onward propagation
mean_wall_time_onwd_prop_compute
Mean average time to compute onward propagation
"""
def __init__(self):
self.reset()
def reset(self):
Stats.reset(self)
# Dynamics generators (Hamiltonians)
self.num_dyn_gen_computes = 0
self.mean_num_dyn_gen_computes_per_update = 0.0
self.mean_wall_time_dyn_gen_compute = 0.0
# **** Propagators *****
self.num_prop_computes = 0
self.mean_num_prop_computes_per_update = 0.0
self.mean_wall_time_prop_compute = 0.0
# **** Forward propagation ****
self.num_fwd_prop_step_computes = 0
self.mean_num_fwd_prop_step_computes_per_update = 0.0
self.mean_wall_time_fwd_prop_compute = 0.0
# **** onward propagation ****
self.num_onwd_prop_step_computes = 0
self.mean_num_onwd_prop_step_computes_per_update = 0.0
self.mean_wall_time_onwd_prop_compute = 0.0
def calculate(self):
Stats.calculate(self)
self.mean_num_dyn_gen_computes_per_update = \
self.num_dyn_gen_computes / float(self.num_ctrl_amp_updates)
self.mean_wall_time_dyn_gen_compute = \
(self.wall_time_dyn_gen_compute /
float(self.num_dyn_gen_computes))
self.mean_num_prop_computes_per_update = \
self.num_prop_computes / float(self.num_ctrl_amp_updates)
self.mean_wall_time_prop_compute = \
self.wall_time_prop_compute / float(self.num_prop_computes)
self.mean_num_fwd_prop_step_computes_per_update = \
(self.num_fwd_prop_step_computes /
float(self.num_ctrl_amp_updates))
self.mean_wall_time_fwd_prop_compute = \
(self.wall_time_fwd_prop_compute /
float(self.num_fwd_prop_step_computes))
self.mean_num_onwd_prop_step_computes_per_update = \
(self.num_onwd_prop_step_computes /
float(self.num_ctrl_amp_updates))
self.mean_wall_time_onwd_prop_compute = \
(self.wall_time_onwd_prop_compute /
float(self.num_onwd_prop_step_computes))
def report(self):
"""
Print a report of the stats to the console
"""
print("\n------------------------------------"
"\n---- Control optimisation stats ----")
self.report_timings()
self.report_func_calls()
self.report_amp_updates()
self.report_dyn_gen_comps()
self.report_fwd_prop()
self.report_onwd_prop()
print("------------------------------------")
def report_dyn_gen_comps(self):
print("**** {} Computations ****".format(self.dyn_gen_name))
print("Total number of {} computations: "
"{}".format(self.dyn_gen_name, self.num_dyn_gen_computes))
print("Mean number of {} computations per update: "
"{}".format(self.dyn_gen_name,
self.mean_num_dyn_gen_computes_per_update))
print("Mean wall time to compute {}s: "
"{} s".format(self.dyn_gen_name,
self.mean_wall_time_dyn_gen_compute))
print("**** Propagator Computations ****")
print("Total number of propagator computations: "
"{}".format(self.num_prop_computes))
print("Mean number of propagator computations per update: "
"{}".format(self.mean_num_prop_computes_per_update))
print("Mean wall time to compute propagator "
"{} s".format(self.mean_wall_time_prop_compute))
def report_fwd_prop(self):
print("**** Forward Propagation ****")
print("Total number of forward propagation step computations: "
"{}".format(self.num_fwd_prop_step_computes))
print("Mean number of forward propagation step computations"
" per update: "
"{}".format(self.mean_num_fwd_prop_step_computes_per_update))
print("Mean wall time to compute forward propagation "
"{} s".format(self.mean_wall_time_fwd_prop_compute))
def report_onwd_prop(self):
print("**** Onward Propagation ****")
print("Total number of onward propagation step computations: "
"{}".format(self.num_onwd_prop_step_computes))
print("Mean number of onward propagation step computations"
" per update: "
"{}".format(self.mean_num_onwd_prop_step_computes_per_update))
print("Mean wall time to compute onward propagation "
"{} s".format(self.mean_wall_time_onwd_prop_compute))


Build Realtime Apps now! Jet is a framework for building distributed realtime Apps. It employs fast push technologies and differential updates to keep all clients in sync. It is very easy to use and features powerful query filters, sorting rules and a Web Inspector, called Radar.
Jet has been designed for IoT , Games, Collaborative Apps or anything else where things are in flux and fast communication is required. Its efficient design allows Jet Daemons to run very nicely on systems with rather limited ressources like the RaspberryPi. Jet Peers can even run on Arduino!


--- layout: archive title: Zulip Chat Archive permalink: /stream/113489-new-members/topic/le.20and.20ge.20not.20equivalent.3F.html ---
Code:
lemma test (L : ℝ) (h : L ≥ 0) (h₁ : 0 ≤ L): L < 0 := begin rw le_iff_eq_or_lt at h₁, rw le_iff_eq_or_lt at h, end
Tactic state:
rewrite tactic failed, did not find instance of the pattern in the target expression ?m_3 ≤ ?m_4 state: L : ℝ, h : L ≥ 0, h₁ : 0 = L ∨ 0 < L ⊢ L < 0
why is this happening? In my code where this originally happened I had just proved L ≥ 0 in a have statement, switching it to 0 ≤ L gave no errors as if they were the same.
but the test lemma seems to imply they are different?
rw
requires syntactic equality, whereas have
only requires definitional equality. For rw
to work they have to look the same more or less.
Does simp also require syntactic equality? I switched rw into simp in code above, and it also gives an error.
so I assume yes
It would be easier to help if you could provide a true lemma that you'd like to prove
Anyway, always use le
Yes, rewrites are a great example of where definitional equality isn't good enough. I see this a lot in my code now, I don't know why. I have to use show
to change my goal to something definitionally equal and then the rw
works
Last updated: Apr 24 2020 at 19:02 UTC


THE WINGS OF THE DOVE (Miramax) Starring: Helena Bonham Carter, Linus Roache, Alison Elliott, Alex Jennings, Elizabeth McGovern, Charlotte Rampling. Screenplay: Hossein Amini, based on the novel by Henry James. Producers: Stephen Evans and David Parfitt. Director: Iain Softley. MPAA Rating: R (sexual situations, nudity) Running Time: 101 minutes. Reviewed by Scott Renshaw.
From beneath broad-brimmed hats, the dark eyes of Helena Bonham Carter burn with primal ferocity in THE WINGS OF THE DOVE; behind veils of lace, her mind ponders decidedly un-ladylike thoughts. Carter's body of film work, including noteworthy roles in A ROOM WITH A VIEW, HOWARDS END, WHERE ANGELS FEAR TO TREAD and TWELFTH NIGHT, might lead you to suspect she was born wearing a corset. It also makes WINGS a particularly intriguing addition to her resume. Like most of her previous films, this one is a costume drama based on a classic novel (by Henry James). This time, however, Carter creates a character who prowls through every scene as though she may tear off that corset at any moment with a howl of rage against the social order.
Eventually she does remove the offending garment (more on which momentarily), but the preceding moments build with a powerful sense of anticipation. Carter plays Kate Croy, a young turn-of-the-century Englishwoman of minimal means taken in by her wealthy Aunt Maude (Charlotte Rampling). Maude has plans for her neice's future, plans which do not include a poor husband like Kate's beloved, journalist Merton Densher (Linus Roache). Faced with choosing between her patron and her heart, Kate discovers another alternative when she befriends American heiress Millie Theale (Alison Elliott). The terminally ill Millie has eyes for Merton, which Kate sees as a perfect opportunity: if Merton can woo his way into Millie's will, Kate and Merton could eventually marry after all.
At the heart of this convoluted romantic triangle is author Henry James' fascination with the differences between English and American society. For Kate, wealth means obligatory membership in a stratified social system which has become a farce by 1910, with landed gentlemen like Lord Mark (Alex Jennings) reduced to fortune-hunting to stave off insolvency; for activist writer Merton, wealth is an arbitrary dividing line separating him from his object of desire. When Millie enters their lives, both are confronted with challenges to their assumptions. Though wealthy, Millie is kind and never condescending, nor is she restricted by social mandates. While Kate envies Millie's freedom, Merton begins to realize that Kate's actions are the result of her choices, not an inevitable by-product of money.
Those tense interpersonal dynamics are rendered with impressive economy in Hossein Amini's screenplay. THE WINGS OF THE DOVE comes in at under an hour and 45 minutes, a remarkable achievement for a literary adaptation made even more remarkable by the richness of the characterizations. The requisite sumptuous production values are all in place (notably John Beard's spectacular production design), yet THE WINGS OF THE DOVE never once sacrifices focus on the characters for fetishistic period detail. Merton's background is less focused than the rest, but Linus Roache creates a convincing portrait of torn loyalties; as Millie, Alison Elliott plays the doomed Millie with a tenderness of spirit which never lapses into cinematic sainthood.
Both Roache and Elliott are strong, but Helena Bonham Carter is a powerhouse. Her performance pulses with resentment and rationalized deviousness, captured by Iain Softley in direction which holds on her face whenever possible. The potentially unsympathetic character of Kate becomes a tragic figure who feels forced into plotting for her most basic happiness.  Carter shows plenty of nerve (and plenty of skin) in that scene, but she also shows a range few of her previous characters have required. Freeing herself from the broad-brimmed hats, veils of lace and, yes, even her corset, Helena Bonham Carter exposes a tortured soul struggling to break free of roles dictated by costume. How very fitting.
On the Renshaw scale of 0 to 10 soaring doves: 9.
Visit Scott Renshaw's MoviePage http://www.inconnect.com/~renshaw/ *** Subscribe to receive new reviews directly by email! See the MoviePage for details, or reply to this message with subject line "Subscribe".
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Please keep in mind that shorteners are the easiest and cheapest Method of supporting me.  So take yourself a few seconds and enjoy your download afterwards.
Download now


Part 10 - Other Plugin support
Economy / Vault
Parkour supports the ability to use Economy through the Vault plugin, created by Sleaker.
The configuration option in the config.yml is "Other.Economy.Enabled" and must be set to true. When Parkour starts up, it will print a message whether it connected to the Vault plugin successfully.
Once successfully linked, you are able to reward players with an amount of currency, as well as charge them for joining a course.
If there are courses that exist before the plugin was linked with Vault, these need adding to the economy.yml, which is made easy by entering /pa econ recreate.
Once the process is complete it will notify you how many courses were updated. At this stage the economy.yml file should contain all the courses on your server, and a prize and fee set to 0.
The joining fee and reward amount can be set in game, using /pa econ setprize (course) (amount) and /pa econ setfee (course) (amount). Amount being the amount of currency to add / retract.
BountifulAPI
BountifulAPI adds the ability to display titles and various other notifications, rather than printing the messages into the chat.
Created by connorlinfoot, available here: https://www.spigotmc.org/resources/bountifulapi-1-8-1-13.1394/
Parkour Expansion
Allows for PlaceholderAPI to be used with the Parkour plugin, provides a large amount of available placeholder values. Can be used to extend to other plugins to allow for powerful compatibility.
Plugin and image created by steve4744, available here: https://www.spigotmc.org/resources/parkour-expansion.41874/
Parkour Top Ten
Allows for the player's Head to be proudly displayed next to their best times, great for a competitive Parkour server.
Plugin and image created by steve4744, available here: https://www.spigotmc.org/resources/parkour-top-ten.46268/


lgr is a logging package for R built on the back of R6 classes. It is designed to be flexible, performant and extensible. The package vignette contains a comprehensive description of the features of lgr (some of them unique among R logging packages) along with many code examples.
Users that have not worked with R6 classes before, will find configuring Loggers a bit strange and verbose, but care was taken to keep the syntax for common logging tasks and interactive usage simple and concise. User that have experience with shiny, plumber, python logging or Apache Log4j will feel at home. User that are proficient with R6 classes will also find it easy to extend and customise lgr, for example with their own appenders Loggers or Appenders.
lgr$fatal(capture.output(iris))
works)data.table
included for interactive use.sprintf()
for composing log messages.To log an event with with lgr we call lgr$<logging function>()
. Unnamed arguments to the logging function are interpreted by sprintf()
. For a way to create loggers that glue instead please refer to the vignette.
lgr$fatal("A critical error")
#> FATAL [12:42:55.706] A critical error
lgr$error("A less severe error")
#> ERROR [12:42:55.763] A less severe error
lgr$warn("A potentially bad situation")
#> WARN [12:42:55.802] A potentially bad situation
lgr$info("iris has %s rows", nrow(iris))
#> INFO [12:42:55.804] iris has 150 rows
# the following log levels are hidden by default
lgr$debug("A debug message")
lgr$trace("A finer grained debug message")
A Logger can have several Appenders. For example, we can add a JSON appender to log to a file with little effort.
tf <- tempfile()
lgr$add_appender(AppenderJson$new(tf))
lgr$info("cars has %s rows", nrow(cars))
#> INFO [12:42:55.956] cars has 50 rows
cat(readLines(tf))
#> {"level":400,"timestamp":"2019-03-25 12:42:55","logger":"root","caller":"eval","msg":"cars has 50 rows"}
JSON naturally supports custom fields. Named arguments passed to info()
, warn()
, etc… are interpreted as custom fields.
lgr$info("loading cars", "cars", rows = nrow(cars), cols = ncol(cars))
#> INFO [12:42:55.980] loading cars {rows: 50, cols: 2}
cat(readLines(tf), sep = "\n")
#> {"level":400,"timestamp":"2019-03-25 12:42:55","logger":"root","caller":"eval","msg":"cars has 50 rows"}
#> {"level":400,"timestamp":"2019-03-25 12:42:55","logger":"root","caller":"eval","msg":"loading cars","rows":50,"cols":2}
For more examples please see the package vignette and documentation
lgr is used to govern console output in my shiny based csv editor shed
# install.packages("remotes")
remotes::install_github("s-fleck/shed")
library(shed)
library(lgr)
# the root loggers threshold is NA (= log everything), but the console appender
# only displays `info` level messages by default. Let's set it to NA/"all" so
# that we get more exciting output when running shed
console_threshold(NA)
# you also have to set the threshold of the logger of shed which is "info" by
# default
shed:::lg$set_threshold(NA)
# edit away and watch the rstudio console!
shed(iris)
The api of lgr is stable and safe for use. The internal implementation of the database logging features still needs some refinement, and if you are using lgr with a database, I would be grateful for any kind of feedback.1
lgr is currently very actively developed, and feature requests are encouraged.
R6: The R6 class system prevents the framework on which lgr is built and the only Package lgr will ever depend on.
lgr comes with a long list of optional dependencies. These are not necessary to use lgr, but that are required for some extra functions. Most of these dependencies are tied to specific Appenders, though crayon and data.table are also relevant to interactive use of lgr.
Care was taken to choose packages that are slim, stable, have minimal dependencies, and are well maintained :
AppenderDt
, and also by all database / DBI Appenders.LayoutJson
. JSON is a popular plaintext based file format that is easy to read for humans and machines alike.use_logger()
Other optional dependencies (future, future.apply) do not provide any extra functionality but had to be included for some of the automated unit tests run by lgr.
You can install lgr from CRAN
install.packages("lgr")
Or you can install the current development version directly from github
#install.packages("remotes")
remotes::install_github("s-fleck/lgr")
The only database logging I can currently test extensively is DB2 via RJDBC. I do not recommend this setup if you have other options.↩


Here you can edit many of the settings used in basic rooms. Some controls provide drop down menus that are filled out automagically when objects are imported into the project (such as items and doors).
Most controls correspond directly with a function call built into the 'room.c' object. For more details please see the builders guide to rooms that is provided with Dead Souls. You can view it here http://dead-souls.net/docs/build/.


OER sind mehr als digitale Arbeitsblätter
February 5, 2017
To make your first blog post, just create a new markdown file in the _posts
directory with the title format YYYY-MM-DD-title.md
. Posts follow the simple markdown syntax and can include a wide array of multimedia formats.
This is a header
And this is a simple paragraph.
Smaller header
This is how you bold & italicize text.
Here is some inline code
.
blockCode() {
return true;
}
Another header
And here’s a list:
- Item 1
- Item 2
- Item 3


I am currently a Ph.D student in the cognitive robotics group in Tampere University of Technology. I am working on a framework that would endow robots with reasoning and interaction skills allowing for instance the generalization of collaborative tasks in industry and thus modify the way we are currently forced to use robots.
First as an intern and then as a research assistant I spent 8 months working in the intelligent robotics group in Aalto University. The project focused on human-robot interaction and how to resolve uncertainties in communication. It led to the following publication :
A. Angleraud, Q. Houbre, V. Kyrki, R.S. Pieters. Human-Robot Interactive Learning Architecture using Ontologies and Symbol Manipulation, in 27th IEEE International Symposium on Robot and Human Interactive Communication (RO-MAN), 2018.
In my 4th years of engineering studies I had the chance to spend a semester in the Seoul National University where I got introduced to AI, computer vision, and started learning python and C++.
Originated from Paris I moved to the south of France in Toulouse in 2012 where I studied maths, electronics and computer engineering for 5 years. My projects include object programming, functional programming and logic programming and range from pure software developments (e.g., ethernet chat app) to more complex systems (e.g., autonomous vehicle project)
If you have an idea for a potential collaboration, a question, or just want to say hi, drop me a line.


Speed Reader
--
Go
Words per minute
This is a lot of text that will be easier to read with a speed reader. You do not have to move your eyes, you just have to read the word. The default is 400 words per minute. It can be adjusted below. To use this, just copy and paste the text you want to read into the text field, and hit go.


| Exported Interfaces - Details |
XLayoutManager
- Description
- central interface to query for, create, destroy and manipulate user
interface elements which are bound to a frame.
- See also
- ::com::sun::star::frame::XLayoutManager;
|
|
| XFrameActionListener
|
::com::sun::star::ui::XUIConfigurationListener
- Description
- notification interface to receive change messages of user interface
elements which are part of the layout manager.
E.g., you can receive events of insertion/replacing and
removing of settings data of user interface elements.
- See also
- ::com::sun::star::ui::XUIConfiguration
|
|
XMenuBarMergingAcceptor
- Description
- provides functions to merge menus for inplace editing of components
inside OpenOffice.org.
|
|
XLayoutManagerEventBroadcaster
- Usage Restrictions
- optional
- Description
- registers listeners that want to receive layout manager
events.
|
|
XInplaceLayout
- Usage Restrictions
- deprecated
- optional
- Description
- interface to support settings a menu bar for inplace editing of
components inside OpenOffice.org.
|
|
Copyright © 2013, The Apache Software Foundation, Licensed under the Apache License, Version 2.0. Apache, the Apache feather logo, Apache OpenOffice and OpenOffice.org are trademarks of The Apache Software Foundation. Other names may be trademarks of their respective owners.


British Airways, pilots' union agree preliminary pay deal to end dispute
(Reuters) - British Airways and its pilots’ union BALPA have reached a preliminary agreement to end the pay dispute that resulted in the first walkout by pilots in the airline’s history, the union said on Friday.
The agreement came after the two sides held talks under the auspices of the ACAS arbitration service.
BALPA said in a statement: “We can confirm that BALPA, BA and ACAS have put together a new pay and conditions proposal and, subject to final checks, BALPA expects it will shortly be consulting its 4,000 BA members on them.”
A BA spokeswoman said “We welcome this positive step.”
As part of the agreement, BA agreed to insert an inflation protection clause to its previous pay offer of an 11.5% rise over three years, the Financial Times reported.
The airline also offered improvements to working conditions, rostering and flight bonuses, the paper added.
British Airways pilots went on strike for 48 hours in September, grounding 1,700 flights.
BA, part of International Consolidated Airlines Group (ICAG.L), said in September that the strikes had cost it 137 million euros ($151 million).


--- layout: tutorial-extended title: The Weather App --- {% assign tutorial_github_url = "https://github.com/infinispan/infinispan-embedded-tutorial" %} {% assign @tutorial_steps = "The Weather Application, Initializing the CacheManager, Putting stuff in the cache, Making entries expire, Configuring the default cache, Clustering the application, Listen to changes in the cluster, Listen to changes in the cache, Grouping entries together, Temperature averages with streams, Declarative configuration" | split: ", " %} {% assign tutorial_step = 4 %}
In the previous step we used the overloaded put() method to store mortal entries. But since we want all of our entries to expire with the same lifespan, we can configure the cache to have default expiration values. To do this we will customize the org.infinispan.configuration.cache.Configuration. A configuration in Infinispan is mostly immutable, aside from some runtime-tunable parameters, and is constructed by means of a ConfigurationBuilder. Using the above use-case, let's create a cache configuration where we want to set the default expiration of entries to 5 seconds. The following code shows how it's done:
cacheManager = new DefaultCacheManager();
ConfigurationBuilder config = new ConfigurationBuilder();
config.expiration().lifespan(5, TimeUnit.SECONDS);
cacheManager.defineConfiguration("weather", config.build());
The configuration builder uses a fluent pattern, so you can tune more configuration aspects with chained methods. With this in mind let's run our application again:
git checkout -f step-4
mvn clean package exec:exec
will yield the same result as we got in the previous step. We didn't change the behaviour of the application, we just changed the semantics of the cache.


21 Ways to keep up with your Notes
Many of us are in the habit of leaving things for the last moment. Being a student, you must have been a victim in a situation where either you are not able to complete notes or maybe do not have a strategy to study. It is not just about having study material at your table and giving it a read or maybe memorizing it. It is more of a technique that everyone can apply; all it takes is a will to perform. Here are 21 ways to keep up with your notes.
1. Before the Lecture.
You have to make sure that you have printouts of what is being taught in your class. You must
practice all the questions mentioned in your notes. It eases the process of solving problems.
This trick works because our visual and spatial memory is quite strong and it is easier to
recollect things which are familiar to it.
2. During the Lecture.
Organize your notes and clip them together. While you are being taught, stay aware of what your professor emphasizes. Keep a highlighter or a pen with yourself so that you can get important things marked. Also, get your questions answered.
3. After the Lecture.
Always read your notes when you get back home. Prepare summaries and keep them somewhere together and safe. You have got to rewrite your notes by your own hands; you can revise your topics this way.
4. Begin with a Reference
When making notes, always mention the date, page, and name of the chapter you've been making notes from.
5. Slide through your Chapters
Chapters must be sectioned into smaller parts.
7. Concise Sentences
Write shorter sentences, you may even use keywords at times, but don't overuse them, it creates confusion.
8. Highlight what is needed
Not everything needs to be highlighted; you can do this trick for those specific words which can make you remember the whole thing. This is mind-mapping.
9. Use of Symbols
It's simple and really interesting. Making symbols like an exclamation sign can remind you that the topic is really important.
10. Do not Repeat
You don't have to write the same thing twice, make little changes; they can expand your memory.
11. Colour Schemes
If you are using different coloured pens, never use more than three.
12. Mind Mapping
Mind mapping remembers things with the help of either a diagram or a keyword. They are packed with information. All you have to do is remember the little things.
13. Flashcards
Flashcards should only be made as short as possible and especially when you have to conduct a quick revision.
14. Providing Header
Always use a header, not too hard but always attractive enough to keep you indulged.
15. Providing Subheader
It must stand out from the rest of the text, but should not be placed in the centre. Keep it smaller than the header.
16. Respecting Bullets
Bullets are always easier to read and keep your content organized. Only the sentences must be really short.
17. Rough and Quick Diagrams
Make soft diagrams that keep your content clean and you can have a glimpse of them.
18. Practical Tips and Tricks
Create and compare practical applications of what you read, it improves your chances of retaining things.
19. Putting Colons
Important references and short explanations can be put within colons and brackets.
20. Decor with Boxes
The easiest step to contrast important definitions is to make a box or a circle around them. It decorates your notes.
21. Key is the Lifeline
When using abbreviations, always add Key at least explaining all about the abbreviations you've used, this saves your time and makes your study effective. With the help of such well-crafted notes, you will now be able to deal with your burdening studies.
By –
Sameer Hussain
Tags: #corruption, #EvilsOfCorruption, #socialevil, #ECONOMIC EVIL, # POLITICAL EVIL, #notespickup, #notes, #trends
Leave a Suggestion


The result is 4
:
```js run let fruits = [“Apples”, “Pear”, “Orange”];
let shoppingCart = fruits;
shoppingCart.push(“Banana”);
! alert( fruits.length ); // 4 /! ```
That’s because arrays are objects. So both shoppingCart
and fruits
are the references to the same array.


Put Template APIedit
Put Index Template Requestedit
A PutIndexTemplateRequest
specifies the name
of a template and patterns
which controls whether the template should be applied to the new index.
Settingsedit
The settings of the template will be applied to the new index whose name matches the template’s patterns.
Mappingsedit
The mapping of the template will be applied to the new index whose name matches the template’s patterns.
request.mapping( "{\n" + " \"properties\": {\n" + " \"message\": {\n" + " \"type\": \"text\"\n" + " }\n" + " }\n" + "}", XContentType.JSON);
The mapping source can be provided in different ways in addition to the
String
example shown above:
Map<String, Object> jsonMap = new HashMap<>(); { Map<String, Object> properties = new HashMap<>(); { Map<String, Object> message = new HashMap<>(); message.put("type", "text"); properties.put("message", message); } jsonMap.put("properties", properties); } request.mapping(jsonMap);
Aliasesedit
The aliases of the template will define aliasing to the index whose name matches the
template’s patterns. A placeholder {index}
can be used in an alias of a template.
Orderedit
In case multiple templates match an index, the orders of matching templates determine the sequence that settings, mappings, and alias of each matching template is applied. Templates with lower orders are applied first, and higher orders override them.
Versionedit
A template can optionally specify a version number which can be used to simplify template management by external systems.
Providing the whole sourceedit
The whole source including all of its sections (mappings, settings and aliases) can also be provided:
request.source("{\n" + " \"index_patterns\": [\n" + " \"log-*\",\n" + " \"pattern-1\"\n" + " ],\n" + " \"order\": 1,\n" + " \"settings\": {\n" + " \"number_of_shards\": 1\n" + " },\n" + " \"mappings\": {\n" + " \"properties\": {\n" + " \"message\": {\n" + " \"type\": \"text\"\n" + " }\n" + " }\n" + " },\n" + " \"aliases\": {\n" + " \"alias-1\": {},\n" + " \"{index}-alias\": {}\n" + " }\n" + "}", XContentType.JSON);
Optional argumentsedit
The following arguments can optionally be provided:
Synchronous executionedit
When executing a PutIndexTemplateRequest
in the following manner, the client waits
for the PutIndexTemplateResponse
to be returned before continuing with code execution:
AcknowledgedResponse putTemplateResponse = client.indices().putTemplate(request, RequestOptions.DEFAULT);
Synchronous calls may throw an IOException
in case of either failing to
parse the REST response in the high-level REST client, the request times out
or similar cases where there is no response coming back from the server.
In cases where the server returns a 4xx
or 5xx
error code, the high-level
client tries to parse the response body error details instead and then throws
a generic ElasticsearchException
and adds the original ResponseException
as a
suppressed exception to it.
Asynchronous executionedit
Executing a PutIndexTemplateRequest
can also be done in an asynchronous fashion so that
the client can return directly. Users need to specify how the response or
potential failures will be handled by passing the request and a listener to the
asynchronous put-template method:
The asynchronous method does not block and returns immediately. Once it is
completed the ActionListener
is called back using the onResponse
method
if the execution successfully completed or using the onFailure
method if
it failed. Failure scenarios and expected exceptions are the same as in the
synchronous execution case.
A typical listener for put-template
looks like:
Put Index Template Responseedit
The returned PutIndexTemplateResponse
allows to retrieve information about the
executed operation as follows: