Function: SB-EXT:SAVE-LISP-AND-DIE¶
Save a “core image”, i.e. enough information to restart a Lisp process later in the same state, in the file of the specified name. Only global state is preserved: the stack is unwound in the process.
The following &KEY arguments are defined:
:TOPLEVEL The function to run when the created core file is resumed. The default function handles command line toplevel option processing and runs the top level read-eval-print loop. This function returning is equivalent to (SB-EXT:EXIT :CODE 0) being called.
TOPLEVEL functions should always provide an ABORT restart: otherwise code they call will run without one.
:EXECUTABLE If true, arrange to combine the SBCL runtime and the core image to create a standalone executable. If false (the default), the core image will not be executable on its own. Executable images always behave as if they were passed the –noinform runtime option.
:SAVE-RUNTIME-OPTIONS If true, values of runtime options –dynamic-space-size and –control-stack-size that were used to start SBCL are stored in the standalone executable, and restored when the executable is run. This also inhibits normal runtime option processing, causing all command line arguments to be passed to the toplevel. Meaningless if :EXECUTABLE is NIL.
:PURIFY If true (the default on cheneygc), do a purifying GC which moves all dynamically allocated objects into static space. This takes somewhat longer than the normal GC which is otherwise done, but it’s only done once, and subsequent GC’s will be done less often and will take less time in the resulting core file. See the PURIFY function.
:ROOT-STRUCTURES This should be a list of the main entry points in any newly loaded systems. This need not be supplied, but locality and/or GC performance may be better if they are. This has two different but related meanings: If :PURIFY is true - and only for cheneygc - the root structures are those which anchor the set of objects moved into static space. On gencgc - and only on platforms supporting immobile code - these are the functions and/or function-names which commence a depth-first scan of code when reordering based on the statically observable call chain. The complete set of reachable objects is not affected per se. This argument is meaningless if neither enabling precondition holds.
:ENVIRONMENT-NAME This has no purpose; it is accepted only for legacy compatibility.
:COMPRESSION This is only meaningful if the runtime was built with the :SB-CORE-COMPRESSION feature enabled. If NIL (the default), saves to uncompressed core files. If :SB-CORE-COMPRESSION was enabled at build-time, the argument may also be an integer from -1 to 9, corresponding to zlib compression levels, or T (which is equivalent to the default compression level, -1).
:APPLICATION-TYPE Present only on Windows and is meaningful only with :EXECUTABLE T. Specifies the subsystem of the executable, :CONSOLE or :GUI. The notable difference is that :GUI doesn’t automatically create a console window. The default is :CONSOLE.
The save/load process changes the values of some global variables:
STANDARD-OUTPUT, DEBUG-IO, etc. Everything related to open streams is necessarily changed, since the OS won’t let us preserve a stream across save and load.
DEFAULT-PATHNAME-DEFAULTS This is reinitialized to reflect the working directory where the saved core is loaded.
SAVE-LISP-AND-DIE interacts with SB-ALIEN:LOAD-SHARED-OBJECT: see its documentation for details.
On threaded platforms only a single thread may remain running after SB-EXT:SAVE-HOOKS have run. Applications using multiple threads can be SAVE-LISP-AND-DIE friendly by registering a save-hook that quits any additional threads, and an init-hook that restarts them.
This implementation is not as polished and painless as you might like:
- It corrupts the current Lisp image enough that the current process needs to be killed afterwards. This can be worked around by forking another process that saves the core.
- There is absolutely no binary compatibility of core images between different runtime support programs. Even runtimes built from the same sources at different times are treated as incompatible for this purpose. This isn’t because we like it this way, but just because there don’t seem to be good quick fixes for either limitation and no one has been sufficiently motivated to do lengthy fixes.
Lambda list¶
(sb-impl::core-file-name &key sb-impl::toplevel sb-impl::executable
sb-impl::save-runtime-options sb-ext:purify sb-impl::root-structures
sb-impl::environment-name sb-impl::compression)


The topic describes how to customize a WP85 UART port so it can be configured as an application serial port.
The syntax is:
Where
a
is the service typeb
is the UART number, either 1
or 2
.Here's a code sample setting 17
for the service type and 1
for the UART number:
Reboot your target after running the command.
Run AT!MAPUART
? to check the config settings.
The current AT command spec defines the service as:
Service to map to UART: 0: UART disabled 1: AT Command service 2: Diagnostic Message service 3: Reserved 4: NMEA service 5-15: Reserved 16: Linux Console 17: Customer Linux application
Copyright (C) Sierra Wireless Inc. Use of this work is subject to license.


Today we will ride almost from sea to sea. We will leave the beautiful town of Zichron Yaakov and begin riding eastwards, until we reach the Kinneret (the Sea of Galilee). We start with a descent, riding towards road no. 70, which will soon change into a climb to the Elyakim Junction. Here we will turn right for a 10 mile ride through the Ramot Menashe Park, known by some as the “Tuscany of the Middle East". In 2011 UNESCO recognized the 20,000 acres of the Ramot Menashe district as a biosphere for reservation, in order to maintain the natural and rural characteristics of this area.
From Kibbutz Mishmar Ha'Emek we turn right again towards Megiddo Junction, passing the famous archeological site of Tel Megiddo. Did you know that the word "Armageddon", described in the New Testament as the apocalypse derives from the Hebrew "Har Megiddo" meaning "Mount of Megiddo"…?
At the Megiddo Junction we will turn left on road 65, and ride on the well-known "Ruler Road", crossing the fertile fields of the Jezreel Valley and ride through the town of Afula, the Capital of the Valley. We will enjoy the amazing view of Mt. Tabor rising 1300 ft. above the valley floor with the Church of the Transfiguration lying at the top of the mountain.
We will continue to Golani Junction. The museum commemorating the soldiers of the Golani Infantry Brigade is situated here. From the Junction we will head down the 1,000 ft. steep decline towards Tiberias, enjoying the magnificent scenery of the Sea of Galilee and the Golan Heights on the other side of the lake.


|
JavaTM 2 Platform Standard Ed. 5.0 |
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object java.awt.dnd.DropTarget
public class DropTarget
The DropTarget
is associated
with a Component
when that Component
wishes
to accept drops during Drag and Drop operations.
Each
DropTarget
is associated with a FlavorMap
.
The default FlavorMap
hereafter designates the
FlavorMap
returned by SystemFlavorMap.getDefaultFlavorMap()
.
| Nested Class Summary | |
|---|---|
protected static class |
DropTarget.DropTargetAutoScroller
this protected nested class implements autoscrolling |
| Constructor Summary | |
|---|---|
DropTarget()
Creates a DropTarget . |
|
DropTarget(Component c,
DropTargetListener dtl)
Creates a DropTarget given the Component
to associate itself with, and the DropTargetListener
to handle event processing. |
|
DropTarget(Component c,
int ops,
DropTargetListener dtl)
Creates a DropTarget given the Component
to associate itself with, an int representing
the default acceptable action(s) to support, and a
DropTargetListener to handle event processing. |
|
DropTarget(Component c,
int ops,
DropTargetListener dtl,
boolean act)
Creates a DropTarget given the Component
to associate itself with, an int representing
the default acceptable action(s)
to support, a DropTargetListener
to handle event processing, and a boolean indicating
if the DropTarget is currently accepting drops. |
|
DropTarget(Component c,
int ops,
DropTargetListener dtl,
boolean act,
FlavorMap fm)
Creates a new DropTarget given the Component
to associate itself with, an int representing
the default acceptable action(s) to
support, a DropTargetListener
to handle event processing, a boolean indicating
if the DropTarget is currently accepting drops, and
a FlavorMap to use (or null for the default FlavorMap ). |
| Method Summary | |
|---|---|
void |
addDropTargetListener(DropTargetListener dtl)
Adds a new DropTargetListener (UNICAST SOURCE). |
void |
addNotify(java.awt.peer.ComponentPeer peer)
Notify the DropTarget that it has been associated with a Component This method is usually called from java.awt.Component.addNotify() of the Component associated with this DropTarget to notify the DropTarget that a ComponentPeer has been associated with that Component. |
protected void |
clearAutoscroll()
clear autoscrolling |
protected DropTarget.DropTargetAutoScroller |
createDropTargetAutoScroller(Component c,
Point p)
create an embedded autoscroller |
protected DropTargetContext |
createDropTargetContext()
Creates the DropTargetContext associated with this DropTarget. |
void |
dragEnter(DropTargetDragEvent dtde)
Calls dragEnter on the registered
DropTargetListener and passes it
the specified DropTargetDragEvent . |
void |
dragExit(DropTargetEvent dte)
Calls dragExit on the registered
DropTargetListener and passes it
the specified DropTargetEvent . |
void |
dragOver(DropTargetDragEvent dtde)
Calls dragOver on the registered
DropTargetListener and passes it
the specified DropTargetDragEvent . |
void |
drop(DropTargetDropEvent dtde)
Calls drop on the registered
DropTargetListener and passes it
the specified DropTargetDropEvent
if this DropTarget is active. |
void |
dropActionChanged(DropTargetDragEvent dtde)
Calls dropActionChanged on the registered
DropTargetListener and passes it
the specified DropTargetDragEvent . |
Component |
getComponent()
Gets the Component associated
with this DropTarget . |
int |
getDefaultActions()
Gets an int representing the
current action(s) supported by this DropTarget . |
DropTargetContext |
getDropTargetContext()
Gets the DropTargetContext associated
with this DropTarget . |
FlavorMap |
getFlavorMap()
Gets the FlavorMap
associated with this DropTarget . |
protected void |
initializeAutoscrolling(Point p)
initialize autoscrolling |
boolean |
isActive()
Reports whether or not this DropTarget
is currently active (ready to accept drops). |
void |
removeDropTargetListener(DropTargetListener dtl)
Removes the current DropTargetListener (UNICAST SOURCE). |
void |
removeNotify(java.awt.peer.ComponentPeer peer)
Notify the DropTarget that it has been disassociated from a Component This method is usually called from java.awt.Component.removeNotify() of the Component associated with this DropTarget to notify the DropTarget that a ComponentPeer has been disassociated with that Component. |
void |
setActive(boolean isActive)
Sets the DropTarget active if true ,
inactive if false . |
void |
setComponent(Component c)
Note: this interface is required to permit the safe association of a DropTarget with a Component in one of two ways, either: component.setDropTarget(droptarget);
or droptarget.setComponent(component); |
void |
setDefaultActions(int ops)
Sets the default acceptable actions for this DropTarget |
void |
setFlavorMap(FlavorMap fm)
Sets the FlavorMap associated
with this DropTarget . |
protected void |
updateAutoscroll(Point dragCursorLocn)
update autoscrolling with current cursor locn |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Constructor Detail |
|---|
public DropTarget(Component c, int ops, DropTargetListener dtl, boolean act, FlavorMap fm) throws HeadlessException
Component
to associate itself with, an int
representing
the default acceptable action(s) to
support, a DropTargetListener
to handle event processing, a boolean
indicating
if the DropTarget
is currently accepting drops, and
a FlavorMap
to use (or null for the default FlavorMap
).
The Component will receive drops only if it is enabled.
c
- The Component
with which this DropTarget
is associatedops
- The default acceptable actions for this DropTarget
dtl
- The DropTargetListener
for this DropTarget
act
- Is the DropTarget
accepting drops.fm
- The FlavorMap
to use, or null for the default FlavorMap
HeadlessException
- if GraphicsEnvironment.isHeadless()
returns trueGraphicsEnvironment.isHeadless()
public DropTarget(Component c, int ops, DropTargetListener dtl, boolean act) throws HeadlessException
DropTarget
given the Component
to associate itself with, an int
representing
the default acceptable action(s)
to support, a DropTargetListener
to handle event processing, and a boolean
indicating
if the DropTarget
is currently accepting drops.
The Component will receive drops only if it is enabled.
c
- The Component
with which this DropTarget
is associatedops
- The default acceptable actions for this DropTarget
dtl
- The DropTargetListener
for this DropTarget
act
- Is the DropTarget
accepting drops.
HeadlessException
- if GraphicsEnvironment.isHeadless()
returns trueGraphicsEnvironment.isHeadless()
public DropTarget() throws HeadlessException
DropTarget
.
HeadlessException
- if GraphicsEnvironment.isHeadless()
returns trueGraphicsEnvironment.isHeadless()
public DropTarget(Component c, DropTargetListener dtl) throws HeadlessException
DropTarget
given the Component
to associate itself with, and the DropTargetListener
to handle event processing.
The Component will receive drops only if it is enabled.
c
- The Component
with which this DropTarget
is associateddtl
- The DropTargetListener
for this DropTarget
HeadlessException
- if GraphicsEnvironment.isHeadless()
returns trueGraphicsEnvironment.isHeadless()
public DropTarget(Component c, int ops, DropTargetListener dtl) throws HeadlessException
DropTarget
given the Component
to associate itself with, an int
representing
the default acceptable action(s) to support, and a
DropTargetListener
to handle event processing.
The Component will receive drops only if it is enabled.
c
- The Component
with which this DropTarget
is associatedops
- The default acceptable actions for this DropTarget
dtl
- The DropTargetListener
for this DropTarget
HeadlessException
- if GraphicsEnvironment.isHeadless()
returns trueGraphicsEnvironment.isHeadless()
| Method Detail |
|---|
public void setComponent(Component c)
component.setDropTarget(droptarget);
or droptarget.setComponent(component);
The Component will receive drops only if it is enabled.
c
- The new Component
this DropTarget
is to be associated with.public Component getComponent()
Component
associated
with this DropTarget
.
public void setDefaultActions(int ops)
DropTarget
ops
- the default actions
DnDConstants
public int getDefaultActions()
int
representing the
current action(s) supported by this DropTarget
.
public void setActive(boolean isActive)
true
,
inactive if false
.
isActive
- sets the DropTarget
(in)active.public boolean isActive()
DropTarget
is currently active (ready to accept drops).
true
if active, false
if notpublic void addDropTargetListener(DropTargetListener dtl) throws TooManyListenersException
DropTargetListener
(UNICAST SOURCE).
dtl
- The new DropTargetListener
TooManyListenersException
- if a
DropTargetListener
is already added to this
DropTarget
.
TooManyListenersException
public void removeDropTargetListener(DropTargetListener dtl)
DropTargetListener
(UNICAST SOURCE).
dtl
- the DropTargetListener to deregister.public void dragEnter(DropTargetDragEvent dtde)
dragEnter
on the registered
DropTargetListener
and passes it
the specified DropTargetDragEvent
.
Has no effect if this DropTarget
is not active.
dragEnter
in interface DropTargetListener
dtde
- the DropTargetDragEvent
NullPointerException
- if this DropTarget
is active and dtde
is null
isActive()
public void dragOver(DropTargetDragEvent dtde)
dragOver
on the registered
DropTargetListener
and passes it
the specified DropTargetDragEvent
.
Has no effect if this DropTarget
is not active.
dragOver
in interface DropTargetListener
dtde
- the DropTargetDragEvent
NullPointerException
- if this DropTarget
is active and dtde
is null
isActive()
public void dropActionChanged(DropTargetDragEvent dtde)
dropActionChanged
on the registered
DropTargetListener
and passes it
the specified DropTargetDragEvent
.
Has no effect if this DropTarget
is not active.
dropActionChanged
in interface DropTargetListener
dtde
- the DropTargetDragEvent
NullPointerException
- if this DropTarget
is active and dtde
is null
isActive()
public void dragExit(DropTargetEvent dte)
dragExit
on the registered
DropTargetListener
and passes it
the specified DropTargetEvent
.
Has no effect if this DropTarget
is not active.
This method itself does not throw any exception for null parameter but for exceptions thrown by the respective method of the listener.
dragExit
in interface DropTargetListener
dte
- the DropTargetEvent
isActive()
public void drop(DropTargetDropEvent dtde)
drop
on the registered
DropTargetListener
and passes it
the specified DropTargetDropEvent
if this DropTarget
is active.
drop
in interface DropTargetListener
dtde
- the DropTargetDropEvent
NullPointerException
- if dtde
is null
and at least one of the following is true: this
DropTarget
is not active, or there is
no a DropTargetListener
registered.isActive()
public FlavorMap getFlavorMap()
FlavorMap
associated with this DropTarget
.
If no FlavorMap
has been set for this
DropTarget
, it is associated with the default
FlavorMap
.
public void setFlavorMap(FlavorMap fm)
FlavorMap
associated
with this DropTarget
.
fm
- the new FlavorMap
, or null to
associate the default FlavorMap with this DropTarget.public void addNotify(java.awt.peer.ComponentPeer peer)
peer
- The Peer of the Component we are associated with!public void removeNotify(java.awt.peer.ComponentPeer peer)
peer
- The Peer of the Component we are being disassociated from!public DropTargetContext getDropTargetContext()
DropTargetContext
associated
with this DropTarget
.
DropTargetContext
associated with this DropTarget
.protected DropTargetContext createDropTargetContext()
protected DropTarget.DropTargetAutoScroller createDropTargetAutoScroller(Component c, Point p)
c
- the Component
p
- the Point
protected void initializeAutoscrolling(Point p)
p
- the Point
protected void updateAutoscroll(Point dragCursorLocn)
dragCursorLocn
- the Point
protected void clearAutoscroll()
|
JavaTM 2 Platform Standard Ed. 5.0 |
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
Copyright © 2004, 2010 Oracle and/or its affiliates. All rights reserved. Use is subject to license terms. Also see the documentation redistribution policy.


Hello,
As part of my Master thesis collaborating with the CIVIS project, I am exposed to other commercial energy monitoring alternatives.
That said I sometimes have difficulties to justify the advantages of Open Energy Monitor to the other people.
One of the main alternatives is Smappee (http://www.smappee.com/), slightly more expensive than the option of using emonTX Shield V2 combined with NanodeRF.
For the extra cost, Smappee comes in a box (not to mention pre-assembled) and has IFTTT integration (I know Emoncms has MQTT).
This is a real problem in my opinion for Open Energy Monitor, unless of course the project is adapted.
Personally I am an advocate of Open Source, as in my opinion through collaboration faster and better results are possible.
Am saying this as a lot of emphasis is placed on visualisations in the development of Emoncms.
Is good, but functionality shouldn't be forgotten.
After all the average non-hobbyist will not spend hours looking at graphs, but needs a simple functional interface, as offered by other alternatives.
Also a lot of emphasis is placed on low-write.
Again not every person is able to setup a Raspberry Pi and in big research projects, sharing and server integration with other projects is key.
Lastly it would be good if algorithms for identifying loads based on current peaks were started as a new direction.
Curious of other opinions ?
Re: Emoncms New Direction
Never realised smappee was that cheap?!
[Duplicate post deleted. Please read "NEW USERS, PLEASE READ - Posts held for moderation"]
Re: Emoncms New Direction
Yes the price of Smappee shocked me too, when discussing with my supervisor.
Is why I opened this post, not as a critic but as awareness so that Open Energy Monitor can hopefully take into account the situation.
Re: Emoncms New Direction
Apologies for the dupe post, I had read the New Users, Please Read....
but if nothing comes up saying waiting for moderation, or you are in a queue, your message is important to us, then you will of course get multiple posts.
Re: Emoncms New Direction
"if nothing comes up..."
But it does. You didn't see it.
Re: Emoncms New Direction
Hapless,
It looks like this:
Re: Emoncms New Direction
I'm not sure that message sticks around once the page is reloaded though.
Re: Emoncms New Direction
obviously I didn't see the warning, otherwise I wouldn't have posted again!
OK, time to move on, back to Christophe's original point...
Smappee UK price for single phase, solar equipped installation is £179 inc. vat and carriage.
Equivalent OEM is £183.73 inc. vat and carriage
The whole smappee package looks very polished and complete - not tried it but from folk who have they are pleased with how it tracks individual loads/appliances, but again there are issues with smaller loads?
Re: Emoncms New Direction
Smappee is a self-learning system that improves accuracy in identifying loads over time. Indeed some glitches like iron being mistaken with stove. It basically gives your overall consumption situation as well as a breakdown of power and duration per device.
However as it is a commercial system, the code on Smappee itself cannot be hacked, only export of results from Smappee server via API. Hence the beauty of Open Energy Monitor, as you can decide what to send to the server as well as the interval.
Open Energy Monitor lately is just giving me unnecessary work, in having to identify bugs in the code and fixing them each time. My point being that if new features will be added to the code, at least test them properly and do not leave half un-functional functions in the code, just put them in a separate file or Github fork so that it is clear that those new features are faulty (I am referring to latest Emoncms release v8.5).
Just to say that after my thesis, I will create a new fork with all the complaints I have mentioned fixed. And overtime new up-to-date in comparison with other alternatives functions implemented.
--------
Lastly just a suggestion about the post moderation issue: why not give the moderation power to the topic opening user as well, to give less work to site administrators ?
Re: Emoncms New Direction
Yes, true, very nicely done.
But as far as I can see from the description it only measures phase currents, not voltage. If that is true it cannot measure consumption very precisely. Correct me please if I am wrong.
Jörg.
Re: Emoncms New Direction
But as far as I can see from the description it only measures phase currents, not voltage.
The installation section of the manual doesn't show a mains connected VT, only CTs.
So, unless the power supply for the Ethernet gateway is also the VT, (which may, or may not, be a bad thing) I'd say Jörg is correct.
http://cdn.smappee.com/media/wysiwyg/Manuals/Smappee_IM_UK_Installation_...
http://cdn.smappee.com/media/wysiwyg/Manuals/Smappee_IM_US_Installation_...
Re: Emoncms New Direction
Smappee gets its voltage signal from the "wall-wart", not unlike the latest emonTX stuff. From the two installations I've seen it can measure real power impressively accurately, but the appliance recognition stuff is pretty hit and miss. Both the owners I know have stopped using that feature, and just use it as a very accurate whole-house power monitor. I suspect in multi-phase installations it must be doing some sort of guess about the other phases (again like some OEM 3 phases sketches). And in the US it can only see one leg, so must assume the other is identical in amplitude.
I suspect the appliance recognition will only ever be as good as the amount of effort you're prepared to put it, and it takes an enormous amount of effort so that's why my two buddies have given up on that part. When you look at a complex load like a dishwasher running for 50 mins. you see why it's problematic. I think Smappee notes the current signature (i.e. the fundamental and quite a few harmonics) of every event it sees. So every relay, solenoid, and pump in your dishwasher all appear as unique unknown appliances that you need to identify and group together under dishwasher.
One of my buddies gave up early, still will hundreds of unidentified "appliances" in his house, while the other was a lot more determined. But for his efforts, he's now told his dishwasher has come on when he turns his oven on. I suspect it will improve over time, especially if they can pull off a crowd sourced database of signatures that new users get for free.... but they'll need more determined customers than the two I know.
Re: Emoncms New Direction
I had wondered how this would be able to recognize all the many different cycles that say, a washing machine could present and cater for outside influence like changes in time to heat water due to initial water temp variations by season etc and densely filled verses light clothing etc monitoring at a component level accommodates that but what about wear and tear or replacement parts throwing a spanner in the works? I'm not sure I would have the patience, excellent concept I hope it progresses but it is without a doubt quite a different product to OEM.
Paul
Re: Emoncms New Direction
Ok, that is a good information. I could not extract this from their web page.
Do you know how the appliance recognition works in practical terms? Does it always present you a number of 'unknown' loads where you have to tell it which load is which or does it make an 'educated guess' itself?
Jörg.
Re: Emoncms New Direction
It just assigns them sequential numbers as it finds them, and it's up to you to edit "Appliance 85" into "Garage Door" or whatever, when (if?) you eventually work it out. It's been a good 9 months since I've played with one, so there's a chance it's improved since then. I vaguely recall it asked you for a Make/Model of appliances, which made me think they were crowd sourcing a database of signatures. So maybe they can now (or one day) say... "It looks like you have an LG Fridge Model xxx, confirm?".
Oh, and it has a training mode too, where you can say "Listen up, I'm about to turn the TV on". My buddy tried that with his circulation pump over and over, and it refused to see anything... although total power went up by the correct amount when he turned it on.
Re: Emoncms New Direction
Nice to see the debate about the difference between OEM and Smappee, as well as the appliance recognition feature of Smappee.
So as was mentioned Smappee is both powered and measures voltage from the "wall-wart". This is clearly an advantage over emonTX where you need 2 voltage supply inputs if taking voltage measurements. And doing some research shows that powering the Nanode or Arduino base from the shield is not a problem. That would be one major design improvement.
Secondly appliance recognition is extremely complex, so I do not expect Emoncms to instantly address this feature. However my main point about Emoncms is that the existing functionality can be improved. There are numerous posts about features not behaving as they should and as I can see when myself debugging many half-complete functions. And as mentioned integration with IFTT or working on how to control remote devices is a reasonable objective in the main aim of keeping Open Energy Monitor competitive to other commercial options.
To summarise, one has to see Emoncms and OEM from a non-technical user perspective as well.
Re: Emoncms New Direction
So as was mentioned Smappee is both powered and measures voltage from the "wall-wart".
I'm no expert on EmonTXs, but I'm pretty sure the latest ones use the AC wall-wart for both V sensing and powering the unit.
Secondly appliance recognition is extremely complex, so I do not expect Emoncms to instantly address this feature.
I think Emoncms would be very challenged to do appliance recognition with the data it typically receives today.. i.e. average power used over the last 10 seconds. I suspect you'd need some serious DSP horsepower right down at the pointy end where the signal arrives, to extract all the harmonic info. At least I think that's how smappee does it.
Re: Emoncms New Direction
I'm no expert on EmonTXs, but I'm pretty sure the latest ones use the AC wall-wart for both V sensing and powering the unit.
Yes the emonTX V3 is as you say, but not the Shield V2 nor the new emonPi. But there is a significant cost difference when selecting the emonTX V3 option.
Either way the emonTX V3 would require a Base unit which would be that second "wall-wart". Not to mention the overall larger space requirements. Using the emonTX Shield effectively tackles this problem. Hence my preference for the emonTX Shield V2 combined with Nanode option.
--------
Secondly appliance recognition is extremely complex, so I do not expect Emoncms to instantly address this feature.
I'm looking into this. Ok but if more DSP horsepower was the effective issue, this can surely be addressed with new hardware.
Re: Emoncms New Direction
Another smappee-like product that does appliance signature recognition:
https://www.indiegogo.com/projects/ecoisme-intelligent-energy-monitoring-system#/story
First prototype built from an Arduino!
Re: Emoncms New Direction
Very interesting to read about !
Definitely with a bit of effort, can the same device recognition eventually be integrated into Open Energy Monitor.
Right now after running into problems with 3-phase measurements, similar to http://openenergymonitor.org/emon/node/10419 , I will have to fix the issue before finishing my thesis.
The eventually can I explore the device recognition functionality.
Re: Emoncms New Direction
Do you guys think it is possible to analyze the patterns of each device with 10s interval monitoring or will it require more high resolution analyzing?
Does these units analyse inside the hardware or on the server?
Both units looks interesting, and this is probably the way to go also for the professional market, as this would reduce the amount of sensors needed to be installed. Alot of events kan be sensed from just logging a few points of temperature and energy/power.
//J
Re: Emoncms New Direction
I think 5 second interval would be more appropriate.
Good question about where the analysis is done.
I would go for analysing on the server, as in addition to better hardware you afterall view that resulting data on app/web-interface.
But is important to note that an Arduino alone is not sufficient for these new requirements.
A lot of changes required.
It is just a pity that Open Energy Monitor does not live up to the expectations of Open Source Projects, in the sense that the Open Product is at least as good or better or cheaper than commercial alternative.
As mentioned is some posts above, I really want to fix this gap.
So if you have experience or motivation just message my profile, we can discuss how to tackle the issue.
Re: Emoncms New Direction
@christophe_meyers: just came across that thread and your problems with 3 phases...Just to make it short because it has nothing to do with the subject of this topic:
Since I have enabled CT4 (see http://openenergymonitor.org/emon/node/10419) but don't use it, the system looks fine to me. I share some data here http://emoncms.org/daturach. As a base, I loaded the sketch attached by Robert Wall in my original thread (10419).
Re: Emoncms New Direction
Hello daturach,
See my comment at http://openenergymonitor.org/emon/node/10419
Seems to require rethinking the voltage array procedure.
Please let me know if it works for you, as my code surely requires more testing and feedback.
Thanks
Christophe
Re: Emoncms New Direction
Christophe, both you and I had completely missed the true source of the problem. Use the present sketch on Github, which has been corrected (V3.4 only).
Re: Emoncms New Direction
Robert,
Following the comments at http://openenergymonitor.org/emon/node/10419 , I have indeed used the new V3.4 sketch. However the problem is still there, as the values I get using that sketch still are 'ovf' sometimes. Hence my effort in trying to address the issue.
I'm going to have to take this occasion again, to state that this Open Energy Monitor project is not being well managed. For several reasons:
- when someone publishes new code (like my 3-phase now), at least congratulate their effort. Did you test my code ? No, I suppose. Simply reject whatever you don't appreciate. Open Source is about working together, not a centralized top-down approach as I feel is now (your project is purely commercial to sell your hardware, other Open Source aspects are neglected). You people running the project cannot get all ideas and by encouraging contributions from other people, can the project get better and better. Open Source has some values that really are not being respected.
- by welcoming contributions (not just your ideas) will the project move forward. As right now Open Energy Monitor is by far behind all other commercial options. I know you people running the project don't take this into account, but again for the sake of an Open Source project with motivated contributors, please wake up. Are you aware of https://www.indiegogo.com/projects/ecoisme-intelligent-energy-monitoring-system#/story ? This project is definitely based on Open Energy Monitor (first prototype at least) and by being open-minded, did they turn it into a viable business model. How many more times will Open Energy Monitor need to be let down like this, before new ideas are welcomed to Open Energy Monitor ?
- as already stated above, I will make a new Open Energy Monitor project, where ideas and collaboration is welcomed. That is why Open Source is better than commercial, through encouraged collaboration ! Is a pity that I need to go that extent, but what can I do ?
Christophe
Re: Emoncms New Direction
I work for one of the most popular integration / building controls / energy management companies in the UK and can also say that the key to progression and uptake is integration.
Being able to integrate the openenergymonitor eco system into existing, already established frameworks such as those used in building energy management etc is important.
I have been playing with openenergymonitor now for only a few days and its great. Therefore we just designed a software module for the worlds most advanced integration platform 'Tridium Niagara AX' that leverages the emoncms API in order to get datapoints into the Niagara Framework which then allows for complex control, analytics and general integration into a building management system.
There is a lot to be said for having a good, simple API... And since emoncms already has one, I feel that it is already geared up to become something big.
Open Source is good for everyone!
Re: Emoncms New Direction
I have no intention of taking part in any public discussion about the management of OpenEnergyMonitor.
Re: Emoncms New Direction
I'm going to keep my answer short, as my previous unapproved post went into too much detail.
Basically encouraging user contributions and understanding that Open Energy Monitor must integrate with other available systems is key.
That's all I'll say, others can understand from between the lines what I mean.
Re: Emoncms New Direction
Interesting read and research here: http://csserver.ucd.ie/~aruzzelli/pubs/Secon10_REAR.pdf


The forward solution¶
Contents
Overview¶
This page covers the definitions of different coordinate systems employed in MNE software and FreeSurfer, the details of the computation of the forward solutions, and the associated low-level utilities.
MEG/EEG and MRI coordinate systems¶
The coordinate systems used in MNE software (and FreeSurfer) and their relationships are depicted in MEG/EEG and MRI coordinate systems. Except for the Sensor coordinates, all of the coordinate systems are Cartesian and have the “RAS” (Right-Anterior-Superior) orientation, i.e., the \(x\) axis points to the right, the \(y\) axis to the front, and the \(z\) axis up.
The coordinate transforms present in the fif files in MNE and the FreeSurfer files as well as those set to fixed values are indicated with \(T_x\), where \(x\) identifies the transformation.
The coordinate systems related to MEG/EEG data are:
Head coordinates
This is a coordinate system defined with help of the fiducial landmarks (nasion and the two auricular points). In fif files, EEG electrode locations are given in this coordinate system.  For details, see MEG/EEG and MRI coordinate systems.
Device coordinates
This is a coordinate system tied to the MEG device. The relationship of the Device and Head coordinates is determined during an MEG measurement by feeding current to three to five head-position indicator (HPI) coils and by determining their locations with respect to the MEG sensor array from the magnetic fields they generate.
Sensor coordinates
Each MEG sensor has a local coordinate system defining the orientation and location of the sensor. With help of this coordinate system, the numerical integration data needed for the computation of the magnetic field can be expressed conveniently as discussed in Coil geometry information. The channel information data in the fif files contain the information to specify the coordinate transformation between the coordinates of each sensor and the MEG device coordinates.
The coordinate systems related to MRI data are:
Surface RAS coordinates
The FreeSurfer surface data are expressed in this coordinate system. The origin of this coordinate system is at the center of the conformed FreeSurfer MRI volumes (usually 256 x 256 x 256 isotropic 1-mm3 voxels) and the axes are oriented along the axes of this volume. The BEM surface and the locations of the sources in the source space are usually expressed in this coordinate system in the fif files. In this manual, the Surface RAS coordinates are usually referred to as MRI coordinates unless there is need to specifically discuss the different MRI-related coordinate systems.
RAS coordinates
This coordinate system has axes identical to the Surface RAS coordinates but the location of the origin is different and defined by the original MRI data, i.e. , the origin is in a scanner-dependent location. There is hardly any need to refer to this coordinate system explicitly in the analysis with the MNE software. However, since the Talairach coordinates, discussed below, are defined with respect to RAS coordinates rather than the Surface RAS coordinates, the RAS coordinate system is implicitly involved in the transformation between Surface RAS coordinates and the two Talairach coordinate systems.
MNI Talairach coordinates
The definition of this coordinate system is discussed, e.g. , in http://imaging.mrc-cbu.cam.ac.uk/imaging/MniTalairach. This transformation is determined during the FreeSurfer reconstruction process.
FreeSurfer Talairach coordinates
The problem with the MNI Talairach coordinates is that the linear MNI Talairach transform does matched the brains completely to the Talairach brain.  As a result, the MNI brains are slightly larger (in particular higher, deeper and longer) than the Talairach brain. The differences are larger as you get further from the middle of the brain, towards the outside. The FreeSurfer Talairach coordinates mitigate this problem by additing a an additional transformation, defined separately for negatice and positive MNI Talairach \(z\) coordinates. These two transformations, denoted by \(T_-\) and \(T_+\) in MEG/EEG and MRI coordinate systems, are fixed as discussed in http://imaging.mrc-cbu.cam.ac.uk/imaging/MniTalairach (Approach 2).
The different coordinate systems are related by coordinate transformations depicted in MEG/EEG and MRI coordinate systems. The arrows and coordinate transformation symbols (\(T_x\)) indicate the transformations actually present in the FreeSurfer files. Generally,
where \(x_k\),:math:y_k,and \(z_k\) are the location coordinates in two coordinate systems, \(T_{12}\) is the coordinate transformation from coordinate system “1” to “2”, \(x_0\), \(y_0\),and \(z_0\) is the location of the origin of coordinate system “1” in coordinate system “2”, and \(R_{jk}\) are the elements of the rotation matrix relating the two coordinate systems. The coordinate transformations are present in different files produced by FreeSurfer and MNE as summarized in Coordinate transformations in FreeSurfer and MNE software packages.. The fixed transformations \(T_-\) and \(T_+\) are:
and
Note
This section does not discuss the transformation between the MRI voxel indices and the different MRI coordinates. However, it is important to note that in FreeSurfer, MNE, as well as in Neuromag software an integer voxel coordinate corresponds to the location of the center of a voxel. Detailed information on the FreeSurfer MRI systems can be found at https://surfer.nmr.mgh.harvard.edu/fswiki/CoordinateSystems.
Transformation |
FreeSurfer |
MNE |
\(T_1\) |
Not present |
Measurement data files
Forward solution files (*fwd.fif)
Inverse operator files (*inv.fif)
|
\(T_{s_1}\dots T_{s_n}\) |
Not present |
Channel information in files containing \(T_1\). |
\(T_2\) |
Not present |
MRI description files Separate
coordinate transformation files
saved from mne_analyze
Forward solution files
Inverse operator files
|
\(T_3\) |
mri/*mgz files |
MRI description files saved with mne_make_cor_set if the input is in mgz or mgh format. |
\(T_4\) |
mri/transforms/talairach.xfm |
MRI description files saved with mne_make_cor_set if the input is in mgz or mgh format. |
\(T_-\) |
Hardcoded in software |
MRI description files saved with mne_make_cor_set if the input is in mgz or mgh format. |
\(T_+\) |
Hardcoded in software |
MRI description files saved with mne_make_cor_set if the input is in mgz or mgh format. |
Note
The symbols \(T_x\) are defined in MEG/EEG and MRI coordinate systems. mne_make_cor_set /mne_setup_mri prior to release 2.6 did not include transformations \(T_3\), \(T_4\), \(T_-\), and \(T_+\) in the fif files produced.
The head and device coordinate systems¶
The MEG/EEG head coordinate system employed in the MNE software is a right-handed Cartesian coordinate system. The direction of \(x\) axis is from left to right, that of \(y\) axis to the front, and the \(z\) axis thus points up.
The \(x\) axis of the head coordinate system passes through the two periauricular or preauricular points digitized before acquiring the data with positive direction to the right. The \(y\) axis passes through the nasion and is normal to the \(x\) axis. The \(z\) axis points up according to the right-hand rule and is normal to the \(xy\) plane.
The origin of the MEG device coordinate system is device dependent. Its origin is located approximately at the center of a sphere which fits the occipital section of the MEG helmet best with \(x\) axis axis going from left to right and \(y\) axis pointing front. The \(z\) axis is, again, normal to the \(xy\) plane with positive direction up.
Note
The above definition is identical to that of the Neuromag MEG/EEG (head) coordinate system. However, in 4-D Neuroimaging and CTF MEG systems the head coordinate frame definition is different. The origin of the coordinate system is at the midpoint of the left and right auricular points. The \(x\) axis passes through the nasion and the origin with positive direction to the front. The \(y\) axis is perpendicular to the \(x\) axis on the and lies in the plane defined by the three fiducial landmarks, positive direction from right to left. The \(z\) axis is normal to the plane of the landmarks, pointing up. Note that in this convention the auricular points are not necessarily located on \(y\) coordinate axis. The file conversion utilities take care of these idiosyncrasies and convert all coordinate information to the MNE software head coordinate frame.
Coil geometry information¶
This Section explains the presentation of MEG detection coil geometry information the approximations used for different detection coils in MNE software. Two pieces of information are needed to characterize the detectors:
The location and orientation a local coordinate system for each detector.
A unique identifier, which has an one-to-one correspondence to the geometrical description of the coil.
Note
MNE ships with several coil geometry configurations.
They can be found in mne/data
.
See Plotting sensor layouts of MEG systems
for a comparison between different coil geometries, and
Implemented coil geometries for detailed information regarding
the files describing Neuromag coil geometries.
The sensor coordinate system¶
The sensor coordinate system is completely characterized by the location of its origin and the direction cosines of three orthogonal unit vectors pointing to the directions of the x, y, and z axis. In fact, the unit vectors contain redundant information because the orientation can be uniquely defined with three angles. The measurement fif files list these data in MEG device coordinates. Transformation to the MEG head coordinate frame can be easily accomplished by applying the device-to-head coordinate transformation matrix available in the data files provided that the head-position indicator was used. Optionally, the MNE software forward calculation applies another coordinate transformation to the head-coordinate data to bring the coil locations and orientations to the MRI coordinate system.
If \(r_0\) is a row vector for the origin of the local sensor coordinate system and \(e_x\), \(e_y\), and \(e_z\) are the row vectors for the three orthogonal unit vectors, all given in device coordinates, a location of a point \(r_C\) in sensor coordinates is transformed to device coordinates (\(r_D\)) by
where
Calculation of the magnetic field¶
The forward calculation in the MNE software computes the signals detected by each MEG sensor for three orthogonal dipoles at each source space location. This requires specification of the conductor model, the location and orientation of the dipoles, and the location and orientation of each MEG sensor as well as its coil geometry.
The output of each SQUID sensor is a weighted sum of the magnetic fluxes threading the loops comprising the detection coil. Since the flux threading a coil loop is an integral of the magnetic field component normal to the coil plane, the output of the k th MEG channel, \(b_k\) can be approximated by:
where \(r_{kp}\) are a set of \(N_k\) integration points covering the pickup coil loops of the sensor, \(B(r_{kp})\) is the magnetic field due to the current sources calculated at \(r_{kp}\), \(n_{kp}\) are the coil normal directions at these points, and \(w_{kp}\) are the weights associated to the integration points. This formula essentially presents numerical integration of the magnetic field over the pickup loops of sensor \(k\).
Computing the forward solution¶
Examples on how to compute the forward solution using
mne.make_forward_solution()
can be found
Compute forward solution and Computing the forward solution.
Note
Notice that systems such as CTF and 4D Neuroimaging
data may have been subjected to noise cancellation employing the
data from the reference sensor array. Even though these sensor are
rather far away from the brain sources, this can be taken into account
using mne.io.Raw.apply_gradient_compensation()
.
See Brainstorm CTF phantom dataset tutorial.
EEG forward solution in the sphere model¶
For the computation of the electric potential distribution
on the surface of the head (EEG) it is necessary to define the conductivities
(\(\sigma\)) and radiuses of the spherically
symmetric layers. Different sphere models can be specified with
through mne.make_sphere_model()
.
Here follows the default structure given when calling sphere = mne.make_sphere_model()
Layer |
Relative outer radius |
\(\sigma\) (S/m) |
|---|---|---|
Head |
1.0 |
0.33 |
Skull |
0.97 |
0.04 |
CSF |
0.92 |
1.0 |
Brain |
0.90 |
0.33 |
Although it is not BEM model per se the sphere
structure
describes the head geometry so it can be passed as bem
parameter in
functions such as mne.fit_dipole()
, mne.viz.plot_alignment()
or mne.make_forward_solution()
.
When the sphere model is employed to compute the forward model using
mne.make_forward_solution()
, the computation of the
EEG solution can be substantially accelerated by using approximation
methods described by Mosher, Zhang, and Berg, see Forward modeling (Mosher et
al. and references therein). In such scenario, MNE approximates
the solution with three dipoles in a homogeneous sphere whose locations
and amplitudes are determined by minimizing the cost function:
where \(r_1,\dotsc,r_m\) and \(\mu_1,\dotsc,\mu_m\) are the locations and amplitudes of the approximating dipoles and \(V_{true}\) and \(V_{approx}\) are the potential distributions given by the true and approximative formulas, respectively. It can be shown that this integral can be expressed in closed form using an expansion of the potentials in spherical harmonics. The formula is evaluated for the most superficial dipoles, i.e., those lying just inside the inner skull surface.
Averaging forward solutions¶
Purpose¶
One possibility to make a grand average over several runs
of a experiment is to average the data across runs and average the
forward solutions accordingly. For this purpose,
mne.average_forward_solutions()
computes a weighted average of several
forward solutions. The function averages both MEG and EEG forward solutions.
Usually the EEG forward solution is identical across runs because the electrode
locations do not change.


2020, Day 10, Part 2 - Hints
My background being in mathematics, I do suffer a bit parse-heavy days, while I enjoy thoroughly days like today.
Below a sequence of micro-hints to help those who have the reciprocal suffering.
Following them all the way should result in something similar to my implementation,
but you might want to stop earlier and come up with your own version.
Problem
You have to implement a function solve2
that counts all possible arrangements of a sequence of integers according to the constraints:
- start with 0
- any subsequent element should have a difference with the previous that is either 1, 2 or 3
- end with max element of the sequence + 3
(Advent of) Hints
I am not really using nim notation in the hints and they should be agnostic with respect to the programming language.
Hint 1
Sort your input if you haven't already (you should have in part1) and realize there are no duplicates
Hint 2
Is there a way to split the problem from a big sequence into several subsequences?
Hint 3
In particular, are there elements in the sequence that cannot be skipped in any configuration (e.g. every configuration must contain them)?
Hint 4
I mean in the sequences [0 3 4]
or [0 1 4]
(or [0 2 5]
or [0 3 5]
) can I ever skip the middle element? How many configurations do those have?
Hint 5
yep, those sequences only have one conifguration possible
Hint 6
realize that you can in fact split your problem whenever you have an element that has a difference of 3
with either the preceding or subsequent element
Hint 7
in particular realize that the absolute values of the elements do not really matter, only their differences 🤯!
Hint 8
implement a diff
function (output of the above sequences would be (3 1)
, (1 3)
, (2 3)
, (3 2)
; note that I changed the syle of parentheses: []
for original sequence and ()
for its differences.
Hint 9
the new function we need to implement we call it numArr
and computs number of possible arrangements given the differences of a (sub)sequence (it assumes first and last elements must be in the sequence)
Hint 10
previous hints imply that numArr (s 3 t) = numArr(s)*numArr(t)
where s
and t
are subsequence 😲
Hint 11
now you are starting to realize that you will use recursion 🐢🐢🐢
Hint 12
manually compute the result over all possible difference sequences of length 2 and 3 (without a 3
difference)
Hint 13
is there another difference configuration that will result in stuff you cannot skip, can you see it?
Hint 14
numArr (s 2 2 t) = ?
Hint 15
numArr (s 2 2 t) = numArr(s)*numArr(t)
Hint 16
you are almost there but not yet: now you can split problem from a big sequence into a subsequence for some special cases, how do I reduce the computation for a sequence that has none of this special cases? I need to be able to reduce the length of the sequence!
Hint 17
to count the number of arrangements start counting those which contain the second element (remember the first must be included) and then count those who do not
Hint 18
try with this sequence (1 1 1 1)
, you can think of it as [0 1 2 3 4]
Hint 19
numArr (x y s) = ?
where x
, y
are single differences and s
is a subsequence
Hint 20
correct! numArr (x y s) = numArr (y s) + numArr (x+y s)
💪
Hint 21
(note that having excluded the special cases when one of the difference is 3
or two subsequent 2
s, now x + y <= 3
)
Hint 22
that's about it, you can implement a recursion using this, trying to take care first of the special cases (short lengths, diff sequences containg 3
or two 2
s)
Hint 23
(optional) ok, you want more? what does speed up recursion in case you need to recompute previously computed results?
Hint 24
that's right: memoization!
Hint 25
I am out of hints and you can just go and see my implementation! Hope you enjoyed!
import nimib, nimoji, markdown
nbInit
var hint = 1
template nbxHint(details: string) =
nbText: "Hint " & $hint & "
" & details.emojize.markdown & "
"
inc hint
nbText: """# 2020, Day 10, Part 2 - Hints
My background being in mathematics, I do suffer a bit parse-heavy days, while I enjoy thoroughly days like today.
Below a sequence of micro-hints to help those who have the reciprocal suffering.
Following them all the way should result in something similar to my implementation,
but you might want to stop earlier and come up with your own version.
## Problem
You have to implement a function `solve2` that counts all possible arrangements of a sequence of integers according to the constraints:
* start with 0
* any subsequent element should have a difference with the previous that is either 1, 2 or 3
* end with max element of the sequence + 3
## (Advent of) Hints
I am not really using [nim](https://nim-lang.org/) notation in the hints and they should be agnostic with respect to the programming language.
"""
nbxHint: "Sort your input if you haven't already (you should have in part1) and realize there are no duplicates"
nbxHint: "Is there a way to split the problem from a big sequence into several subsequences?"
nbxHint: "In particular, are there elements in the sequence that **cannot** be skipped in any configuration (e.g. every configuration must contain them)?"
nbxHint: "I mean in the sequences `[0 3 4]` or `[0 1 4]` (or `[0 2 5]` or `[0 3 5]`) can I ever skip the middle element? How many configurations do those have?"
nbxHint: "yep, those sequences only have one conifguration possible"
nbxHint: "realize that you can in fact split your problem whenever you have an element that has a difference of `3` with either the preceding or subsequent element"
nbxHint: "in particular realize that the absolute values of the elements do not really matter, only their differences :exploding_head:!"
nbxHint: "implement a `diff` function (output of the above sequences would be `(3 1)`, `(1 3)`, `(2 3)`, `(3 2)`; note that I changed the syle of parentheses: `[]` for original sequence and `()` for its differences."
nbxHint: "the new function we need to implement we call it `numArr` and computs number of possible arrangements given the differences of a (sub)sequence (it assumes first and last elements **must** be in the sequence)"
nbxHint: "previous hints imply that `numArr (s 3 t) = numArr(s)*numArr(t)` where `s` and `t` are subsequence :astonished:"
nbxHint: "now you are starting to realize that you will use recursion :turtle::turtle::turtle:"
nbxHint: "manually compute the result over all possible difference sequences of length 2 and 3 (without a `3` difference)"
nbxHint: "is there another difference configuration that will result in stuff you cannot skip, can you see it?"
nbxHint: "`numArr (s 2 2 t) = ?`"
nbxHint: "`numArr (s 2 2 t) = numArr(s)*numArr(t)`"
nbxHint: "you are almost there but not yet: now you can split problem from a big sequence into a subsequence for some special cases, how do I reduce the computation for a sequence that has none of this special cases? I need to be able to reduce the length of the sequence!"
nbxHint: "to count the number of arrangements start counting those which contain the second element (remember the first must be included) and then count those who do not"
nbxHint: "try with this sequence `(1 1 1 1)`, you can think of it as `[0 1 2 3 4]`"
nbxHint: "`numArr (x y s) = ?` where `x`, `y` are single differences and `s` is a subsequence"
nbxHint: "correct! `numArr (x y s) = numArr (y s) + numArr (x+y s)` :muscle:"
nbxHint: "(note that having excluded the special cases when one of the difference is `3` or two subsequent `2`s, now `x + y <= 3`)"
nbxHint: "that's about it, you can implement a recursion using this, trying to take care first of the special cases (short lengths, diff sequences containg `3` or two `2`s)"
nbxHint: "(optional) ok, you want more? what does speed up recursion in case you need to recompute previously computed results?"
nbxHint: "that's right: [memoization](https://en.wikipedia.org/wiki/Memoization)!"
nbxHint: "I am out of hints and you can just go and see my [implementation](https://github.com/pietroppeter/adventofnim/blob/master/2020/day10.nim)! Hope you enjoyed!"
nbSave


Black Hole Review
\[
I_{0}[g_{\mu\nu},A_{\mu}]=-\frac{1}{16\pi}\int\rd^{4}x\sqrt{-g}\, \left(R-F_{\mu\nu}^2\right) \quad \quad
\left(G_N=1\right)
\]
Relevant Points
-
BHs fully specified by mass, spin, charge: \(M,Q,J\)
-
Thermodynamic description: \(T, S,\ldots\)
-
Entropy: \(S=\frac{\rm Area}{4}\), depends on \(M,Q,J\)
-
When \(Q,J\neq 0\) there is a minimum mass: \(M>M_{\rm ext}(Q,J)\)
Metric Description: \(Q\neq 0\)
\[
I_{0}[g_{\mu\nu},A_{\mu}]=-\frac{1}{16\pi}\int\rd^{4}x\sqrt{-g}\, \left(R-F_{\mu\nu}^2\right)
\]
\[
\begin{gather}
g_{\mu\nu}\rd x^{\mu}\rd x^{\nu}=-\Delta \rd t^{2}+\Delta^{-1}\rd r^{2}+r^{2}\rd \Omega^{2}\ , \quad A_{\mu}\rd x^{\mu}=\frac{Q}{r}\rd t\nn
\Delta=\left(1-\frac{2M}{r}+\frac{Q^{2}}{r^{2}}\right)
\end{gather}
\]
\(M,Q\) determine horizons.
\[
\begin{gather}
r_{\pm}= M\pm \sqrt{M^2-Q^2}
\end{gather}
\]
Must have \(M>Q\), else Naked Singularity
Thermodynamic Description: \(Q\neq 0\)
Famously, black holes behave thermodynamically
Temperature and Entropy given by
\[
\begin{gather}
T_0(M,Q)=\frac{r_{+}-M}{2\pi r_{+}^{2}}\quad \quad S_{0}(M,Q)=\frac{\rm Area}{4}=\pi r_{+}^{2}\nn
r_{+}\equiv M+\sqrt{M^{2}-Q^{2}}
\end{gather}
\]
Must again have \(M>Q\), otherwise \(T,S\) are imaginary
Extremal Mass
\[
M(Q,T)> \lim_{T\to 0}M(Q,T)=Q\equiv M_{\rm ext}^{0}(Q)
\]
Moving Away from GR
Change theory: \(\Delta \mathcal{L}\) from UV physics. Studied re: LIGO
Relations between \(T,S,\ldots\) and \(M,Q,J\) altered
-
Entropy: \(S=\frac{\rm Area}{4}+({\rm other\ geometric \ factors})\)
-
Minimum mass is altered: \(M_{\rm ext}=M_{\rm ext}^{0}+\Delta M_{\rm ext}\)
Corrections \(\Delta S, \Delta M_{\rm ext}\) are complicated functions of \(M,Q,J,c_i\)
Charged BHs: \(\Delta M_{\rm ext}(Q,c_i)~\)and \(\Delta S(M,Q,c_i)\). \(J=0\)
Surprise: \(\Delta M\propto -\Delta S\) near minimal mass, \(M\approx Q\)
\(\bbox[5px, border: 2px solid red]{\Delta S\propto -\Delta M_{\rm ext}\Big|_{M\approx Q}}\)
Reveals new implications of Weak Gravity Conjecture
Connecting \(\Delta M_{\rm ext}\) and \(\Delta S\)
Similar Phenomenological Findings
\(\Delta S\propto -\Delta M_{\rm ext}\Big|_{\approx {\rm minimum \ mass}}\) in all cases
Crying out for a universal thermodymamic explanation


{% load staticfiles %}
 {{recipe.time}} minutes Price: ${{recipe.price}} Servings: {{recipe.servings}}
January 1, 2014 by {{recipe.user.name}}
{{recipe.description}}
{{recipe.methods|linebreaks}}


A very customer friendly site with all bank features at doorstep or rather in one's own hands. Experience the best way of banking
Give all your details and create your account
Cashier can transfer, deposit, and withdraw amount from your account.
Get all your transaction details and check your balance
We give the best service of support. Our team is available 24×7 to help you with your problem.
We provide best insurance policy for you. A policy affordable to all classes. Do read more.


Welcome jim.riaz
Service unavailable
Scheduled maintenance from 17 June to 20 June 2016.
Please sign in after 15:00 20 Jun 2016.
You will not be able to use the site during this time. Sorry for any inconvenience this may cause.


Open Pampas [av19], plain, in Mandoria, peasants: 104
Last updated Turn #148
Open Pampas [av19], plain, in Mandoria, peasants: 104
------------------------------------------------------------------------
18: De Bloemkool [c6t], refugee, arrived from the west.
22: De Bloemkool [c6t], refugee, went east.
23: Stack of cyclops [fk6y], cyclops, number: 9, arrived from the east.
25: Stack of cyclops [fk6y], cyclops, number: 9, went west.
30: The population grows by one peasant.
Routes leaving Open Pampas:
North, plain, to Open Pampas [au19], 7 days
East, plain, to Open Pampas [av20], 7 days
South, plain, to Open Pampas [aw19], 7 days
West, plain, to Open Pampas [av18], 7 days
Seen here:
Stack of giants [fo1m], giants, number: 10
Stack of cyclops [fk6y], cyclops, number: 9


ionic
The Ionic CLI is your go-to tool for developing Ionic apps. You can follow CLI development on Github.
Installation
Please make sure Node 6+ and NPM 3+ are installed.
Then, install the CLI globally (you may need sudo):
$ npm install -g [email protected]
Getting Started
Start a new Ionic project using ionic start
:
ionic start myNewProject tabs
cd ./myNewProject
This will create a new app named myNewProject
. Once you cd
into your
project’s directory, a few new commands become available to you, such as
serve
:
ionic serve
Commands
Here is a full list of Ionic commands. You can also see the list on the command
line with ionic --help
.
| Command | Description |
|---|---|
| docs | Open the Ionic documentation website |
| generate | Generate pipes, components, pages, directives, providers, and tabs (ionic-angular >= 3.0.0) |
| info | Print system/environment info |
| link | Connect your local app to Ionic |
| login | Login with your Ionic ID |
| serve | Start a local development server for app dev/testing |
| signup | Create an Ionic account |
| start | Create a new project |
| telemetry | Opt in and out of telemetry |
| upload | Upload a new snapshot of your app |
| cordova build | Build (prepare + compile) an Ionic project for a given platform |
| cordova compile | Compile native platform code |
| cordova emulate | Emulate an Ionic project on a simulator or emulator |
| cordova platform | Add or remove a platform target for building an Ionic app |
| cordova plugin | Manage Cordova plugins |
| cordova prepare | Transform metadata to platform manifests and copies assets to Cordova platforms |
| cordova resources | Automatically create icon and splash screen resources |
| cordova run | Run an Ionic project on a connected device |
| package build | Start a package build |
| package download | Download your packaged app |
| package info | Get info about a build |
| package list | List your cloud builds |


Tomato is an online food delivery application. It is a restaurant aggregator and food delivery company. You have been hired as a consultant for the company. They have started their business in one location only, Bangalore. They target one area, Electronic city, in a group of 4 societies with middle-class families. They started their promotion and sales as follows-
Scenerio 3
The idea here is for people to be aware of an option called Tamato. To their surprise, people did order later in the week as well. Details as follows
i) Within 1st week after initiation, 50% of people repeated order
ii) 2nd-week post-offer, 25% repeated order
iii) 3rd week onwards there was no orders
Assuming that the orders are for the same amount as before on average, what would be the company's profit now? (Revenue margin is 20% on the amount of purchase still)


CARDS
Memory Error Detected: 1
Control Flow Error Detected: 6
Most Recent Error Detected: Memeory Corruption Error


In computer science, arranging in an ordered sequence is called "sorting". Sorting is a common operation in many applications, and efficient algorithms to perform it have been developed.
The most common uses of sorted sequences are:
Making lookup or search efficient.
Making merging of sequences efficient.
Enable processing of data in a defined order.
The opposite of sorting, rearranging a sequence of items in a random or meaningless order, is called shuffling.
For sorting, either a weak order, "should not come after", can be specified, or a strict weak order, "should come before" (specifying one defines also the other, the two are the complement of the inverse of each other, see operations on binary relations). For the sorting to be unique, these two are restricted to a total order and a strict total order, respectively.
Sorting n-tuples (depending on context also called e.g. records consisting of fields) can be done based on one or more of its components. More generally objects can be sorted based on a property. Such a component or property is called a sort key.
For example, the items are books, the sort key is the title, subject or author, and the order is alphabetical.
A new sort key can be created from two or more sort keys by lexicographical order. The first is then called the primary sort key, the second the secondary sort key, etc.
For example, addresses could be sorted using the city as primary sort key, and the street as secondary sort key.
If the sort key values are totally ordered, the sort key defines a weak order of the items: items with the same sort key are equivalent with respect to sorting. See also stable sorting. If different items have different sort key values then this defines a unique order of the items.
Workers sorting parcels in a postal facility
A standard order is often called ascending (corresponding to the fact that the standard order of numbers is ascending, i.e. A to Z, 0 to 9), the reverse order descending (Z to A, 9 to 0). For dates and times, ascending means that earlier values precede later ones e.g. 1/1/2000 will sort ahead of 1/1/2001.
Stable v/s Unstable Sorting
A sorting algorithm is said to be stable if two objects with equal keys appear in the same order in sorted output as they appear in the input unsorted array.
Whereas a sorting algorithm is said to be unstable if their are two or more objects with equal keys doesn't appear in same order before and after sorting.
Stable v/s Unstable Sorting
A sorting algorithm using at most h comparisons on all inputs corresponds to a tree of height at most h. Such a tree has at most 2 × h leaves. On the other hand, each permutation of 1, ... ,N must land at a different leaf, and so there must be at least N! leaves. Putting these together, we deduce that 2 × h ≥ N! and so h ≥ log2 N! = Ω(N log N) (using Stirling's approximation). So every sorting algorithm must use at least log2 N! = Ω(N log N) comparisons in the worst case (on some inputs it can use less)
Selection Sort
(Stable comparison sort of θ(N2) complexity)
Selection sort is a sorting algorithm, specifically an in-place comparison sort. It has θ(N2) time complexity, making it inefficient on large lists, and generally performs worse than the similar insertion sort. Selection sort is noted for its simplicity, and it has performance advantages over more complicated algorithms in certain situations, particularly where auxiliary memory is limited.
The algorithm divides the input list into two parts: the sublist of items already sorted, which is built up from left to right at the front (left) of the list, and the sublist of items remaining to be sorted that occupy the rest of the list. Initially, the sorted sublist is empty and the unsorted sublist is the entire input list. The algorithm proceeds by finding the smallest (or largest, depending on sorting order) element in the unsorted sublist, exchanging (swapping) it with the leftmost unsorted element (putting it in sorted order), and moving the sublist boundaries one element to the right.
Points to note:
Selection sort is an in-place comparison sort.
Best, average and worst case time complexity is θ(N2)
It has one of the lowest number of swaps of all sorting algorithms.
# Selection sort implementation in Python 3
from random import random as r
array = [int(r() * 1024) for i in range(16)]
def sort():
for i in range(len(array)):
min_value = array[i]
min_pos = i
for j in range(i + 1, len(array)):
if array[j] < min_value:
min_value = array[j]
min_pos = j
# Swap array[i] with array[min_pos]
array[i], array[min_pos] = array[min_pos], array[i]
if __name__ == "__main__":
print("Unsorted Array: ", array)
sort()
print("Sorted Array: ", array)
Bubble Sort
(Stable comparison sort of θ(N2) complexity)
Bubble sort, sometimes referred to as sinking sort, is a simple sorting algorithm that repeatedly steps through the list to be sorted, compares each pair of adjacent items and swaps them if they are in the wrong order. The pass through the list is repeated until no swaps are needed, which indicates that the list is sorted. The algorithm, which is a comparison sort, is named for the way smaller or larger elements "bubble" to the top of the list. Although the algorithm is simple, it is too slow and impractical for most problems even when compared to insertion sort. It can be practical if the input is usually in sorted order but may occasionally have some out-of-order elements nearly in position.
Bubble sort has worst-case and average complexity both θ(N2), where n is the number of items being sorted. There exist many sorting algorithms, such as merge sort with substantially better worst-case or average complexity of θ(N log2 N). Even other θ(N2) sorting algorithms, such as insertion sort, tend to have better performance than bubble sort. Therefore, bubble sort is not a practical sorting algorithm when n is large.
# Bubble Sort implementation in Python 3
from random import random as r
array = [int(r() * 1024) for i in range(16)]
def sort():
for i in range(len(array)):
for j in range(len(array) - i - 1):
if array[j] > array[j + 1]:
array[j], array[j + 1] = array[j + 1], array[j]
if __name__ == "__main__":
print("Unsorted Array: ", array)
sort()
print("Sorted Array: ", array)
Quick Sort
(Comparison sort of θ(N log2 N) average-case complexity
Has θ(N2) worst-case complexity)
Quick Sort (sometimes called partition-exchange sort) is an efficient sorting algorithm, serving as a systematic method for placing the elements of an array in order. Developed by Tony Hoare in 1959 and published in 1961, it is still a commonly used algorithm for sorting. When implemented well, it can be about two or three times faster than it's main competitors, merge sort and heapsort.
Quick Sort is a comparison sort, meaning that it can sort items of any type for which a "less-than" relation (formally, a total order) is defined. In efficient implementations it is not a stable sort, meaning that the relative order of equal sort items is not preserved. Quicksort can operate in-place on an array, requiring small additional amounts of memory to perform the sorting. It is very similar to selection sort, except that it does not always choose worst-case partition.
Mathematical analysis of quicksort shows that, on average, the algorithm takes θ(N log2 N) comparisons to sort n items. In the worst case, it makes O(N2) comparisons, though this behavior is rare.
Example of partition function (Showing a single pass)
Showing Quick Sort as divide-&-conquer algorithm
# Quick Sort implementation in Python 3
from random import random as r
array = [int(r() * 1024) for i in range(16)]
# Lomuto Partition function
def partition(lb, ub):
pivot_index = ub
k = lb - 1
for i in range(lb, ub):
if array[i] < array[pivot_index]:
k += 1
array[k], array[i] = array[i], array[k]
k += 1
array[k], array[pivot_index] = array[pivot_index], array[k]
return k
# Quick Sort recursive implementation
def quick_sort(lb, ub):
if lb < ub:
p = partition(lb, ub)
quick_sort(lb, p - 1)
quick_sort(p + 1, ub)
# Quick Sort implementation
def sort():
quick_sort(0, len(array) - 1)
if __name__ == "__main__":
print("Unsorted Array: ", array)
sort()
print("Sorted Array: ", array)
Heap Sort
(Unstable comparison sort of θ(N log2 N) complexity)
In computer science, heapsort is a comparison-based sorting algorithm. Heap Sort can be thought of as an improved selection sort: like that algorithm, it divides its input into a sorted and an unsorted region, and it iteratively shrinks the unsorted region by extracting the largest element and moving that to the sorted region. The improvement consists of the use of a heap data structure rather than a linear-time search to find the maximum.
Although somewhat slower in practice on most machines than a well-implemented quicksort, it has the advantage of a more
favorable worst-case θ(N log2 N) runtime. Heapsort is an in-place algorithm, but it is not a stable sort.
Heap Sort was invented by J. W. J. Williams in 1964. This was also the birth of the heap, presented already by Williams as a useful data structure in its own right. In the same year, R. W. Floyd published an improved version that could sort an array in-place, continuing his earlier research into the treesort algorithm.
The heapsort algorithm can be divided into two parts.
In the first step, a heap is built out of the data. The heap is often placed in an array with the layout of a complete binary tree. The complete binary tree maps the binary tree structure into the array indices; each array index represents a node; the index of the node's parent, left child branch, or right child branch are simple expressions. For a zero-based array, the root node is stored at index 0; if i is the index of the current node, then
iParent(i) = floor((i - 1) / 2) where floor functions map a real number to the smallest leading integer
iLeftChild(i) = 2 × i + 1
iRightChild(i) = 2 × i + 2
In the second step, a sorted array is created by repeatedly removing the largest element from the heap (the root of the heap), and inserting it into the array. The heap is updated after each removal to maintain the heap property. Once all objects have been removed from the heap, the result is a sorted array.
Heap Sort can be performed in place. The array can be split into two parts, the sorted array and the heap. The storage of heaps as arrays is diagrammed here. The heap's invariant is preserved after each extraction, so the only cost is that of extraction.
# Heap Sort implementation in Python 3
from random import random as r
array = [int(r() * 1024) for i in range(16)]
def parent(index):
return (index - 1) >> 1
def right(index):
return (index << 1) + 1
def left(index):
return (index << 1) + 2
# Function to build max heap from given array
def build_max_heap():
for i in range(len(array)):
index = i
while parent(index) >= 0 and array[index] > array[parent(index)]:
array[index], array[parent(index)] = array[parent(index)], array[index]
index = parent(index)
# Iterative Heap Sort implementation
def sort():
build_max_heap()
size = len(array)
for i in range(len(array)):
array[0], array[size - 1] = array[size - 1], array[0]
size -= 1
# Swim down the top of heap until balanced
current_index = 0
while True:
max_index = current_index
if left(current_index) < size and array[left(current_index)] > array[max_index]:
max_index = left(current_index)
if right(current_index) < size and array[right(current_index)] > array[max_index]:
max_index = right(current_index)
if max_index != current_index:
array[max_index], array[current_index] = array[current_index], array[max_index]
current_index = max_index
else:
break
if __name__ == "__main__":
print("Unsorted Array: ", array)
build_max_heap()
print("Max Heap: ", array)
sort()
print("Sorted Array: ", array)


Origins
all
Nuxeo
Community
Personal
Languages
all
Categories
all
Sort by:
default
name
pushed_at
watchers
random


Video lesson: learn the number one missing guitar skill
by MusicRadarVideo lesson: learn the number one missing guitar skill
This week Guitar Mastery's Claus Levin is looking at the skill every musician needs, and he's got some simple but essential exercises to learn it…
-----------------------------------------------------
This exclusive MusicRadar video lesson is brought to you in association with our friends at Guitarmastery.net. Check out their site for more lessons and courses.
-----------------------------------------------------
Over the last two decades I have been lucky enough to study hundreds of aspiring guitar masters and the number one challenge for almost all of them has been lack of rhythm skills.
If you could wave a magic wand an become an instant master of rhythm right now, your playing would be almost unrecognisable. And I mean ALL of your playing – soloing, rhythm guitar, finger picking… all of it.
Rhythm is probably what holds us back more than anything else... just think about it; rhythm makes up 50% of the musical equation so whatever you are practicing or listening to, at least 50% of it is pure rhythm.
The great news is that mastering rhythm is easily learned and you can practice it without your guitar.
-
Check out the previous lessons in this series:
My number one favourite pentatonic shape of all time , The magic of the pentatonic double-note shape , Super-easy ways to use advanced scale shapes to spice up your playing .


User Details
First Name
Last Name
Email
Permission
Admin
Default
Observer
Group
Manager
Analyst
Pentester
Client.Rep
Save
Cancel
Current Tasks
Task Name
Perform Arp Scans !!
Due Date
10/24/1984


Working with a SQLite Database
Objective
In this chapter, you will learn how to interact with the built-in SQLite3 RDMS with the Ti.Database module. You'll learn how to create databases and tables. You'll retrieve data. And you'll store data in the database.
Contents
SQLite3 is version 3 of SQLite's SQL-based relational database management system (RDMS), chosen by Apple, Google and RIM to provide local data storage on their mobile devices. SQLite is currently the world's most widely-used database. It owes it's popularity to its open source code, low resource footprint and, as it does not rely on any installed services unlike almost all other DBMSs, its simplicity of setup and maintenance.
There are a few things to note when you first work with SQLite, that may influence the way you develop with it:
-
SQLite's data is stored in a simple text file. There is no granular security or user privileges for data. Anyone with filesystem access to it may read its contents.
-
There are only five underlying data types; TEXT, NUMERIC, INTEGER, REAL, NONE. Datatypes In SQLite explains them in more detail.
-
Binary objects (BLOBs) are stored as text representations, thus access to BLOBs is not optimal. We recommend you store BLOBs on the filesystem and store the filesystem path in the database.
-
SQLite supports concurrent read access, but enforces sequential write access. This is because a filesystem lock is placed on the file during write operations. This is an important point to bear in mind with multi-threaded applications.
-
Referential integrity is not enabled by default. See SQLite Foreign Key Support for more information.
-
RIGHT and FULL OUTER JOINs are not supported.
-
There is limited ALTER TABLE support; columns may not be modified or deleted.
Titanium provides access to SQLite via its Titanium.Database module that returns the Titanium.Database.DB object, for installing and opening databases and executing queries, and the Titanium.Database.ResultSet object, which holds the data returned from those queries.
Creating a database
To open a database file, instantiate the Titanium.Database object with its open() or install() methods.
Using open() will open a database file from the database directory within the application's directory structure on the device. On Android, this is applicationDataDirectory/../databases/, thus residing in the same parent directory as the applicationDataDirectory. If a database file does not already exist with the same name, a new, empty (except for some system tables) SQLite database file will be automatically created.
var db = Ti.Database.open('weatherDB');
This code will create a file with a filename of weatherDB and return an instance of Titanium.Database.DB. You may prefer to give the file a .sqlite or .db extension, although this is not mandatory.
On the other hand, install() will copy a pre-existing database file from Titanium's Resources directory, or one of its descendants, to applicationDataDirectory/../databases/ and return a reference to the opened database. If a file already exists with the same name, the copy action will silently fail and the database will simply be opened (and reference returned).
var db = Ti.Database.install('/mydata/weatherDB', 'weatherDB');
In this example, weatherDB, initially stored in the Resources/mydata/ directory, will be copied to the application's databases directory.
Both open() and install() are safe methods in that calling either in reference to an existing database will not overwrite or delete an existing database file.
Once the database exists and is opened, some tables may be created using the execute() method:
db.execute('CREATE TABLE IF NOT EXISTS city (id INTEGER PRIMARY KEY, name VARCHAR(16) NOT NULL, continent VARCHAR(16) NOT NULL, temp_f VARCHAR(4), temp_c VARCHAR(4), condition_id INTEGER NOT NULL)');
db.execute('CREATE TABLE IF NOT EXISTS condition (id INTEGER PRIMARY KEY, summary VARCHAR(16) NOT NULL, icon TEXT NOT NULL)');
The IF NOT EXISTS part of these statements is standard SQLite syntax to ensure that tables will not be overwritten if they already exist. Hence, it's commonplace to use them when an application starts, to ensure that an application won't fail due to a missing database file or table structure.
Pre-populating a database
You have a couple of options to pre-populate a database for your app: include it in the app's package or download it from a remote server.
Include it in the application package
If you have a database that already contains data that you want to use for your application, you can distribute it with your app and install it the first time your app is run. You would place your SQLite database file in your app's Resources directory during development. Then you'd include an install() call in your app's initialization routines.
Shipping an initial database with your app increases the size of the app's package file (ipa or apk) making for slower downloads from the App Store or Market. It also consumes more storage space on the user's device. install() will copy the file to the applicationDataDirectory/../databases/ folder. Because the Resources directory is read-only on the device, the distribution database file cannot be deleted, resulting in two copies of this file on the user's device.
If timeliness of your data is crucial to your application's usefulness, consider whether it is appropriate to ship the application with a full database when it will no doubt be replaced soon after initial install.
Download from a remote resource
As an alternative to the above, you can ship a "skeleton" database file; this is a database with the minimum amount of data required for the application to run. Then, on first boot, ask the user's authorization to download a replacement from a remote source, using the following method:
buttonInstallRemote.addEventListener('click', function(){
var fileWeatherDB = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory,'../databases/'+filename);
var c = Ti.Network.createHTTPClient();
c.setTimeout(10000);
c.onload = function(e){
fileWeatherDB.write(this.responseData);
Ti.API.info("ONLOAD = "+e);
Ti.UI.createAlertDialog({title:'Info', message:'Database installed', buttonNames: ['OK']}).show();
};
c.onerror = function(e){
Ti.UI.createAlertDialog({title:'Error', message:'Error: ' + e.error, buttonNames: ['OK']}).show();
};
c.open('GET',"http://wiki.appcelerator.org/download/attachments/6261518/weatherDB");
c.send();
});
Storing data
In order to insert records to a database, you should pass an SQL INSERT statement to the execute() method. While you could use string concatenation to construct the INSERT statement, SQLite and Titanium's execute() method support the safer technique of using unnamed parameterized queries. In other words, you enter question marks as placemarkers where you would like each variable containing your data to be substituted, as follows:
db.execute('INSERT INTO city (name,continent,temp_f,temp_c,condition_id) VALUES (?,?,?,?,?)',importName,importContinent,importTempF,importTempC,dbConditionId);
It's commonplace for tables to include an auto-incrementing primary key, representing a unique ID for each row. You would typically use such IDs to access individual rows to update them or delete them. You can obtain the row ID associated with a newly inserted row by examining the lastInsertRowID property, like this:
db.execute('INSERT INTO city (name,continent,temp_f,temp_c,condition_id) VALUES (?,?,?,?,?)',importName,importContinent,importTempF,importTempC,dbConditionId);
var lastID = db.lastInsertRowID; // presumes `city` has an auto-increment column
Reading data
You can retrieve data from the database using a typical SQL SELECT query, passed to execute() like the examples above. This method returns a Titanium.Database.ResultSet object, which you use to access the queried data.
(The execute() method always returns a result set object, but it's not all that useful with CREATE TABLE and other queries shown previously.)
The result set data is available using the methods that the Titanium.Database.ResultSet object provides. In the following code, a loop is used to iterate through each row, and only ends when isValidRow() returns false. The fieldByName() method allows you to refer to each field by its database column name, or an alias you assign in the SQL statement. At each iteration of the loop, it is necessary to move the ResultSet row pointer to the next row, using the next() method.
var cityWeatherRS = db.execute('SELECT id,name,continent FROM city');
while (cityWeatherRS.isValidRow())
{
var cityId = cityWeatherRS.fieldByName('id');
var cityName = cityWeatherRS.fieldByName('name');
var cityContinent = cityWeatherRS.fieldByName('continent');
Ti.API.info(cityId + ' ' + cityName + ' ' + cityContinent);
cityWeatherRS.next();
}
cityWeatherRS.close();
You may join related tables together, just as you would in standard SQL. The following returns all the city records and includes the weather conditions summary for each, if it exists.
db.execute('SELECT city.id,name,cond.id,cond.summary,cond.icon FROM city LEFT JOIN condition cond WHERE city.condition_id = cond.id');
Of course, you can select subsets of data by providing conditions within your SELECT statements. For example, the following returns only those records where the weather summary is "Partly Cloudy":
var cityWeatherRS = db.execute('SELECT city.id AS city_id,name,cond.id AS cond_id,cond.summary,cond.icon FROM city LEFT JOIN condition cond WHERE city.condition_id = cond.id WHERE cond.summary=?', "Partly Cloudy");
Notice here that the city.id and cond.id columns have been aliased. This is because the fieldByName() method would not be able to distinguish between them if you simply passed their column name, fieldByName(id). Thus, the ResultSet code would look like this:
while (cityWeatherRS.isValidRow())
{
var cityId = cityWeatherRS.fieldByName('city_id');
var cityName = cityWeatherRS.fieldByName('name');
var cityConditionId = cityWeatherRS.fieldByName('cond_id');
var cityConditionSummary = cityWeatherRS.fieldByName('summary');
var cityConditionIcon = cityWeatherRS.fieldByName('icon');
Ti.API.info(cityId + ' ' + cityName + ' ' + cityConditionId + ' ' + cityConditionSummary + ' ' + cityConditionIcon);
cityWeatherRS.next();
}
cityWeatherRS.close();
Updating data
To update a database row you would use the UPDATE statement along with parameterized queries as shown above for inserting data. For example:
db.execute('UPDATE condition SET icon=? WHERE id=?',importIcon,dbConditionId);
Deleting data
You can delete one or more rows from a table using the DELETE statement. Make sure to supply a condition or all rows in the table will be deleted. SQLite also supports the DROP TABLE syntax to remove an entire table from the database.
db.execute('DELETE FROM city WHERE id=?',cityId);
Closing the database and ResultSet
As explained in the introduction, SQLite enforces sequential write-access to the database (one process at a time). This makes it vital that you close the database connection when you have completed any INSERT or UPDATE operations. If you don't, you might receive "DatabaseObjectNotClosed" exceptions when your script next attempts to write to it.
db.close();
Leaving the ResultSet open is less of an issue, but it's good practice to close it to free system resources.
cityWeatherRS.close();
Unlike a web environment, connection pooling is not a consideration. In general, the time to open and close database connections is minimal. Any time savings gained there is more than lost in the extra resources consumed by open connections and the potential for "DatabaseObjectNotClosed" exceptions.
Hands-on Practice
Goal
In this activity, you will write an app that will display the contents of a database in a table. The app's output will respect the user's preference for units based on data saved in a Ti.App.Properties property. When complete, your app should look like the following:
Resources
To perform the steps in this activity, you will need the following files:
Steps
-
If you didn't complete the 5.2 lab, download the starting code sample and import that project.
-
Download the sample database and store it in the Resources directory of your project.
-
Add the code to install the database, naming your app's database weather.
-
Add the following function to convert temperatures to Fahrenheit based on the user's preference (update as necessary to reflect your app's namespace):
myapp.convertTemp = function(temp) { if(Ti.App.Properties.getString('units','c')==='f') { return Math.round(temp*1.8+32) +'\u00b0F'; // convert to Fahrenheit & append degree symbol-F } else { return temp +'\u00b0C'; } };
-
Write a function named getRows() that accomplishes the following:
-
Opens the database
-
Executes the following query: SELECT city, temp, condition, icon FROM cities JOIN conditionCodes ON cities.conditionID = conditionCodes.conditionID ORDER BY city
-
Loop through the result set. For each result, create a table row that contains these three child views:
-
An ImageView pointing to http://www.worldweather.org/img_cartoon/ plus the value of the icon column. The image should be shown at the left edge of the row.
-
Label to display the City name. The text should be large and bold, and positioned to the right of the image.
-
A Label to display the temperature, as formatted by the convertTemp() function. It should be smaller text, positioned at the right edge of the row.
-
-
Make sure to close the database connection when the function is done, and return the resulting array to the caller.
-
-
In the window on tab 1, add a TableView. Then write a populate() function that sets the table's data to the results from the getRows() function.
-
Add an App-level event listener that calls the populate() function.
-
Update the event listener on the units switch (on the preferences tab) to fire your app-level event when the user updates the temperature units.
-
Build and test your app in the simulator/emulator.
References and Further Reading
Summary
In this chapter, you learned how to interact with the built-in SQLite3 RDMS with the Ti.Database module. You learned how to create, install, and populate databases. You also learned how to use SQL to perform CRUD (create, read, update, and delete) operations on your data.


I received a Bachelor's degree in Joint Biology and Chemistry from Harvey Mudd College in 2008. Since then I have moved around in a wide variety of fields. I spent a few years working in wineries here and around the world. While exciting and rewarding, it was not a stable career so I returned to the US. I began working as a biometric technician for the US Citizenship and Immigartion Services (USCIS). I was promoted to backup site supervisor within a year. After four years I moved on to working as a personal assistant. I was unhappy in my career path and decided I needed a change. I decided to return to school to learn how to program.


A p element with class="example" in a div.
Another p element with class="example" in a div.
A p element in div with a span element with class="example" inside of it.
Click the button to add a background color to all elements with class="example" inside DIV.
Note: The querySelectorAll() method is not supported in Internet Explorer 8 and earlier versions.


GIFy.me
A simple animated GIF creator
Drop or select 4 images
Woops, something is wrong!
Browse...
30%
How many loops?
Infinite
Delay between frames?
in milliseconds
Create GIF!


{% load otree static %}
First, every player will be randomly paired with another player. In other words, you will have a counterpart, but you will not be told who it is. Your identity will also remain hidden from your counterpart.
The two participants in a pair will have two different roles: the proposer and the responder. You will be assigned randomly to a role, and it will be displayed on the next page.
There will be {{ Constants.num_rounds }} rounds of the game. Your role will remain the same for all rounds. However, your counterpart will be chosen randomly each round among the players who have the opposite role.
In each round, the two of you will together receive {{ Constants.endowment }}. The experiment is about how to divide this amount.
The game consists of two stages.
First the responder makes a choice between two options: RESPOND or ACCEPT. This choice is conditional on the computer's choice between INFORMED or UNINFORMED. That means the responder has to choose between RESPOND or ACCEPT twice: first, for the scenario when the computer chooses INFORMED and second, for the other scenario when the computer chooses UNINFORMED.
Then the computer uniformly randomly chooses among six options:
Based on the responder's and the computer's choices, it is decided what type of the game will be played in stage 2, RESPOND or ACCEPT.
Both players are informed about the type of the game G. In addition, if the computer chose INFORMED, they both know whether the choice of the game was made by the computer (when the computer chose RESPOND or ACCEPT) or by the responder (when the computer chose RESPONDER'S CHOICE).
The proposer makes an offer to the responder. This offer specifies how to divide the {{ Constants.endowment }} between the two players. The proposer has to choose among the following {{ Constants.offer_choices_count }} options:
If G=RESPOND, then while the proposer makes the offer, the responder can select which {{ Constants.offer_choices_count }} offers stated above to accept or reject. After the proposer has made the offer, it will be either accepted or rejected according to the responder's choices.
If G=ACCEPT, then the offer is accepted automatically.
If the offer is accepted, the players will receive a payoff accordingly
If the offer is rejected, both players will receive {{ Constants.payoff_if_rejected }}


I'm A Celebrity 'chlamydia fears' as koala invades the camp ahead of new series
Many of the koalas in Australia carry the sexually transmitted infection chlamydia and, while unlikely, it is possible for the disease to be transferred over to humans
by Rose Hill, https://www.mirror.co.uk/authors/rose-hill/A koala has crawled into the I'm A Celebrity camp for the first time in the show's 17-year history.
The animal, nicknamed Karl by crew, managed to creep into the jungle set and is "perfectly happy" sleeping above in the trees, the Daily Star has reported.
However his appearance may cause alarm to some as many of the Australian natives carry the sexually transmitted infection chlamydia.
While it is unlikely that the disease can be passed from koalas to humans, it is possible by urine.
Series producer Olly Nash told the paper that the celebs need not be alarmed by Karl and that he isn't dangerous - but conceded he was a bit smelly.
He said: "He’s around here somewhere, he’s on the side of the valley somewhere hanging around a ridge.
"It’s the first one I’ve ever heard of in the camp. They’re not dangerous but they are a bit smelly.”
This comes amid news that show bosses are on red alert and “closely monitoring” if they need to evacuate from the jungle site in the coming days after there were huge bushfires in the area.
At least three people are dead and thousands have been displaced by a weekend of bushfires in Australia.
On Sunday, the fire emergency's third day, more than 100 blazes were still burning across New South Wales and Queensland.
Prime Minister Scott Morrison said the military could be called upon to support the 1,300 firefighters working in the two states.
There have been fires closeby to the site in recent days at Lamington National Park, around 10 kilometres away, and yesterday a fire 2,200 hectares in size and “out of control” was raging at Mount Nardi National Park around 20 kilometres away.
An ITV Spokesman told the Mirror: “We are in constant contact with the NSW fire brigade and are closely monitoring the situation. We currently have no cause for concern. The health and safety of all our production crew and celebrities are of the utmost importance.”
*I'm A Celebrity returns on Sunday at 9pm on ITV


jdbctrace configuration
To apply your changes, a restart of the server is required.
Config
Trace
Filter
Thread
SQL