Update 2010-08-27: Comments indicated that what I did here is not the best solution. Like noted in my original post, a set would be better in this case. I eventually used set(r).issubset(set(l)). Marius also pointed out to set(r) <= set(l), but I like the issubset one more.
I wanted to check if every element of one list or tuple is part of another one using Python. A set has the issubset()-method, but I couldn't find anything build-in for a tuple. It was, however, rather quickly done:
>>> r = (1,2) >>> l = (3,4,1,5,2) >>> False not in [ e in l for e in r ] True >>> r = (1,9) >>> False not in [ e in l for e in r ] False
Why I'm posting this? I just found it cute code, somehow.
In Pylons v1.0 you can define global variables by adding them to the Globals-class. If you want a variable called spam and you want it to be globally available, your lib.app_globals.Globals-class would look like this:
class Globals(object):
def __init__(self, config):
self.cache = CacheManager(**parse_cache_config_options(config))
self.spam = False
To use it in a model-module for example, you have to import app_globals from the pylons module, like this:
from pylons import app_globals as g print g.spam
It took me a while to figure this out.. And I'm starting to like Pylons somehow.
The following AppleScript will:
- Prompt for a destination folder
- Ask for an album name, which will be a folder in destination folder
- Get currently selected photo(s) from Aperture
- Store the image files using the Image ID of Aperture
- Store some META information in a text file, with similar name as image file
The export format is PNG 1024x1024. I needed only that, so I hardcoded it.
Note dependencies: You need the renameFile, joinList and splitString functions found in earlier blog entries.
property defExportSetting : "PNG - Fit within 1024 x 1024"
on apertureExport(fldAlbum)
tell application "Aperture"
set imageSel to (get selection)
end tell
set out to {}
repeat with img in imageSel
tell application "Aperture"
set kwList to (get id of every keyword of img)
set imgDate to value of EXIF tag "ImageDate" of img
end tell
set imgId to id of img
set imgName to name of img
set imgTags to my joinList(kwList, ",")
copy "Name: " & imgName to end of out
copy "Tags: " & imgTags to end of out
copy "ApertureId: " & imgId to end of out
set dstFileMeta to (fldAlbum & imgId & ".meta") as string
end repeat
tell application "Aperture"
set dstFile to (export imageSel using export setting defExportSetting to fldAlbum)
end tell
set dstFile to my renameFile(dstFile, imgId)
copy "File: " & (POSIX path of dstFile) to end of out
tell application "Finder"
end tell
set fp to open for access file dstFileMeta with write permission
write (joinList of out given delimiter:return) to fp
close access fp
end apertureExport
on run
set dstFolder to (choose folder with prompt "Choose an destination") as text
set dlgAlbum to display dialog "Album name" buttons {"OK", "Cancel"} default answer "Picture pool"
set dstAlbum to (text returned of dlgAlbum) as text
tell application "Finder"
if not (exists alias (dstFolder & dstAlbum)) then
make new folder at alias (dstFolder) with properties {name:dstAlbum}
end if
end tell
set fldAlbum to (dstFolder & dstAlbum) as alias
apertureExport(fldAlbum)
end run
This script is safe, but I don't take any responsibility when it screws up you Aperture library. It shouldn't really, I coded it on my main library: hardcore!
Two small helper AppleScript functions for joining a list and splitting a string given delimiter. Sure, quite an easy task, but it involves setting a global delimiter. Bit like FS in shell. I hope this helps a few folks out there starting out with AppleScript.
to joinList(aList, delimiter)
set retVal to ""
set prevDelimiter to AppleScript's text item delimiters
set AppleScript's text item delimiters to delimiter
set retVal to aList as string
set AppleScript's text item delimiters to prevDelimiter
return retVal
end joinList
to splitString(aString, delimiter)
set retVal to {}
set prevDelimiter to AppleScript's text item delimiters
log delimiter
set AppleScript's text item delimiters to {delimiter}
set retVal to every text item of aString
set AppleScript's text item delimiters to prevDelimiter
return retVal
end splitString
Here a few lines showing how to use them:
set tmp to my splitString(oldAlias as text, ":") set imgTags to my joinList(kwList, ",")
Again, no comments! Enjoy!
The following AppleScript function renames a file. If you thought this to be a simple thing, try to write it without looking here below. I spend a lot time on this, I might not even use it, but here it is for other mortals wishing to lose weight exercising AppleScript:
to renameFile(oldAlias, newFileName) tell application "Finder" set f to item (oldAlias as text) tell f set ext to its name extension set nFn to (newFileName & "." & ext) set its name to nFn end tell end tell set tmp to my splitString(oldAlias as text, ":") set the last item of tmp to nFn return my joinList(tmp, ":") end renameFile
No comments in code, I do not want to spoil your fun!
I needed while writing an export script for Aperture. Here is how I used it after a photo was exported from Aperture:
tell application "Aperture" set dstFile to (export imageSel using export setting defExportSetting to fldAlbum) end tell set dstFile to my renameFile(dstFile, imgId)
MySQL Connector/Python is (or should be) compliant with the Python DB-API 2.0 specification. This means that you can use DBUtils' PooledDB module to implement database connection pooling.
Here below you'll find an example which will output the connection ID of each connection requested through the pooling mechanism.
from DBUtils.PooledDB import PooledDB
import mysql.connector
def main():
pool_size = 3
pool = PooledDB(mysql.connector, pool_size,
database='test', user='root', host='127.0.0.1')
cnx = [None,] * pool_size
for i in xrange(0,pool_size):
cnx[i] = pool.connection()
cur = cnx[i].cursor()
cur.execute("SELECT CONNECTION_ID()")
print "Cnx %d has ID %d" % (i+1,cur.fetchone()[0])
cur.close()
for c in cnx:
c.close()
The output will be something like this:
Cnx 1 has ID 42 Cnx 2 has ID 41 Cnx 3 has ID 40
This post explains how to disable Arbitration when using MySQL Cluster. It gives a case where this could be useful.
First, a piece of advice: you do not want to run MySQL Cluster with arbitration disabled. But if you must, e.g. because of an oversight in your implementation, you can.
Arbitration is very important in MySQL Cluster. It makes sure you don't end up with a Split Brain situation: 2 halves working independently, continuing changing data, making it impossible for them to work together later on.
However, Arbitration comes with a price: you need an extra machine. "Sure, what's the big deal?". It's not that easy when you lack the money, or more problematic, when you lack the real-estate in your rack.
Everyone running MySQL Cluster should know that you should not run the ndb_mgmd on the same machines on which the data node processes, ndbd or ndbmtd, are running. The Management Nodes need to be on a separate machine so it can act as an Arbitrator.
Here's an example why: If you have two hosts A and B and both are running a management and data node process. Host A's ndb_mgmd is currently the Arbitrator. Now unplug host A *BANG*: one data node and the arbitrator down. The other data node on Host B notices this, and tries to figure out if it can continue. So it checks if it can reach the Arbitrator: but it's gone as well! So, the data node on host B goes faithfully down. This all happens in a few seconds, there is no time to elect a new Arbitrator. "Cluster's dead, Jim".
What if you can't get a 3rd machine? There's an option for that.. Data nodes can be configured with setting the Arbitration-option to WaitExternal. This means you will have to develop your own arbitration application or script. How cool is that? Well, it might be cool, but it's a pain in the butt.
[ndbd default] Arbitration = WaitExternal ArbitrationTimeout = 3
What happens with our 2 host setup with above changes: When Host A, which has the Arbitrator, goes down, the data node on Host B will wait for 3 seconds, i.e. ArbitrationTimeout. It will block all incoming transactions, refusing changes. An application, the External Arbitrator, running on Host B (actually on all hosts running MySQL Cluster proceses) has 3 seconds to figure out whether Host B can continue running it's ndbd process(es), or not. In this case, it should find out that Host A is down and that Host B should continue keeping the data available.
"Ah, easy! Problem solved!", you might joyfully exclaim. No, it isn't. It's more complicated than that. What happens when Host A doesn't go down, but both hosts can't see each other due to a network issue between them? Both External Arbitrators would figure out that they need to continue: you end up again with a split brain. So you still need someway to handle that.
At this point, I would like to say: "Goodluck!". Every situation is going to be different. Everyone will have his own External Arbitrator requirements or ways to check if a host or blade chassis is up or not. It's a great option, and it puts you more in control of your MySQL Cluster, but it adds a lot of complexity.
So, my advice: revise and correct your MySQL Cluster setup when you think you need to disable Arbitration.
