--- layout: archive title: Zulip Chat Archive permalink: /stream/113488-general/topic/.24.20in.20let.20in.20tactic.20mode.html ---
definition n : ℕ := begin let d := nat.succ $ nat.zero, -- fails exact d, end
Replacing the $ with brackets (or in this case not even brackets) fixes it. It seems to me that the $ wants to eat the comma and things after it.
Is that expected behaviour?
It's not that $
eats too much input, but that it has a lower precedence than is used to parse the argument to let
. $
has the same precedence as ;
, and let a := b; c
is supposed to be parsed as (let a := b); c
. Perhaps it should have a higher precedence than ;
, but it's never quite clear what would be the best order in all contexts
I.e. let d := (nat.succ $ nat.zero)
should work
See also Use of $ in tactics.
{% endraw %}Last updated: Apr 24 2020 at 19:02 UTC


As Mobile Product Design Director, I led a team to transform our apps from static feed readers into experiences purpose-built for mobile.
When I took on the role in 2011, story selection and layouts were determined by editors on the desktop website, then fed downstream to the mobile apps.
There was little to no variation across elements.  Headlines and images were uniform.
In time, we got better at interpreting those feeds. It seems trivial now, but in 2012 we were able to assemble articles into groupings and vary the weight of headlines according to importance.
We added banner headlines and span photos.
This was before Android released Lollipop, so there was still considerably more control over presentation on iOS.
While we made these incremental improvements, we also launched a mobile subscription model.
The key to its success was a metered approach that acquired paid subscribers while allowing non-subscribers to continue viewing a limited number of articles. It was a huge moment in publishing that was emulated across the industry.
We also began providing native feeds to third party apps like Flipboard, and were able to exert some control over the presentation of our brand in those contexts.
In 2014, I advocated for a major investment to break the downstream dependence from our desktop website.
With this illustration I demonstrated how the investment would open up a new generation of editorial styles.
It all came to fruition in 2015.
We now had a set of apps written, designed, and edited expressly for Android, iOS, and mobile web.
Readers flock to The New York Times for its curated selection of news from editors rather than algorithms. But The Times produces a firehose of great content every day, and only a small portion of it is Top News. How do you surface the remainder?
When we embarked on an iPad app redesign, we transformed another feed reader with few visual templates into a stylized experience that amplified the voice and art direction of every section.
As a product director, I pushed to incorporate full covers from the print magazine for the first time. This required a new feed and additional workflow. A small victory that brought a steady dose of visual intelligence to the top of the app every week.
I also restructured the app so that a broad swathe of content appears on the front page, not just Top News. This had the effect of distributing readership across the app in an unprecedented way. Viewership of the magazine, for instance, increased three-fold.
But we still faced the issue of readers feeling like they missed the best material from across The Times.
So I proposed a sort of Tinder for news that would rely on a strong recommendation engine then under development.
I created this prototype of the interaction in Framer.
When the recommendation engine didn’t perform as expected, I suggested we pivot to a simpler solution. It made use of two basic pieces of information: an aggregate notion of the most popular non-news stories, and which of those stories a user has seen.
The result was In Case You Missed It, an automated list of trending stories appended to every article. It soundly outperformed the previous list of articles in that same position.
In addition to iterating on and maintaining our existing apps, I was also responsible for developing entirely new app concepts.
I helped develop the initial idea behind what later became NYT Now, the lighter-weight subscription news product targeted at millenials.
A central goal of the app was to counteract the often-overwhelming river of mobile news. With a lighter volume and more summaries, it was meant to function as a digest of the news, at a cheaper price.
This initial concept is very close to what we launched the following year.
I was also responsible for the UX surrounding the integration of our apps into Android and iOS. From the app stores to the appearance of our Today widget to notifications, arguably the most important way an app reaches out through the device.
Alerts are a powerful way of instantaneously reaching hundreds of thousands of users. But it's a blunt instrument that should be used sparingly.
By launching four additional sub-channels, we were able to reduce volume in the main channel (with less sports, for example) while allowing users with these additional interests to ask for more.
The eventual plan is for Alerts to become far more granular. One key is to develop compelling editorial hooks pegged to major ongoing stories.
Unlike automated products like Google Alerts, we found that treating these alerts as handwritten elements like any other aspect of our coverage led to higher user satisfaction.
I am also host of the podcast The People.
Thanks for stopping by!
elliottmalkin@gmail.com


--- layout: default texts: compatibility ---
{% include head.html %}Get started with Vita3K and play your favorite PSVita games!
GPU that supports OpenGL 4.4
CPU with the AVX instruction set
Minimum of 4GB RAM
GPU that supports OpenGL 4.4 and above
GPU that supports shader interlock
CPU with the AVX instruction set
8GB of RAM or greater
If you're having trouble running Vita3K and it complains about VCRUNTME140_1.dll was not found
,
download and install the Visual C++ 2015-2022 Redistributable.
You need to be running a 64-bit operating system in order for Vita3K to work.
Some games require the system modules be present for Vita3K to (low level) emulate them. This can be done by installing the PS Vita firmware through Vita3K.
The firmware can be downloaded from the official PlayStation website, there's also an additional firmware package that contains the system fonts that needs to be installed. The font firmware package can be downloaded straight from the PlayStation servers.
Install both firmware packages using the File > Install Firmware
menu option.
System modules can be managed in the Configuration > Settings > Core
tab of the emulator,
we recommend Modules Mode > Automatic
.
And if you have doubts some modules are causing crashes you can try to remove them.
Vita3K does not condone piracy, therefore, you are required to dump your own games. Currently, it is preferred to dump your games on a Vita or Vita TV (PS TV) using HENkaku 3.60 - 3.65.
Currently, Vita3K supports .pkg, NoNpDrm, FAGDec, or manually decrypted games (Vitamin dumps are not supported and Maidump is unstable).
The games should be in a .zip or .vpk format if you want to install them from the emulator, or if you prefer to copy them yourself,
you can drag and drop the game folder in your pref_path/ux0/app
folder (not applicable for NoNpDrm dumps/.pkg files).
pref_path
defaults to:
%Appdata%/Roaming/Vita3K/Vita3K
on windows
~/.local/share/Vita3K/Vita3K
on linux
~/Library/Application Support/Vita3K
on macOS
These are the several ways to dump and get decrypted games in order of their accuracy.
Launch Vitashell and navigate to gro0:app
Launch Vitashell and navigate to ux0:app
(or wherever your games are) and choose a game you want to dump
△
then choose Open decrypted
That's the game files done, now we need to use FAGDec to decrypt the selfs.
✖
button, wait for FAGDec to find all the modules and then select DECRYPT ALL
Start
[START] START DECRYPT(SELF)
ux0:FAGDec/app/'title_id'
Now all you gotta do is take the files that FAGDec outputted and put them in the previously copied folder from VitaShell, if asked to replace some files, confirm the replacement.
It's very important that the folder containing the game files be named as the game's Title ID.
After dumping your game, you can optionally package it into a .vpk file for Vita3K to install. By packaging your dump into a .vpk, you can drag and drop it directly into the Vita3K window to install it.
File
-> Create vpk from maidump folder...
EBOOT.BIN
file inside of your dump folder.The progress of the vpk creation will be shown at the bottom of the VitaOrganizer window. Once it's completed, open Vita3K and drag the vpk onto the Vita3K window.
Download the latest nonpdrm.skprx, copy it to ux0:tai
and modify the ux0:tai/config.txt
file to add the path to the module under *KERNEL
as follows
*KERNEL
ux0:tai/nonpdrm.skprx
ur0:tai/config.txt
instead assuming you do not have a config.txt file inside the ux0:tai/
folder
ux0:nonpdrm/license/app/TITLE_ID/6488b73b912a753a492e2714e9b38bc7.rif
ux0:nonpdrm/license/addcont/TITLE_ID/DLC_FOLDER/6488b73b912a753a492e2714e9b38bc7.rif (for additional content)
gro0:app/TITLE_ID
or ux0:app/TITLE_ID
to your PC and copy the fake license ux0:nonpdrm/license/app/TITLE_ID/6488b73b912a753a492e2714e9b38bc7.rif
file as TITLE_ID/sce_sys/package/work.bin
TITLE_ID
, select all the contents and compress them into a .zip format.TITLE_ID.zip
file and confirm. The game will begin installing (This might take a long time for large games).ux0:addcont/TITLE_ID/DLC_FOLDER
or, on selected card games, from grw0:addcont/TITLE_ID/DLC_FOLDER
(ONE AT A TIME)
ux0:nonpdrm/license/addcont/TITLE_ID/DLC_FOLDER/6488b73b912a753a492e2714e9b38bc7.rif
to DLC_FOLDER/sce_sys/package/work.bin
and transfer it to your pc. DLC_FOLDER
, select all the contents and compress them into a .zip format.DLC_FOLDER.zip
file and confirm. The DLC will begin installing.


Opportunities at Centre for Lifelong Learning and Individualised Cognition (CLIC)
Now Open for Applications
The Centre for Lifelong Learning and Individualised Cognition (CLIC), funded by the National Research Foundation (NRF) in Singapore and coordinated through the Cambridge Centre for Advanced Research and Education in Singapore (CARES), is a collaboration between Nanyang Technological University (NTU) and the University of Cambridge. CLIC is a flagship programme in the Science of Learning to harness advancements in neuroscience to develop cognitive training programmes for the improvement of lifelong flexible learning, focusing initially on adolescents and young adults, but also envisaging work with infants and older adults. This is a strategic global initiative for the Universities of Cambridge and NTU that brings together multidisciplinary expertise from over 30 investigators in the areas of Neuroscience, Psychology, Linguistics and Education across the two universities.
Nanyang Technological University is a research intensive university currently ranked 13th globally and placed 1st amongst the world’s best young universities. The University has Colleges of Engineering, Business, Science, Humanities, Arts, & Social Sciences, and an Interdisciplinary Graduate School. Further, the new Lee Kong Chian School of Medicine benefits from a dual campus located at Novena, in close proximity to the Singapore city centre. The Cognitive Neuroimaging Centre (CoNiC) houses state-of-the-art neuroimaging facilities including a newly installed 3T MRI scanner and MEG, as well as new EEG, NIRS, TMS and tDCS equipment.
The first phase of the CLIC program will initially be housed at Nanyang Technological University, Singapore. As the programme progresses, other sites will be developed to meet the needs of the experimental programme. The new CLIC research centre will provide a vibrant, fast-paced, international and interdisciplinary environment with excellent opportunities for skills development and knowledge exchange between partner Principal Investigator labs in Singapore and Cambridge.
The Principal Investigators involved in the first phase of the research programme include:
From Cambridge: Director Professor Zoe Kourtzi (Psychology), Senior Scientific Advisor Professor Trevor Robbins (Psychology), Deputy Directors Professor Henriette Hendriks (Linguistics), Professor Anna Vignoles (Education), and Imaging Lead - Professor John Suckling (Psychiatry); supported by co-Investigators Prof Barbara Sahakian (Psychiatry) and Dr Michelle Ellefson (Education).
From NTU: Director Professor Annabel Chen (Psychology), Deputy Director Asst Prof Victoria Leong (Psychology), Imaging Lead - Professor Balázs Gulyas (LKCMedicine), and Principal Investigators Professor David Hung (NIE), Asst Prof Bobby Cheon (Psychology) and Assoc Prof Georgios Christopoulos (Nanyang Business School); supported by co-Investigator Dr Teo Chew Lee (NIE).
List of Available Positions
Research Fellow Positions:
- Research Fellow/Research Engineer in Neuroimaging and MRI Pulse Sequence (RF6)
- Research Fellow in Neuroimaging and Cognition (RSB RF3)
- Research Fellow in Neuroimaging and Intervention (RSB RF4)
Research Assistant/Associate Positions:
For more available positions at CLIC, please kindly visit this link: Centre for Lifelong Learning and Individualised Cognition (CLIC)


data class BindingComplete : ConfigInputContext
Wrapper for status, and content for the BindingFragment for displaying connections. |
|
data class ConfigInputComplete : ConfigInputContext
Wrapper for status, DialogJs and ConfigInputs. |
|
sealed class ConfigInputContext
A safe way for wrapping status and other things. |
|
data class ConnectionV : ConfigInputContext
Wrapper for status, and content for the BindingFragment for displaying connections. |
|
class EditComponentViewModel : AndroidViewModel
ViewModel for the EditComponentActivity. |
|
data class InheritanceV
Data for displaying inheritance. |
|
data class InheritanceVWrapper
Wrapper for list of InheritanceV and a configType. |
|
data class OnlyStatus : ConfigInputContext
Wrapper just for status. |


SageResearch
Sage Bionetworks has spent four years developing mobile health study apps and played a role in supporting over 20 projects, using Research Kit as the basis for all of our iPhone development. Based on that experience, we have begun to generate a next-generation framework and are looking for the involvement of the broader Research Kit community to provide input on design goals and approaches, and contribute to development. This framework:
- Keeps what is good and useful about ResearchKit, provides for a smooth transition from it, and allows ResearchKit 1.x components to be used as modules in Research apps;
- Is based on modern technology (Swift 5);
- Allows maximum flexibility in extending the core step/task navigation and results gathering functionality by defining a set of protocols and then providing a set of classes as concrete reference implementations;
- Allows maximum flexibility in UI/UX design, first by separating generic UX logic control from platform-specific UI implementations, and also again by providing protocols and concrete reference implementations of those protocols;
- Reduces app size and dependency on unused parts of the underlying OS (e.g., permissions strings required in Info.plist files) by separating specific active tasks or logical groups of tasks into their own modules, in general (but not necessarily) built on these two frameworks;
- Is designed with parallel development for other (mobile and web) platforms in mind so that the broadest spectrum of study participants can be reached with the minimum coding effort.
Like ResearchKit, this project is independent of any particular back-end service used to collect study data, record consent, or perform other centralized study functions. Sage Bionetworks is also the lead developer of Bridge Server, an open source set of services and SDKs for supporting mHealth research.
This project represents the results to date and the ongoing implementation of those goals.
Documentation
The core step/task navigation and results-gathering framework is currently called Research.
The UI/UX framework is called ResearchUI.
The sensor recorder framework is called ResearchRecorders.
License
Sage Research SDK is available under the BSD license:
Copyright © 2017-2019, Sage Bionetworks All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of Sage Bionetworks nor the names of BridgeSDk’s contributors may be used to endorse or promote products derived from this software without specific prior written permission.


To get a feel for the different ways of interacting with Couch, let’s start with a Hello World. Here’s
the boilerplate to set up a tornado server with two endpoints at /hello
and /hi
:
import tornado application = tornado.web.Application([ (r'/hello/([^/]+)', JumpyHello), (r'/hi/([^/]+)', RelaxedHello), ]).listen(1920) tornado.ioloop.IOLoop.instance().start()
Since both of the request handlers (defined below) will need a reference to the database, set up a global for them to share:
from corduroy import Database, NotFound, relax people_db = Database('people') # i.e., http://<IP_ADDRESS>:5984/people
Our first request handler will parse the url and pull out the last component (which will be treated as a document ID). It will then try to retrieve that doc from the database and print a greeting based on its contents. Here is a handler that uses an explicit callback to make a non-blocking request:
class JumpyHello(tornado.web.RequestHandler): @tornado.web.asynchronous def get(self, user_id): # Request the corresponding user's doc. This will return # immediately and control will leave this method. Later on # the got_user_doc callback will be invoked with the # response and a status object as arguments. people_db.get(user_id, callback=self.got_user_doc) def got_user_doc(self, doc, status): # Generate output based on the db's response if status.ok: self.write('hello %s %s'%(doc['first'],doc['last'])) elif status.error is NotFound: self.write('hello whoever you are') else: raise status.exception self.finish()
Though it’s gratifying to know that your server process isn’t blocking while waiting for Couch to
respond, the resulting code doesn’t feel terribly pythonic. Ideally something as simple as a GET
request should be a one-liner. In addition, the use of callbacks means your code is no longer
in the call stack should an exception occur during the request. As a result, error handling becomes a
C-like process of manual status
inspection in lieu of idiomatic try
/except
blocks.
A particularly nice solution to this problem of twisted async code is provided by the tornado.gen
module. As the
abbreviated name suggests, their approach is to use python generators
to turn request handler methods into coroutines that can be suspended during i/o then restarted when
the response arrives.
Corduroy is happy to work in this style and provides the @relax
decorator to make
the syntax more transparent (or at least more glazed with sugar). When applied to one of your
methods, the decorator allows you to treat the API as if it were blocking and no longer requires
explicit callbacks.
The result of this yield
expression will be the data that would ordinarily be passed to your
callback function but can now be captured through simple assignment. If an error occurrs, the decorator
handles that as well by raising the exception at the point of the yield
in your code:
class RelaxedHello(tornado.web.RequestHandler): @relax def get(self, user_id): try: doc = yield people_db.get(user_id) self.write('hello %s %s'%(doc['first'],doc['last'])) except NotFound: self.write('hello whoever you are') self.finish()
This code looks like ‘normal’ blocking code but will in fact execute asynchronously. At the
point of the yield
statement, the request handler releases control of the event loop while
Corduroy creates a callback behind the scenes. Once this internal callback fires, the request handler’s
method is resumed. The handler can then make other asynchronous requests or just return its output if
there’s nothing more to be done.
Virtually every method in Corduroy accepts an optional keyword argument called callback
.
When this argument is omitted (and the @relax
decorator is not in effect), the call will
use blocking i/o and the function call will not return until the operation is complete (or until an exception is raised).
If you pass a callable object (a.k.a. a function) as the callback arg, the call will complete almost immediately and the return value will not be the final data but a replica of the HTTP Request (which can be useful for debugging e.g., when passing a lot of options). The callback will be invoked moments later, when the server response arrives.
Callbacks should expect two arguments and be of the form:
def mycallback(data, status): pass
The first argument will contain the response from the server, either as a unicode string or as a decoded json object.
The second argument allows for error checking and has five attributes of intrest:
ok
: False
if a response code >= 400 was receivedcode
: The numeric HTTP response codeheaders
: A dictionary of response headersexception
: Either None
or the exception that would have been raised
were this a non-blocking call. Feel free to raise it yourself.error
: Either None
or the class of the exception. This is redundant,
but also allows callback functions to use the syntax:if status.error is Conflict:
if isinstance(status.exception, Conflict):
When status.ok
is False
, the contents of the first argument are somewhat
variable. Sometimes Couch responds verbosely to error conditions and the data
argument will
contain a json object. At other times data
will simply be None
. When in
doubt, consult the HTTP API.
When you call the database from within a @relax
-decorated function you don't have to
provide a callback; the decorator will do it for you. To give you some idea of what happens when you
type yield
, the decorator-provided callback’s logic looks something like this:
def relax_callback(data, status): if status.exception: raise status.exception # (in the context of your function) else: return data # (and assign it to the yield's lvalue)
The rest of this guide will use the implicit callback style for brevity’s sake. Just keep in mind that anywhere you
see a yield
before a library call, you could pass a callback
argument
instead.
When thought of purely as a key/value store, a CouchDB installation is a cascade of json objects with three basic levels of hierarchy. In Couch nomenclature, a single Server can contain many Databases which in turn contain many Documents.
Servers are represented by Couch
objects. The constructor takes a url as an argument,
but will use the values in corduroy.defaults
to construct a default url if none is provided.
You can also include login credentials, either inline or as a 2-tuple.
If you haven’t overridden the host
and port
defaults, all of these instantiations should be equivalent:
couchdb = Couch('http://username:pass@<IP_ADDRESS>:5984') couchdb = Couch('http://<IP_ADDRESS>:5984', auth=('username','pass')) couchdb = Couch(auth=('username','pass'))
All three of the above will return with:
<Couch 'http://<IP_ADDRESS>:5984'>
Creating a Couch
object doesn’t actually connect to the server. As a result it’s safe to
call the constructor in an event handler without needing a callback. You can then use the object’s
all_dbs
method to obtain a list of available databases, monitor server activity with
tasks
, or read/write configuration options with config
. See the Reference
docs for other server-level operations.
In all likelihood the only methods you’ll use regularly are db
and create
which let you retrieve a reference to a specifc database using its name:
couch = Couch(auth=('user','pass')) try: mydb = yield couch.db('mine') except NotFound: mydb = yield couch.create('mine')
Since this pattern is fairly common, the above can be simplified to:
mydb = yield couch.db('mine', create_if_missing=True)
You don’t actually need to create a Couch
just to access a database. You can also
instantiate them directly by passing the full url to the db to the Database
constructor.
As with Couch
objects, the default server url will be prepended if necessary. Both of these
are equivalent:
db = Database('http://<IP_ADDRESS>:5984/some_db_name') db = Database('some_db_name')
<Database 'some_db_name'>
Creating a Database
object doesn’t contact the server, but an efficient check for its
presence can be performed by calling its exists
method. Similarly useful is the
info
method which performs a GET on the database’s root url.
CouchDB documents are dict-style json objects with two required keys: _id
and _rev
.
The _id
field is a unique-to-that-database string that allows the document to be requested
by name. The _rev
value is filled in by the server when you create or update a document. It
is also the basis of Couch’s transaction-less mechanism for detecting write conflicts (see the Eventual Consistency
section for details).
Corduroy will accept any dict
-like you pass and treat it as a document. The objects it
returns will by default use the corduroy.Document
class (though this can be overridden). The
Document
class inherits from dict
and has two noticeable differences from the
stdlib model:
To fetch a single document, call the Database
object’s get
method with the
desired _id
string. The Document
object it returns can be used just like a dictionary:
db = Database('underlings') ollie = yield db.get('lackey-129') print ollie print 'Mr. %(first)s %(last)s can be found at %(office)s.' % ollie
<Document lackey-129[1] {first:"Oliver", last:"Reeder", office:"Richmond Terrace"}> Mr. Oliver Reeder can be found at Richmond Terrace.
After making local changes, a new version of the document can be written to the db by calling the
save
method:
del ollie.office ollie.education = u'Oxbridge' yield db.save(ollie) print ollie
<Document lackey-129[2] {first:"Oliver", last:"Reeder", education:"Oxbridge"}>
Note that the number in brackets incremented as a result of the save. This number is the first portion
of the _rev
value (the full value looks more like “2-0348cd6cc49cb4cacdb9b94c87c83808
”).
The _rev
will change on every successful update. Also notice that we ignored the return value since the
save
method updates its argument as a side effect.
To remove a document from the db, pass a current version of the doc to the delete
method.
If your argument’s _rev
value doesn’t match the server copy, a conflict exception will
be raised.
try: yield db.delete(ollie) except Conflict: print 'Our doc is stale. Need to refetch and try again.'
To create a new document, save
a dict with a valid _id
string. Its _rev
will be set in the process:
newdoc = {'_id':'lackey-130', 'first':'Angela', 'last':'Heaney'} yield db.save(newdoc) print newdoc._rev
1-d0a259b5b8e71a3c0b0bc7facbb690d5
If you don’t specify an _id
, one will be chosen for you. Corduroy keeps a cache of identifiers
collected from the couch server’s _uuids
API. Relying on server-provided IDs can
purportedly improve performance since the generated identifiers are semi-sequential in a way that
is friendly to b-tree traversal. I take no definite stance on this.
anon = {'first':'Julius', 'last':'Nicholson'} yield db.save(anon) print anon._id, anon._rev
6efcdf33df6c82bfc53d7416c660ef5a 1-967a00dff5e02add41819138abb3284d
Both the get
and save
methods can accept either a single value or a list
as the first argument. To fetch multiple documents in a single request, pass a list of ID strings. The
return value is a list of Document
objects in the same order as the IDs list:
db = Database('backbench') doc_ids = ['ballentine', 'holhurst', 'swain'] docs = yield db.get(doc_ids) print docs[0]
<Document ballentine[9] {first:"Claire", last:"Ballentine", highly_regarded:True}>
Whereas the single-doc get
call will raise a NotFound
exception should the
requested doc not exist, a batch get
flags missing documents by including a None
at the
corresponding element of the results list.
To update multiple documents in a single request, pass your list of updated docs to save
. To
delete one or more docs in the batch, add a _deleted
key to each such doc before submitting
the request:
claire, geoff, ben = docs claire.standing = u'not standing' geoff._deleted = True ben.newsnight = {'paxman':1, 'swain':0} yield db.save([claire, geoff, ben])
One of the fundamental differences between CouchDB and traditional RDBMSs is the way data integrity and transactional semantics are handled. The tl;dr version is that Couch abandons nearly all SQL-ish guarantees and pushes responsibility for conflict resolution to the client.
This might sound like a mis-feature, but in the best Worse-is-Better tradition, the lack of abstraction over what-gets-written-when can force you to improve the way you structure your code. This may just be stockholm syndrome talking, but there’s an argument to be made that the client can do a better job of deciding how to deal with conflicts than a one-size-fits-all transaction could.
Regardless of how they’re rationalized, update conflicts are a common enough occurrance when dealing with documents that your code should generally consider them the norm rather than an exceptional condition.
The basic rule Couch uses to determine whether an update should succeed is quite simple:
The new version of a doc must have the same _rev
value as the copy currently
in the database.
To see how this on some level solves the entire problem of lost data consider the scenario where two
clients simultaneously download the same copy of a doc whose revision is currently 1
. Both
clients will modify their local copy of the doc and attempt to save it back to the database.
The first client to connect will succeed, since the _rev
of its modified doc matches
the value in the database. The server’s copy of the doc is then updated and its _rev
is
incremented to 2
.
When the second client’s save attempt is handled, the client’s _rev
(1
) no longer matches
the server’s copy (now 2
). As a result the save will fail and raise a Conflict
exception.
The second client must now fetch the newly updated doc from the server, re-apply its modifications, then attempt the save again.
The end result of this _rev
-matching rule is that any writes attempted by your code should
use the following algorithm:
_rev
from the newly-retrieved copy of the doc to
your local copy. Ideally do something clever that merges the two docs without losing any edits.GOTO 2
It’s worth acknowledging that doing things ‘correctly’ is a fair amount of (fairly repetitive) work. Thus the temptation to perform blindfolded writes and just hope for the best can be dangerously strong.
To try to make it easier to be responsible in this context, Corduroy treats every write as a potentially
conflict-inducing operation. In previous examples of the save
method, the return value was
ignored. Let’s now take a look at the ConflictResolution
object that save
returns:
# create a pair of new docs docs = [{'_id':'first', 'n':1}, {'_id':'second', 'n':2}] conflicts = yield db.save(docs) print conflicts
<Success: 2 docs updated>
# create a conflict by deleting the rev and re-saving del docs[1]._rev conflicts = yield db.save(docs) print conflicts
<Conflict: second>
From the repr strings you can see whether the write was successful and the list of conflicted IDs if not. To access this information from your code, the conflicts variable contains a pair of attributes to be inspected:
pending
: A dictionary (keyed by _id
) containing a reference to each doc whose
write attempt was unsuccessful.resolved
: A dictionary of all the successfully written docs.You could use the values in pending
to plan a fetch request, merge the results with your
local edits, then resubmit them. But since this is such a common pattern, the ConflictResolution
object provides a method called resolve
to handle all of this in one shot.
Since all parts of the Standard Recipe are identical except for step 4 (merging the local and fetched copies
of the doc), Corduroy allows you to encapsulate your merge logic in a function and pass that to
resolve
which will orchestrate the required HTTP traffic.
def mergefn(local_doc, server_doc): # just copy over the rev (a.k.a. not a real strategy) local_doc._rev = server_doc._rev return local_doc conflicts = yield db.save(docs) if conflicts.pending: print 'pre-merge: ', len(conflicts.pending) yield conflicts.resolve(mergefn) print 'post-merge:', len(conflicts.pending)
pre-merge: 1 post-merge: 0
The ConflictsResolution
object fetches the current versions of all the pending
docs, then repeatedly calls your merge function with local and remote copies of each. The merge function
should return a dictionary that merges the data in the divergent copies. These returned dictionaries will then
be sent to the server in a batch write attempt. If the merge function returns None
, no attempt to
write that doc will be made.
When the resolve
call completes, the pending
and resolved
dictionaries
will be updated to reflect the new state.
The same merge functions that that the resolve
method accepts can also be passed to the
Database.save
method directly. If any conflicts occur, a resolution will automatically be
attempted using your merge function.
def mergefn(local_doc, server_doc): local_doc._rev = server_doc._rev return local_doc yield db.save(docs, merge=mergefn)
Despite this particular merge function’s obvious unsuitability for use in production, a forced overwrite is ocasionally just the thing you need (especially during development). As a further shorthand, the above can be rewritten as:
yield db.save(docs, force=True)
Beyond accessing documents individually, Couch provides a mechanism for building named indexes called ‘views’ that can aggregate data across documents. Views are defined by javascript functions on the server that update the index every time a document is added or modified. From the client’s perspective they are a series of ‘rows’ with three attributes:
key
: A string or other json-serializable object (often a list)id
: The _id
of the document this row represents.value
: An arbitrary value returned by the serverside function.The mapping of rows to documents is not one-to-one, so it’s quite possible for one doc to be represented by multiple rows while another is omitted altogether.
Similarly, key
values may be unique between rows but
often will not be. In fact one of the more useful properties of views is that multiple documents can be
grouped together on the basis of having the same key.
To retrieve all of the rows from a view, call the database object’s view
method with
the ‘name’ of that view as an argument. Views are named according to the
design documents they live in, so for a view
called byname
in a design document called _design/employees
, its ‘name’
would be "employees/byname
".
The result of a call to view
is an iterable list of Row
objects. Here we
grab all of the rows from a view and begin printing them out:
db = Database('dosac') rows = yield db.view('employees/byname') print rows
<employees/byname: 17/17 rows>
for row in rows: print 'key:%s\t| id:%s' % (row.key, row.id)
key:abbott | id:emp-2c9792a3 key:coverley | id:emp-fad5095d key:cullen | id:emp-687e8224 ⋮ key:reeder | id:emp-c110c0a8
Since every row in a view has an associated key, you can selectively query the view only for rows matching a particular value. For instance, to grab just the first row the query would be:
yield db.view('employees/byname', key='abbott')
Queries with multiple keys are also possible:
yield db.view('employees/byname', keys=['coverley', 'murray'])
Part of what makes this a useful feature is that the documents associated with rows can also be included
in the response. As a result, views can be used to define aliases to documents independent of their potentially
unwieldy _id
values:
rows = yield db.view('employees/byname', key='abbott', include_docs=True) print rows[0].doc
<Document emp-2c9792a3[5932] {first:"Hugh", last:"Abbott", locale:"Unknown"}>
Since the rows in a view are sorted in ascending order based on their keys, you can also request all rows
within a range by specifying startkey
and endkey
values. To select all the “C”
names, the query wouldbe:
rows = yield db.view('employees/byname', inclusive_end=False, startkey='c', endkey='d') print [row.key for row in rows]
[u"coverley", u"cullen"]
If it’s not immediately apparent why the above query looks the way it does I highly recommend the CouchDB Guide’s chapter on the subject.
For the most part views as described so far – an ordered set of key/id/value rows – provide all
the data-access flexibility you need for reading out the state of your database. But Couch also
allows for a serverside pre-processing step to be associated with each view through the use of
a reduce
function.
Couch’s semantics would seem to encourage using reduce
as a
way to create denormalized copies of your view data (e.g., creating a list of all the values for
a given key). But in practice this sort of usage is to be avoided due to an unfortunate trade-off
in Couch’s b-tree-based internal design.
Instead, reduce
should be thought of as a way to convert rows into a handful
of numeric values – often only one. Accepting that limitation, it frequently makes sense to use one of
Couch’s built-in reductions
instead of writing your own. In combination with View Collation
this becomes a surprisingly powerful technique.
Here is a view that uses the _count
built-in reduction on rows keyed by the date.
Views with reduce
functions will return the output of that reduction by default. The
pre-reduction rows can still be accessed with the query:
for row in (yield db.view('chronological/counts', reduce=False)): print row.key
["2007","11","28"] ["2007","11","29"] ["2007","11","29"] ⋮ ["2007","12","02"]
The group
and group_level
keyword arguments allow you to control whether
the reduce
function is applied uniformly to the rows (resulting in a single value),
or to groupings based on shared key values.
for row in (yield db.view('chronological/counts', group=True)): print "%(key)s → %(value)i" % row
["2007","11","28"] → 1 ["2007","11","29"] → 17 ["2007","11","30"] → 3 ["2007","12","01"] → 92 ["2007","12","02"] → 50
for row in (yield db.view('chronological/counts', group_level=2)): print "%(key)s → %(value)i" % row
["2007","11"] → 20 ["2007","12"] → 142
Couch is not limited to presenting your documents and views as json-formatted text. It allows you to define special handlers to transform the raw data into HTML, BibTeX, WAD or whatever is appropriate for your application.
These custom formatters are defined in a design document specific to your database and are referred to as ‘lists’ (which process the output of views) and ‘shows’ (which process the content of documents). Their client APIs are quite similar, in both cases you provide the name of the formatter along with the view or document it will be applied to. In response an object is returned with two attributes of interest:
headers
: A dictionary of response headersbody
: A bytestring (or decoded json object if a mime-type of application/json
was
present in the headers)‘Show’ functions are reuseable javascript routines that have access to a specified document as well
as any query arguments passed in the request. Here the function csv
in the design doc
records
is being used to format a document. The include_titles
argument
instructs this particular ‘show’ to output a header row in addition to the document data:
db = Database('mannion') response = yield db.show('records/csv', '1978-wotw', include_titles=True) print response.headers['Content-Type']
text/csv
print response.body
artist,title,review,doc_id Jeff Wayne,War of the Worlds,Stimulating,1978-wotw
‘List’ functions use similar syntax but apply to a view instead of a single document. In addition to query arguments, the same slicing operations that apply to views can be included to filter out selected rows before formatting:
db = Database('tucker') response = yield db.list('agenda/html', 'nomfup', key='n', limit=3, descending=True) print response.body
<ul><li>Nicola Murray</li><li>Newcastle</li><li>National Trust</li></ul>
If your list function is general enough, you can apply it to other views as well; even views in other design documents:
response = yield db.list('agenda/html', 'bollockings/byday', key='2007-10-13') print response.body
<ul><li>Steve Fleming 13:00-13:07</li><li>Julius Nicholson 13:30–</li></ul>
Reliable, master-less replication is one of Couch’s marquee features. A replication involves a source
and a target database and propagates changes from the former to the latter. To copy an existing database,
pass the source and target database names (or urls) to a Couch
object:
couch = Couch() yield couch.replicate('olddb', 'newdb', create_target=True)
Database
objects can also replicate themselves through their push
and pull
methods. Their behavior is analogous to the eponymous commands used by distributed version control systems.
These operations are one-way in nature meaning a full synchronization of two databases (each with local edits)
requires a reciprocal push and pull:
local_db = Database('localdb') remote_db = Database('http://elsewhere.com:5984/remotedb') yield local_db.push(remote_db) yield local_db.pull(remote_db)
In addition to one-off, ‘anonymous’ replications, Couch maintains a system-controlled database called _replicator
to track named replications over time. This database is exposed by the Couch
object and behaves
like any other (supporting get
, save
, and friends).
The _replicator
database has the special property that when docs of a certain form are created,
they will trigger a new replication. Its ongoing status can then be monitored by polling the document:
couch = Couch() repl = { "_id":"local-to-remote", "source":"localdb", "target":"http://elsewhere.com:5984/remotedb", "continuous":True } yield couch.replicator.save(repl) repl_doc = yield couch.replicator.get('local-to-remote') print json.dumps(repl_doc, indent=2)
{ "_id":"local-to-remote", "source":"localdb", "target":"http://elsewhere.com:5984/remotedb", "continuous":true, "_replication_id": "c0ebe9256695ff083347cbf95f93e280", "_replication_state": "triggered", "_replication_state_time":<PHONE_NUMBER> }
As a convenience, all of the replication methods accept a keyword argument called _id
. If included,
a new document will be created in the _replicator
database using the arguments for its fields.
Thus the previous example could be rewritten as:
local_db = Database('localdb') yield local_db.push(remote_db, "http://elsewhere.com:5984/remotedb", continuous=True, _id='local-to-remote')
Or if you want to get fancy:
repl = { "_id":"local-to-remote", "target":"http://elsewhere.com:5984/remotedb", "continuous":True } yield local_db.push(**repl)
At the filesystem level, a couch database is stored as something more akin to a journal file than a snapshot of the current state. Every document modification is appended to this journal and the ‘live’ database can be thought of as the result of playing back all these modification records in order.
Beyond being just an implementational detail, this alternative method of representing a database (as a sequence
of changesets) is exposed through the _changes
API. Your application code can make use of this data in two main ways:
The former can be useful for reinventing differently-sized wheels (see also Replication), while the latter can be used to trigger scripted events such as cache invalidation or summary statistics generation.
When requesting a list of changes, you can either specify no arguments (in which case somewhere between 0 and update_seq
change records will be returned), or you can bracket the time period in order to limit the response size:
db = Database('watched') info = yield db.info() print info.update_seq
11519
changes = yield db.changes() print "seq: %i (%i changes)"% (changes.last_seq, len(changes.results))
seq: 11519 (210 changes)
changes = yield db.changes(since=11500, limit=5) print "seq: %i (%i changes)"% (changes.last_seq, len(changes.results))
seq: 11506 (5 changes)
Each element of the changes.results
list corresponds to a document and contains a delta relative
to its previous state. For all the details see the CouchDB Book’s chapter on the subject.
Changes can also be accessed as a ‘feed’ in which an HTTP connection is left open and Couch will write
individual change notifications to it as they occur. To listen for changes in this manner, request a
continous feed and pass an explicit callback (i.e., do not call yield
this time):
def listener(last_seq, changes): pass feed = db.changes(since=11500, feed='continuous', callback=listener)
The return value of a feed request is a ChangesFeed
object. It will keep the connection alive
and handles the invocation of your callback at regular intervals (see the latency
parameter).
The feed will continue listening until it is explicitly stopped:
feed.stop()
The overall documentation scene for Couch isn’t quite as focused as it could be. There’s quite a bit of good infomation out there, but it’s scattered all over the net. Here are some I’ve found useful:


Upload the WCA registration csv file to automatically sort competitors into groups
Input the csv file and automatically generate scoresheets that are sorted by event and group number (organizers just need to cut the scoresheets)
Sample csv file if you don't want to use the output of "Generate Groups" for group assignments


| bag/__init__.py |
0 |
0 |
0 |
100% |
| bag/admin.py |
0 |
0 |
0 |
100% |
| bag/apps.py |
3 |
3 |
0 |
0% |
| bag/contexts.py |
88 |
62 |
0 |
30% |
| bag/migrations/__init__.py |
0 |
0 |
0 |
100% |
| bag/models.py |
0 |
0 |
0 |
100% |
| bag/templatetags/__init__.py |
0 |
0 |
0 |
100% |
| bag/templatetags/bag_tools.py |
5 |
1 |
0 |
80% |
| bag/test_views.py |
21 |
0 |
0 |
100% |
| bag/tests.py |
9 |
0 |
0 |
100% |
| bag/urls.py |
3 |
0 |
0 |
100% |
| bag/views.py |
51 |
41 |
0 |
20% |
| checkout/__init__.py |
1 |
0 |
0 |
100% |
| checkout/admin.py |
12 |
0 |
0 |
100% |
| checkout/apps.py |
5 |
0 |
0 |
100% |
| checkout/forms.py |
18 |
0 |
0 |
100% |
| checkout/migrations/0001_initial.py |
6 |
0 |
0 |
100% |
| checkout/migrations/0002_auto_20201111_1646.py |
4 |
0 |
0 |
100% |
| checkout/migrations/0003_auto_20201111_1719.py |
5 |
0 |
0 |
100% |
| checkout/migrations/0004_order_user_profile.py |
5 |
0 |
0 |
100% |
| checkout/migrations/0005_auto_20201128_1437.py |
4 |
0 |
0 |
100% |
| checkout/migrations/0006_auto_20201129_1625.py |
4 |
0 |
0 |
100% |
| checkout/migrations/0007_auto_20201129_1626.py |
4 |
0 |
0 |
100% |
| checkout/migrations/__init__.py |
0 |
0 |
0 |
100% |
| checkout/models.py |
54 |
13 |
0 |
76% |
| checkout/signals.py |
9 |
2 |
0 |
78% |
| checkout/test_forms.py |
36 |
0 |
0 |
100% |
| checkout/test_models.py |
20 |
0 |
0 |
100% |
| checkout/test_views.py |
0 |
0 |
0 |
100% |
| checkout/urls.py |
4 |
0 |
0 |
100% |
| checkout/views.py |
87 |
71 |
0 |
18% |
| checkout/webhook_handler.py |
80 |
65 |
0 |
19% |
| checkout/webhooks.py |
28 |
19 |
0 |
32% |
| contact/__init__.py |
0 |
0 |
0 |
100% |
| contact/admin.py |
0 |
0 |
0 |
100% |
| contact/apps.py |
3 |
3 |
0 |
0% |
| contact/migrations/__init__.py |
0 |
0 |
0 |
100% |
| contact/models.py |
0 |
0 |
0 |
100% |
| contact/test_views.py |
14 |
0 |
0 |
100% |
| contact/urls.py |
3 |
0 |
0 |
100% |
| contact/views.py |
17 |
10 |
0 |
41% |
| home/__init__.py |
0 |
0 |
0 |
100% |
| home/admin.py |
0 |
0 |
0 |
100% |
| home/apps.py |
3 |
3 |
0 |
0% |
| home/migrations/__init__.py |
0 |
0 |
0 |
100% |
| home/models.py |
0 |
0 |
0 |
100% |
| home/test_views.py |
6 |
0 |
0 |
100% |
| home/urls.py |
3 |
0 |
0 |
100% |
| home/views.py |
3 |
0 |
0 |
100% |
| products/__init__.py |
0 |
0 |
0 |
100% |
| products/admin.py |
9 |
0 |
0 |
100% |
| products/apps.py |
3 |
3 |
0 |
0% |
| products/forms.py |
15 |
0 |
0 |
100% |
| products/migrations/0001_initial.py |
6 |
0 |
0 |
100% |
| products/migrations/0002_auto_20201105_1401.py |
4 |
0 |
0 |
100% |
| products/migrations/0003_auto_20201116_1548.py |
4 |
0 |
0 |
100% |
| products/migrations/0004_auto_20201116_1549.py |
4 |
0 |
0 |
100% |
| products/migrations/0005_auto_20201123_1549.py |
4 |
0 |
0 |
100% |
| products/migrations/0006_auto_20201128_1437.py |
4 |
0 |
0 |
100% |
| products/migrations/0007_category_image.py |
4 |
0 |
0 |
100% |
| products/migrations/0008_auto_20201129_1439.py |
4 |
0 |
0 |
100% |
| products/migrations/0009_auto_20201129_1456.py |
4 |
0 |
0 |
100% |
| products/migrations/0010_auto_20201129_1534.py |
4 |
0 |
0 |
100% |
| products/migrations/__init__.py |
0 |
0 |
0 |
100% |
| products/models.py |
20 |
0 |
0 |
100% |
| products/test_forms.py |
44 |
0 |
0 |
100% |
| products/test_models.py |
12 |
0 |
0 |
100% |
| products/test_views.py |
14 |
0 |
0 |
100% |
| products/urls.py |
3 |
0 |
0 |
100% |
| products/views.py |
98 |
67 |
0 |
32% |
| products/widgets.py |
8 |
0 |
0 |
100% |
| profiles/__init__.py |
0 |
0 |
0 |
100% |
| profiles/admin.py |
0 |
0 |
0 |
100% |
| profiles/apps.py |
3 |
3 |
0 |
0% |
| profiles/forms.py |
16 |
0 |
0 |
100% |
| profiles/migrations/0001_initial.py |
8 |
0 |
0 |
100% |
| profiles/migrations/0002_auto_20201128_1437.py |
4 |
0 |
0 |
100% |
| profiles/migrations/0003_auto_20201128_1608.py |
4 |
0 |
0 |
100% |
| profiles/migrations/0004_auto_20201129_1448.py |
4 |
0 |
0 |
100% |
| profiles/migrations/__init__.py |
0 |
0 |
0 |
100% |
| profiles/models.py |
21 |
0 |
0 |
100% |
| profiles/test_forms.py |
9 |
0 |
0 |
100% |
| profiles/test_models.py |
14 |
0 |
0 |
100% |
| profiles/test_views.py |
27 |
0 |
0 |
100% |
| profiles/urls.py |
3 |
0 |
0 |
100% |
| profiles/views.py |
26 |
10 |
0 |
62% |


CopperheadOS is now GrapheneOS
CopperheadOS was renamed to GrapheneOS in 2019. It was temporarily known as the Android Hardening project in 2018 before a permanent name had been chosen. For more details on why the project was renamed, see our history page. For the historical release notes of the original CopperheadOS, see our legacy changelog page. The /r/CopperheadOS subreddit was historically the central hub of the community along with a bridged IRC/Matrix channel that's no longer available.
GrapheneOS is the continuation of the original open source project by the original development team. Our source code repositories have been used since CopperheadOS transitioned to being directly based on the Android Open Source Project in 2015. The prior repositories predate the CopperheadOS branding and were also owned by us. It can be confirmed that our repositories are the original ones from the GitHub network graphs showing the forks over the years.
Ownership
We own the historical CopperheadOS source code, documentation and accounts tied to the open source project. Our legacy Twitter account still needs to be returned to us so that it can be renamed and made into an archive.
Copperhead has no valid claim over the ownership of the source code. It was not developed for them. They were involved as a sponsor for the work and had permission to sell products based on it, similar to companies selling devices with GrapheneOS. We've learned a lot of lessons from what happened and are being very careful to avoid being strongly associated with any particular company in the future.
New closed source product reusing the legacy branding
The new product branded as CopperheadOS is closed source and not associated with the original project. They took our project's previous name and copied our legacy source code and documentation. Attribution to us has been stripped away and they pretend to be the ones who created it.
They've essentially stolen the identity of our open source project and have invested substantial resources into misrepresenting GrapheneOS as being a new project. They've built a business based on taking credit for research and development not done by them. Substantial damage has been done to GrapheneOS through an organized campaign of misinformation and harassment.
New CopperheadOS vs. GrapheneOS
The new CopperheadOS is a shadow of the historical GrapheneOS code. They've continued copying portions of our newer generation code but haven't developed any significant privacy or security improvements on their own. It's a poor imitation of the original. It has a fraction of the privacy and security improvements and lacks a team with an understanding of how they work. It often doesn't receive timely security updates. It has made serious mistakes compromising user privacy and security.
CopperheadOS is a paid product and has license enforcement compromising user privacy and security through tracking devices to implement DRM. They use the outrageous business model of charging users for security updates rather than simply selling them the software or devices with it.
GrapheneOS devices can be purchased from a bunch of different companies, organizations and individuals. Many of these offer customer support. Unlike CopperheadOS, it's still open source software and you aren't being charged to simply get the OS updates. Anyone can sell devices with GrapheneOS without permission from the project due the open source licensing. Many of these sellers voluntarily contribute back to the project.
GrapheneOS is far more actively developed than the new CopperheadOS and has substantially more resources available, including significantly more funding.


I am a graduate from the Cegep Heritage College Computer Science program achieving Honour Roll (80% overall average) in every semester. I have become a skilled Programmer and Web Systems Developer. Additionally, I am experienced in databases and System Projects Development using the Agile methodology. For the past couple of years, I have been enjoying my favorite adventure and hobby, mobile app development. Please feel free to learn more about me using my portfolio website and LinkedIn.
Project: Foreign Worker System
Designed and developed a web system with .NET C# using Visual Studio and TFS.Project: Job Bank Mobile App
Designed and developed the Job Bank mobile app using Framework7; a HTML, CSS & JavaScript based framework.Honours: Honour Roll
I achieved Honour Roll (80% overall average) in every semester except one, when I achieved Dean's Honour Roll (90% overall average).Award: DPI Annual Student Award
July 2017 I was awarded the 2017 DPI student award by demonstrating my leadership skills, passion and drive to make a career out of Computer Science, recognized by Laura Simpson and Stéphan Cousineau.Award: Academic Achievement Award
October 2017 I was awarded the Academic Achievement Award by demonstrating my strong skills in the IT field.


Connection-State is:
INITIAL
Realtime Datastore
Firstname
Lastname
Publish
Send test-event with
Subscribe
Request
Make multiply request
-
Response
Multiply number with:


There are two parts to BrainTool:
- The Topic Manager window where you manage your topics and control your browser.
- The Bookmarker where you add new pages into your topic tree.
Click the BrainTool icon (or use Alt-b) to open the Bookmarker to save the current page. Use the Topic Manager to open and close saved browser pages, singly or as a group.
To get you started I'm going to:
- Open the Topic Manager on the left of this screen.
- Resize this window to accommodate. (Feel free to undo that later.)
- Open the BrainTool welcome page with new user information.
| Topic: | |
|
|
|
| Title: | |
| URL: | |


| The Sun |
A G2 star. Radius (km): 695000 Mass (kg): 1.99e30 Density: 1.41 Abo: ? Vo: -26. Rotate (days): 24.6 temperature: 5800 K (surface) 15,600,000 K (core)
| Mercury |
The eighth largest planet. Distance (Mm): 57910 (.39 AU) Period (days): 87.97 (.24 EP) Inclination: 7.00 Eccentricity: 0.21 Radius (km): 2440 (.38 ER) Mass (kg): 3.30e23 Density: 5.43 Abo: .11 Vo: -1.9 Rotate (days): 58.6
| Venus |
The sixth largest planet. Distance (Mm): 108200 (.72 AU) Period (days): 224.70 (.62 EP) Inclination: 3.39 Eccentricity: 0.01 Radius (km): 6052 (.95 ER) Mass (kg): 4.87e24 Density: 5.24 Abo: .65 Vo: -4.4 Rotate (days): -243
| Earth |
The fifth largest planet. Distance (Mm): 149600 (1 AU) Period (days): 365.26 (1 EP) Inclination: 0.00 Eccentricity: 0.02 Radius (km): 6378 (1 ER) Mass (kg): 5.97e24 Density: 5.52 Abo: .30 Vo: - Rotate (days): 0.99
| Mars |
The seventh largest planet. Distance (Mm): 227940 (1.52 AU) Period (days): 686.98 (1.88 EP) Inclination: 1.85 Eccentricity: 0.09 Radius (km): 3397 (.53 ER) Mass (kg): 6.42e23 Density: 3.93 Abo: .15 Vo: -2.0 Rotate (days): 1.03
| Notes |


--- layout: documentation title: IPv6ExtHeaderType ---
In IPv6, optional internet-layer information is encoded in separate headers that may be placed between the IPv6 header and the upper-layer header in a packet. An IPv6 packet may carry zero, one, or more extension headers, each identified by the Next Header field of the preceding header. http://tools.ietf.org/html/rfc2460.
| Field Name | Type | Description |
|---|---|---|
| Hop_by_Hop_Options0..1 | HopByHopOptionsType |
The Hop-by-Hop Options header is used to carry optional information that must be examined by every node along a packet's delivery path. It carries a variable number of type-length-value (TLV) encoded options. |
| Routing0..1 | RoutingType |
The Routing header is used by an IPv6 source to list one or more intermediate nodes to be "visited" on the way to a packet's destination. http://tools.ietf.org/html/rfc2460. |
| Fragment0..1 | FragmentType |
The Fragment header is used by an IPv6 source to send a packet larger than would fit in the path MTU. A fragment packet begins with an unfragmentable part consisting of the IPv6 header plus all extension headers up to and including the routing header. We don't include it for this field because the data is already stored in other elements. We provide the elements necessary for the Fragmentable Part. http://tools.ietf.org/html/rfc2460. |
| Destination_Options0..2 | DestinationOptionsType |
The Destination Options header is used to carry optional information that needs to be examined only by a packet's destination node(s). |
| Authentication_Header0..1 | AuthenticationHeaderType |
Follows RFC2402. The IP Authentication Header is used to provide connectionless integrity and data origin authentication for IP datagrams and to provide protection against replays. http://www.ietf.org/rfc/rfc2402.txt. |
| Encapsulating_Security_Payload0..1 | EncapsulatingSecurityPayloadType |
Follows RFC2406. ESP is used to provide confidentiality, data origin authentication, connectionless integrity, an anti-replay service (a form of partial sequence integrity), and limited traffic flow confidentiality. |


I have Martin's sketch up and running (with a few modifications to use different CT connections). However, I'm not getting a reading from my temperature sensor. My output looks like this:
514 511 510 239.41 811.56 4.36 0.00 49.99 0.00 0.00 PLL is locked
I have CT1 as my grid input (811.56), CT2 is my Solar PV (4.36). The voltage and frequency look fine, but I'm getting 0.00 for the temperature.
I know the sensor is working because the previous sketch (emonTxV3 Discrete Sampling) was displaying the temperature correctly. I changed the W1PIN define to 5 for the emonTx V3.
The pin changes I made are:
// Arduino I/O pin useage
#define VOLTSPIN 0
#define CT1PIN 2
#define CT2PIN 4
#define LEDPIN 6
//#define SYNCPIN 6 // this output will be a 50Hz square wave locked to the 50Hz input
//#define SAMPPIN 5 // this output goes high each time an ADC conversion starts or completes
#define RFMSELPIN 4
#define RFMIRQPIN 3
#define SDOPIN 12
#define W1PIN 5 // 1-Wire pin for temperature
#define TRIACPIN 2 // triac driver pin
Is there anything else I need to change in this sketch for the emonTX V3 ?
Thanks,
Allen
Re: Solar PV power diversion with emonTx V3 using a PLL and temperature measurement
Are you powering the temperature sensor with the output from DIO 19? If you are, have you turned that on? Remember, the emonTx V2 powered the temperature sensor all the time, and that is the version that Martin's code was written for.
(See in the default emonTx V3 sketch:
const byte DS18B20_PWR= 19; // DS18B20 Power
for a hint.)
Re: Solar PV power diversion with emonTx V3 using a PLL and temperature measurement
I had noticed the statements switching the power on in the emonTx V3 sketch, but having never had a V2 I didn't realise the difference.
However, I have tried putting the digitalWrite(DS18B20_PWR, HIGH) statement in the readTemperature() method of Martin's sketch, but I still get nothing back. So I now have (where I have defined DS18B20_PWR to be 19):
int readTemperature()
{
byte buf[9];
int result;
digitalWrite(DS18B20_PWR, HIGH);
oneWire.reset();
oneWire.write(SKIP_ROM);
oneWire.write(READ_SCRATCHPAD);
for(int i=0; i<9; i++) buf[i]=oneWire.read();
if(oneWire.crc8(buf,8)==buf[8])
{
result=(buf[1]<<8)|buf[0];
// result is temperature x16, multiply by 6.25 to convert to temperature x100
result=(result*6)+(result>>2);
}
else result=BAD_TEMPERATURE;
digitalWrite(DS18B20_PWR, LOW);
return result;
}
Can anyone help?
Re: Solar PV power diversion with emonTx V3 using a PLL and temperature measurement
I used 2 functions to access the DS18B20 convertTemperature() starts the conversion and readTemperature() reads the result.
By turning the power off in readTemperature() you will have no power during the conversion process. Since you are using the PLL you presumably are running on mains power so there is no reason not to leave the DS18B20 power on all the time.
Re: Solar PV power diversion with emonTx V3 using a PLL and temperature measurement
I tried just switching it on in the setup(), but that didn't help. So I also added it to the convertTemperature() and readTermperature() method, but still no output.
void convertTemperature()
{
oneWire.reset();
digitalWrite(DS18B20_PWR, HIGH);
oneWire.write(SKIP_ROM);
oneWire.write(CONVERT_TEMPERATURE);
}
I tried the statement both before and after the oneWire.reset() call incase that was doing something. What was the reason for not using the DallasTemperature library?
Re: Solar PV power diversion with emonTx V3 using a PLL and temperature measurement
In the above the power will still be off for the oneWire reset command. Just turn the power on in setup() and remove all other references to DS18B20_PWR.
The Dallas library spends too much time waiting for things to happen so it can't be used with continuous monitoring.
Re: Solar PV power diversion with emonTx V3 using a PLL and temperature measurement
I solved the problem. I was forgetting the pinMode() command. So now these two lines are in my Setup() function and that is all.
pinMode(DS18B20_PWR, OUTPUT);
digitalWrite(DS18B20_PWR, HIGH);
Re: Solar PV power diversion with emonTx V3 using a PLL and temperature measurement
I now have one outstanding issue. I am driving an SSR to simplify the output stage, directly from the Dig2 (pin 4 on connector block) and GND (pin 3 on the connector block). This is giving me an switching voltage of around 3.3V, which hard switch the SSR.
In fact it seems that there is a resistance between the output pins that varies depending on the switching voltage. If I use a 9V battery to switch the relay I get a lower output resistance that 3.3V.
Is there a way to use the 5V supply to switch the relay instead of the 3.3V ?
Re: Solar PV power diversion with emonTx V3 using a PLL and temperature measurement
I've hit a problem that I hope someone can help me with. My temperature sensor has suddenly started returning 300 Celsius. I can see from Martin's sketch that this is a default value when something is wrong. I'm not quiet able to understand what the oneWire code is doing and why this might be.
I loaded up the default emonTxV3 Discrete Sampling sketch and that is reporting the temperature correctly. So there is something in the code, but I don't know what.
Can anyone help?
Re: Solar PV power diversion with emonTx V3 using a PLL and temperature measurement
"So there is something in the code" Not necessarily. It might also be a power supply issue - if the supply is dipping because you are drawing too much current from the 3.3 V rail, that could easily cause the DS18B20 to malfunction. The minimum supply voltage is only 3.0 V, so it doesn't have far to go. Does the DS18B20 work correctly with your code if you disconnect the SSR? If it does, I might be right, if not, I am probably wrong.
To understand the DS18B20 code, you need to study its data sheet. On page 10, the explanation starts with an overview and goes into increasing levels of detail, before giving examples on page 18.
Re: Solar PV power diversion with emonTx V3 using a PLL and temperature measurement
My setup has now been diverting to the hot water tank for a few days and it's looking good. I now have 2 temperature sensors connected (top and bottom of cylinder).
Can anyone tell me where in Martin's sketch to put the logic to switch off diverting when a set temperature is reached?
Re: Solar PV power diversion with emonTx V3 using a PLL and temperature measurement
The actual comparison logic needs to be done infrequently, so immediately after you've got the temperature is a good place for that - set a logical flag and use that every cycle to determine whether to block setting the triac trigger.
Lines 328 or 331 look to be promising candidates, depending on whether you want to allow the manual triggering or not. "divertFlag" is used eventually to calculate the power diverted, so you need to make sure that is dealt with correctly too. I can't see any other traps that might catch you out.


Statistics
bar_chart
Choose a chart
Completion View
Time View
Current view: {{featureTitle}}
Total Count:
{{eventList.length}}


Robot Drive (2 Speed Controllers)
What is it?
Controller for handling robot drive based on a definition of
the motor configuration. The robot drive controller handles basic
driving for a robot. Currently, 2 and 4 motor standard drive
trains and holonomic drive trains are supported.
Robot Drive has been deprecated for 2018, and replaced by
DifferentialDrive or MecanumDrive
Properties
- Left Motor
- The motor to use as the left motor for robot drive
actions.
- Left Motor Inverted
- Whether or not the left motor is mounted backwards.
- Right Motor
- The motor to use as the right motor for robot drive
actions.
- Right Motor Inverted
- Whether or not the right motor is mounted backwards.
- Sensitivity
- Maximum Output
- Maximum allowable output to the motors, generally this
should be one.
- Safety Enabled
- Whether or not motor safety should be in effect
- Safety Expiration Time
- How long before motor safety kicks in.
See Also


 No one leaves until completing the qualification in this room.
You should activate the reading desk where the correct memoir is placed to cancel the seal.


| Figure 1 |
Map of China, showing the observed species richness for vasc ... |
| Figure 2 |
The biodiversity of vascular plant species in China. (A) Dar ... |
| Figure 3 |
Variables importance derived from random forest models showe ... |
| Figure 4 |
Predicted distribution of six dark species under current and ... |


--- layout: documentation title: ICMPv6TimeExceededType ---
Time exceeded error message; ICMP v6 type=3.
| Field Name | Type | Description |
|---|---|---|
| Hop_Limit_Exceeded0..1 | boolean |
Hop limit exceeded in transit (ICMP v6 code=0). |
| Fragment_Reassem_Time_Exceeded0..1 | boolean |
Fragment reassembly time exceeded (ICMP v6 code=1). |


Give this link to others so they can donate on your behalf:
{{ domain }}{% url 'installers' username %}{% extends "control/control_base.html" %} {% block title %} Get Donations - {{ TESTBED }} {{ CLEARINGHOUSE }} {% endblock title %} {% block style %} {{ block.super }} {% endblock style %} {% block script %} {{ block.super }} {% endblock script %} {% block nav_getdonations %}
Give this link to others so they can donate on your behalf:
{{ domain }}{% url 'installers' username %}


Back
Forward
Featured Project
Tsunami Waves
Foundation
Featured Project
Tropical Coffee
Featured Project
Arrowhead
Building Supply


Borrowers who do not have a last_cko_date or last_authentication_date within the last year are excluded.


This is definitely not supported at present, thank you for the catch. I believe I will add a .slug() method to the Taxonomies query builder to allow terms to be provided by slug; however, this depends on WP-API/WP-API#347, because the version of the API in the plugin directory does not support filtering taxonomy collection endpoints. I am not sure how to proceed in releasing this feature given that it is not in the officially-released version of the plugin.
What version are you using? You can try this query; in the latest "master" version of the plugin, it will return an array with a single element:
That makes sense. Filtering for taxonomy collections is not included in 1.1.1, so there won't be any way to get at a specific term until a new plugin version is released; I will add the .slug convenience method at that point.
The best I can offer is to filter down the returned collection:
It is not super efficient to request all terms each time, so you may want to request all of them and cache that collection locally in a variable or an LRU cache to speed up the retrieval.
In the intervening year, this has been broken again by the v2 beta upgrades: WP-API/WP-API#924 identifies that filter is not currently supported on the /categories or /tags endpoints.
WP-API/WP-API#2065 has been opened to identify whether this will ever be reinstated; in the meantime, #126 will add a demonstration of using the ?search parameter to slightly more efficiently retrieve a specific term by slug (basically the same "get them all and search for the one you want in the response" approach detailed above, but with less overhead due to the narrowing effect of ?search=the-slug).
In the docs (frontpage) it says:
This works with the ID, but not with the slug :(. Is this something that changed?
HOST/wp-json/taxonomies/post_tag/terms/42 works HOST/wp-json/taxonomies/post_tag/terms/sociaal-ondernemerschap doesn't
This may just have been a mistake on my part, I can't find a prior version of the API that did support this—I'll look into it today
This is definitely not supported at present, thank you for the catch. I believe I will add a
.slug()
method to the Taxonomies query builder to allow terms to be provided by slug; however, this depends on WP-API/WP-API#347, because the version of the API in the plugin directory does not support filtering taxonomy collection endpoints. I am not sure how to proceed in releasing this feature given that it is not in the officially-released version of the plugin.What version are you using? You can try this query; in the latest "master" version of the plugin, it will return an array with a single element:
c.f. update: the actual PR that landed this change was WP-API/WP-API#401, not 347
The filter by slug is what I had in my code (and which I think worked last week?), but now it returns all items, and doesn't filter.
What version of the WP-API plugin are you using?
The latest stable from wordpress.org, 1.1.1
That makes sense. Filtering for taxonomy collections is not included in 1.1.1, so there won't be any way to get at a specific term until a new plugin version is released; I will add the
.slug
convenience method at that point.The best I can offer is to filter down the returned collection:
It is not super efficient to request all terms each time, so you may want to request all of them and cache that collection locally in a variable or an LRU cache to speed up the retrieval.
I think I'll update the WP-API on the server. Thnx for your input!
In the intervening year, this has been broken again by the v2 beta upgrades: WP-API/WP-API#924 identifies that
filter
is not currently supported on the/categories
or/tags
endpoints.WP-API/WP-API#2065 has been opened to identify whether this will ever be reinstated; in the meantime, #126 will add a demonstration of using the
?search
parameter to slightly more efficiently retrieve a specific term by slug (basically the same "get them all and search for the one you want in the response" approach detailed above, but with less overhead due to the narrowing effect of?search=the-slug
).


This is a test paragraph. It is not too long. And not too short.
// how about some javascript?
function show() {
alert('show me the money!');
}
Do you enjoy those lists? TELL ME!
throw in a random blockquote too!
how about a nice image?
![i love kittens](http://placekitten.com/200/200)


With it being late May, the beginning of summer is right around the corner. Along with that comes a new release of our libraries. Unfortunately, there was an issue with our first attempt (19.5.0) so we created a point release (19.5.1), which fixes the problem. Here are the changes for both 19.5.0 and 19.5.1
com.twitter.finagle.http.MediaType
,
MediaType#typeEquals
for checking if two media types have the same type and
subtype, ignoring their charset, and MediaType#addUtf8Charset
for easily
setting a utf-8 charset. ec0953f1RequestLogger
Stack parameter on your Client
or Server
. ee9cb4ecNameTree.Union
‘s are ignored in the
final binding result. 2fde4d2dc.t.f.client.EndpointerModule
and c.t.f.pushsession.PushStackClient
public
and protected APIs have been changed to use the abstract java.net.SocketAddress
instead of the
concrete java.net.InetSocketAddress
as relying on the concrete implementation was not
necessary. 77a3cdfdwithMaxRequestSize(size)
API
method has been removed. For Finagle HTTP servers, the
withMaxResponseSize(size)
method has been removed. The underlying Stack
params which are set by these methods are respectively HTTP server and HTTP
client side params only. Using these removed methods had no effect on the
setup of Finagle HTTP clients and servers. 5eb3ae24StatsReceiver
implementation to use in the
underlying EmbeddedTwitterServer
instead of always providing an InMemoryStatsReceiver
implementation. 7a486fd2Filter.TypeAgnostic
implementation for the FinagleRequestScopeFilter
for better compatibility with Thrift servers. Update the FinagleRequestScope to make more idiomatic
use of Context locals. 451cff77NullValidationFinatraJacksonModule
. 401d7285c.t.inject.app.DtabResolution
to help users apply supplemental Dtabs added by
setting the dtab.add flag. This will append the supplemental Dtabs to the
Dtab.base in a premain function. 6c4eeda0postInjectorStartup
phase, such that any admin routes are available to be hit during server warmup. Simplify HttpWarmup
utility to make it clear that it can and should only be used for sending requests to endpoints added
to the server’s configured HttpRouter
. The forceRouteToAdminHttpMuxers
param has been renamed
to admin to signal that the request should be sent to the HttpRouter#adminRoutingService
instead
of the HttpRouter#externalRoutingService
. Routing to TwitterServer HTTP Admin Interface via this
utility never worked properly and the (broken) support has been dropped. 0cd3ed69com.twitter.finatra.kafka.test.KafkaTopic
, and
com.twitter.finatra.kafka.test.utils.PollUtils
methods to take
com.twitter.util.Duration
instead of org.joda.time.Duration
. 94c051b3com.twitter.finatra.http.EmbeddedHttpServer
methods which previously used the
routeToAdminServer
parameter have been changed to use a RouteHint
instead for added
flexibility in controlling where a test request is sent. 4653992cFeatureTestMixin.printStats
and setting it to true. 28eecabecom.twitter.inject.utils.RetryPolicyUtils
,
com.twitter.inject.thrift.modules.FilteredThriftClientModule
, and
com.twitter.inject.thrift.filters.ThriftClientFilterChain
methods to take
com.twitter.util.Duration
instead of org.joda.time.Duration
. c295efb0org.apache.commons-fileupload
from version
1.3.1 to version 1.4. This closes #PR-497. d5d32737com.google.common.net.MediaType
with String.
You can migrate by calling MediaType#toString
everywhere you passed a MediaType
before. 826fabb2http
scope to shutdown.time
flag, making it http.shutdown.time
.
2abb46f8DefaultExceptionMapper
. Extend
c.t.finatra.http.exceptions.ExceptionMapper[Throwable]
directly instead. cd2d5be3com.twitter.app.App#failfastOnFlagsNotParsed
up from
c.t.inject.server.TwitterServer
to com.twitter.inject.app.App
such that all Finatra-based
applications default to this behavior. feb887e0c.t.app.Flags
instance to match the semantics of directly calling c.t.app.Flags#add
. Prefer AtomicBoolean
instances over where we currently use mutable Boolean instances in c.t.inject.app.App
, c.t.inject.app.TestInjector
,
and c.t.inject.server.EmbeddedTwitterServer
. 2dfd33b5c.t.finatra.http.RouteHint
was missing from the test-jar sources and has
been added. 7945d128DateTime
deserialization. abb17d5aEmbeddedHttpServer
’s httpGetJson
method now properly passes
all parameters through to the underlying client call. 068cd440(ReqRep)ServicePerEndpoint
now provide a proper filtered
method by default. e46b2785DuplicateFlagDefinitions
lint rule which is violated when multiple Flags
with the same
name are added to the underlying com.twitter.app.App#flag com.twitter.app.Flags instance. fe231c9aFlag
names. Currently, we print a warning to
stderr but do not track the duplicated Flag
names. Tracking them allows us to inspect and
warn over the entire set. 4875552e


algorithm_a demo
Say hello browser
Say hello javascript
Onmouse demo
1st input:
2nd input:
key data here


{% load static i18n %} {% get_current_language as LANGUAGE_CODE %} {% get_available_languages as LANGUAGES %} {% get_language_info_list for LANGUAGES as languages %}


Diriyah Formula E: Sims beats Mercedes duo to pole for season opener
by Alex KalinauckasBMW Andretti's Alexander Sims claimed pole for the 2019-20 Formula E season-opening Diriyah E-Prix ahead of ex-Formula 1 driver Stoffel Vandoorne, as last year's championship frontrunners qualified down the order.
Ailing from the third qualifying group, Sims made it through to the superpole session, before a rapid and planted flying lap in the final segment gave him a 1m14.563s and three points for the first pole of the season - and the second of his FE career.
Sims was investigated for a clash with Jean-Eric Vergne at the end of FP2, but the stewards took no further action as they assessed the incident as a "non-punishing race situation", per an FIA bulletin.
Vandoorne benefited from a strong final sector to claim a front-row start for Mercedes' first FE race as a works entrant, while his team-mate - newly crowned 2019 Formula 2 champion Nyck de Vries - will start third.
De Vries had been up on Sims's lap through the first two sectors, but a slow end to the lap cost him four tenths and a shot at pole.
Edoardo Mortara backed-up the efforts of the works Mercedes drivers with fourth for the manufacturer's customer squad Venturi Racing, qualifying ahead of Sam Bird, who topped the group running and picked up the first point of the season as a result.
But Bird could not follow up on that effort in superpole as he made a mistake at the long Turn 4 right-hander by getting off-line and sliding close to the wall on the extremely low-grip surface, losing 0.8 seconds to Sims in the first sector.
He stayed on it - setting the fastest sector three of superpole - to take fifth ahead of Mahindra Racing's Jerome D'Ambrosio.
Andre Lotterer was the top runner not to make it through to superpole and will start his first FE race for Porsche seventh, qualifying ahead of Oliver Rowland, who survived a brush with the wall going through the rapid and undulating second sector on his group two lap.
Maximilian Guenther and Oliver Turvey both from group three - will round out the top 10 on the grid for Friday's race.
Reigning champion Jean-Eric Vergne will start 11th after he topped a frantic group one ahead of Robin Frijns, who qualified 12th.
The top six drivers from last year's championship left it very late to head out in a bid to find better track conditions on the ever-improving circuit.
Antonio Felix da Costa ended up leading the pack, but he went to the full 250kW after one out-lap from the pits and ended up well adrift of Vergne, later reporting he had a brake issue, and will start 21st in his first race for DS Techeetah.
Lucas di Grassi headed the queue of group one runners taking a second warm-lap - they all had to overtake da Costa in the first sector on their 250kW laps - and he ended up with the second-slowest time in that segment, and down in 19th overall.
Vergne and Frijns topped the group from the middle of the pack, which was running virtually nose to tail by the chequered flag, as Sebastien Buemi and Mitch Evans followed them in the group one standings.
Buemi was eventually shuffled back to 14th and Evans 16th.
Brendon Hartley will make his series debut from 18th after struggling massively for grip throughout his group-four lap, after he missed much of practice following a crash in FP1 and braking issues in FP2.
Neel Jani will start his first FE race for Porsche from 20th after he was held up by yellow flags brought out for separate crashes for James Calado and Nico Muller at the end of group four.
Calado hit the wall going through the ever-tightening Turn 16 right-hander then slid into the barrier at the exit of Turn 17, which follows immediately and leads on the track's main straight.
Seconds behind Calado's pair of crashes, Muller had exactly the same sequence - losing the rear in Turn 16 and striking the wall before sliding to a halt at the Turn 17 outside barrier.
Muller and Calado were later disqualified from the qualifying result as Dragon and Jaguar asked to remove them from parc ferme to make repairs to their cars - but they will line-up in the same order they qualified based on their warm-up lap times in 23rd and 24th.
Starting grid
| Pos | Driver | Team | Car | Time | Gap |
|---|---|---|---|---|---|
| 1 | Alexander Sims | BMW | BMW | 1m14.563s | - |
| 2 | Stoffel Vandoorne | Mercedes | Mercedes | 1m14.839s | 0.276s |
| 3 | Nyck de Vries | Mercedes | Mercedes | 1m14.929s | 0.366s |
| 4 | Edoardo Mortara | Venturi | Mercedes | 1m15.131s | 0.568s |
| 5 | Sam Bird | Virgin | Audi | 1m15.350s | 0.787s |
| 6 | Jerome d'Ambrosio | Mahindra | Mahindra | 1m15.539s | 0.976s |
| 7 | Andre Lotterer | Porsche | Porsche | 1m15.518s | 0.955s |
| 8 | Oliver Rowland | e.dams | Nissan | 1m15.653s | 1.090s |
| 9 | Max Guenther | BMW | BMW | 1m15.680s | 1.117s |
| 10 | Oliver Turvey | NIO | NIO | 1m16.018s | 1.455s |
| 11 | Jean-Eric Vergne | DS Techeetah | DS | 1m16.129s | 1.566s |
| 12 | Robin Frijns | Virgin | Audi | 1m16.200s | 1.637s |
| 13 | Pascal Wehrlein | Mahindra | Mahindra | 1m16.200s | 1.637s |
| 14 | Sebastien Buemi | e.dams | Nissan | 1m16.243s | 1.680s |
| 15 | Daniel Abt | Audi | Audi | 1m16.264s | 1.701s |
| 16 | Mitch Evans | Jaguar | Jaguar | 1m16.532s | 1.969s |
| 17 | Felipe Massa | Venturi | Mercedes | 1m16.583s | 2.020s |
| 18 | Brendon Hartley | Dragon | Penske | 1m17.074s | 2.511s |
| 19 | Lucas di Grassi | Audi | Audi | 1m17.213s | 2.650s |
| 20 | Neel Jani | Porsche | Porsche | 1m17.745s | 3.182s |
| 21 | Antonio Felix da Costa | DS Techeetah | DS | 1m18.613s | 4.050s |
| 22 | Ma Qing Hua | NIO | NIO | 1m21.701s | 7.138s |
| 23 | Nico Muller | Dragon | Penske | 1m23.017s | 8.454s |
| 24 | James Calado | Jaguar | Jaguar | 1m23.792s | 9.229s |


An S4 update of the 'mefa' package using sparse matrices for enhanced efficiency. Sparse array-like objects are supported via lists of sparse matrices.
| Version: | 0.3-5 |
| Depends: | R (≥ 3.2.0), methods, Matrix, pbapply |
| Suggests: | mefa |
| Published: | 2018-03-25 |
| Author: | Peter Solymos |
| Maintainer: | Peter Solymos <solymos at ualberta.ca> |
| BugReports: | https://github.com/psolymos/mefa4/issues |
| License: | GPL-2 |
| URL: | https://github.com/psolymos/mefa4 |
| NeedsCompilation: | no |
| Citation: | mefa4 citation info |
| CRAN checks: | mefa4 results |
| Reference manual: | mefa4.pdf |
| Package source: | mefa4_0.3-5.tar.gz |
| Windows binaries: | r-devel: mefa4_0.3-5.zip, r-release: mefa4_0.3-5.zip, r-oldrel: mefa4_0.3-5.zip |
| OS X binaries: | r-release: mefa4_0.3-5.tgz, r-oldrel: mefa4_0.3-5.tgz |
| Old sources: | mefa4 archive |
| Reverse imports: | opticut |
| Reverse suggests: | mefa |
Please use the canonical form https://CRAN.R-project.org/package=mefa4 to link to this page.


Go back to home page
Choose which category of test the student attended.
Practice Test
Assessment Test
Watched learning videos.
MCQ
Fill-up
C programming
c++ programming
Java programming
Python programming
Enter


Using the CodeSniffer tool to test the PHP code at TMW
Articles
How we focused on our users for the latest version of Kickoff
Making traditional cross-reference tables available in an accessible manner
A brief introduction into getting a an Arduino listening over a USB connection with a PHP script on the other end
The final instalment of a two-part tutorial on creating a web-app that will load and display weather data.
Add tracking events more easily with our new library
The first of a two-part tutorial on creating a web-app that will load and display weather data.
 Time to hit the big bad world. It’s not always a walk in the park.
A new version of the lightweight front-end framework has been released.
You should ask the right questions about outsourcing


| # | Vehicle | Destination |
|---|
Welcome to LPS visualiser
> Start visualising your autonomous vehicle program by entering the lps program or by loading the .lps
file
> Define the vehicle in your lps program or via +
or -
button
> Watch the behaviour of the vehicle by clicking the Animate
button
> Clear the program via Clear
button
> Stop the running program via Stop
button
This project is under MIT license, For further instruction and traffic regulations, please refer to the About page


From 'Jeopardy' to poker to reading comprehension, robots have managed to beat humans in all of these contests in the past decade
by Aaron Holmes- Thanks to leaps and bounds in the field of artificial intelligence in the past decade, robots are increasingly beating humans at our own games.
- AI-powered programs have proven their prowess at competitive games and academic tests alike throughout the past 10 years.
- Many advances in AI can’t be quantified with competitions or challenges, but robots’ victories at games ranging from Jeopardy to Dota show how far AI has come.
- Visit Business Insider’s homepage for more stories.
When IBM’s Deep Blue chess machine defeated world chess champion Garry Kasparov in 1997, the world responded with surprise and angst at how far computers had come: “Be Afraid,” read a Weekly Standard headline reacting to the news.
Artificial intelligence has since made advancements that were unthinkable just 20 years ago – in the past decade alone, robots have achieved dominance over humans in games far more complex than chess.
While most of those advances can’t be quantified with milestones like chess victories, programmers have continued the tradition of building machines designed to outsmart humans at our own games.
Here’s a comprehensive list of the competitions, games, and challenges that robots beat humans at in the past decade.
2011: IBM’s Watson beats two former champions to win Jeopardy
Watson defeated 74-time Jeopardy winner Ken Jennings and 20-time winner Brad Rutter after a three-day contest, showcasing the strength of IBM’s supercomputer.
2014: Facebook’s DeepFace facial recognition algorithm achieves an accuracy rate of 97%, rivaling the rate of humans
Facial recognition technology has only become more sophisticated since Facebook achieved that milestone in 2014. However, some research has questioned whether human facial recognition can accurately be compared to AI facial recognition.
2015: Google DeepMind’s AlphaGo defeats Go champions in Korea and Europe
In the years following AlphaGo’s 2015 victories, it went on to defeat several other international champions, and by 2017 it was able to win 60 rounds of Go back-to-back.
2016: Microsoft speech recognition AI can transcribe audio with fewer mistakes than humans
Microsoft said that its software achieved an error rate of 0.4%, compared to the human error rate of 5.9%.
2017: Libratus, an AI bot, defeats four of the world’s leading poker players in a 20-day tournament
Unlike Chess or Go, poker is an imperfect information game, meaning players have to guess each others’ hands – making Libratus’ victory all the more impressive.
2017: An OpenAI bot defeats a human esports player at the multiplayer online battle arena game Dota 2
The bot, developed by OpenAI, has repeatedly beaten the world’s top Dota 2 players.
2017: An AI system developed by researchers at Northwestern is able to beat 75 per cent of Americans at a visual intelligence test
The program can solve logic games simply by looking at them – while most vision-based AI at the time focused on recognition, this one takes an extra step with visual reasoning.
2018: Alibaba’s AI outscores humans in a Stanford University reading comprehension test
After answering 10,000 reading comprehension questions, Alibaba’s AI scored 82.44, just above the 82.304 score achieved by humans.


In addition to the highlights property, you can also control the highlighting after the pathway is rendered.


| Exported Interfaces - Details |
XFrame
- Description
- allows the component to be loaded and accessed
within the frame; it is the main connection to the
environment of the component.
|
|
XDispatchProvider
- Description
- provides access to dispatchers for the frame.
What kind of URLs a frame accepts in the calls to XDispatchProvider::queryDispatch(),
and how the returned dispatcher handles dispatches is completely implementation dependent
(though of course the restrictions of XDispatchProvider must be met).
Frame implementations may (optionally) support special targets in the call to
XDispatchProvider::queryDispatch().
Such special targets are passed as target frame name. They may, in addition,
require special frame search flags (see FrameSearchFlag), or,
in opposite, limit the set of allowed flags.
Common special targets include:
- _blank
is used to create a new frame when dispatching the URL.
- _default
is used to recycle empty or create a new frame when dispatching the URL.
- _self
forces the frame to dispatch the URL into itself. ("" means the same)
- _parent
dispatches the URL into the parent frame.
- _top
dispatches the URL into the top level frame, the frame where this is invoked belongs to.
- See also
- XDispatch, XFrame::findFrame()
|
|
XDispatchInformationProvider
- Usage Restrictions
- optional
- Description
- provides information about supported commands
- Since
- OOo 2.0
|
|
XDispatchProviderInterception
- Description
- supports interception mechanism for dispatched URLs
Registered objects can intercept, supress or deroute dispatched URLs.
If they support another interface too (XInterceptorInfo)
it's possible to perform it by directly calling of right interceptor without
using list of all registered ones.
|
|
XFramesSupplier
- Description
- provides access to sub frames within this frame
|
|
::com::sun::star::task::XStatusIndicatorFactory
- Usage Restrictions
- optional
- Description
- supplies access to ::com::sun::star::task::XStatusIndicator objects
for the component within the frame to show progresses
|
|
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.