{% extends "_post.html" %}
{% hyde
title: "Django Advice"
snip: "Some useful things I've learned."
created: 2011-06-30 08:30:00
flattr: true
%}
{% block article %}
For the past year and a half or so I've been working full-time at [Dumbwaiter
Design][] doing [Django][] development. I've picked up a bunch of useful tricks along
the way that help me work, and I figured I'd share them.
I'm sure there are better ways to do some of the things that I mention. If you know
of any feel free to hit me up on [Twitter][] and let me know.
Also: this entry was written over several months, so if there are inconsistencies let
me know and I'll try to fix them.
[Dumbwaiter Design]: http://dwaiter.com/
[Django]: {{links.django}}
[Twitter]: http://twitter.com/stevelosh
[TOC]
Vagrant
-------
I used to develop Django sites by running them on my OS X laptop locally and
deploying to a Linode VPS. I had a whole section of this post written up about
tricks and tips for working with that setup.
Then I found [Vagrant][].
I just deleted the entire section of this post I wrote.
Vagrant gives you a better way of working. You need to use it.
[Vagrant]: http://vagrantup.com/
### Why Vagrant?
If you haven't used it before, Vagrant is basically a tool for managing
[VirtualBox][] VMs. It makes it easy to start, pause, and resume VMs. Instead of
installing Django in a virtualenv and developing against that, you run a VM which
runs your site and develop against that.
This may not sound like much, but it's kind of a big deal. The critical difference
is that you can now develop against the same setup that you'll be using in
production.
This cuts out a huge amount of pain that stems from OS differences. Here are a few
examples off the top of my head:
* URLField and MacPorts Python 2.5 on OS X. There's a [bug][] where using
verify\_exists will crash your site every time you save a model, unless you set
a particular environment variable with no debug information. Yeah, I spent
a couple of hours tracking that one down at work. Awesome.
* Installing PIL on OS X is no picnic. [homebrew][] makes things better, if you use it,
so this one isn't a huge deal.
* Every time you update Python in-place on your local machines, ALL of your
virtualenvs break because the Python binaries inside are linked against global
Python library files. Have fun recreating them. I hope you froze your
`requirements.txt` files before you updated.
Using Vagrant and VMs means you can just worry about ONE operating system and its
quirks. It saves you a ton of time.
Aside from that, there's another benefit to using Vagrant: it strongly encourages you
to learn and use an automated provisioning system. Support for Puppet and Chef is
built in. I chose Puppet, but if you prefer Chef that's cool too.
You can also use other tools like Fabric or some simple scripts, but I'd strongly
recommend giving Puppet or Chef a fair shot. It's a lot to learn, but they're both
widely tested and very powerful.
Because you're developing against a VM and deploying to a VM, you can reuse 90% of
the provisioning code across the two.
When I make a new site, I do the following to initialize a new Vagrant VM:
1. `vagrant up` (which runs Puppet to initialize the VM)
2. `fab dev bootstrap`
When I'm ready to go live, I do the following:
1. Buy a Linode VPS.
2. Run Puppet to initialize the VPS.
3. Enter the Linode info in my fabfile.
4. `fab prod bootstrap`
No more screwing around with different paths, different versions of Nginx, different
versions of Python. When I'm developing something I can be pretty confident it will
"just work" in production without any major surprises.
[VirtualBox]: http://www.virtualbox.org/
[bug]: https://trac.macports.org/ticket/24421
[homebrew]: http://mxcl.github.com/homebrew/
### Using Fabric to Stay Fast and Automate Everything
One of the problems with this setup is that I can't just run `python manage.py
whatever` any more because I need it to run on the VM.
To get around this I've created many simple [Fabric][] tasks to automate the common
things I need to do. Fabric is an awesome little Python utility for scripting tasks
(like deployments). We use it constantly at Dumbwaiter. Here are a few examples
from our fabfiles.
[Fabric]: http://fabfile.org/
This first set is for running abitrary commands easily.
`cmd` and `vcmd` will `cd` into the site directory on the VM and run a command of my
choosing. `vcmd` will prefix the command with the path to the virtualenv's `bin`
directory, so I can do something like `fab dev vcmd`, `pip install markdown`.
The `sdo` commands do the same thing, but `sudo`'ed.
:::python
def cmd(cmd=""):
'''Run a command in the site directory. Usable from other commands or the CLI.'''
require('site_path')
if not cmd:
sys.stdout.write(_cyan("Command to run: "))
cmd = raw_input().strip()
if cmd:
with cd(env.site_path):
run(cmd)
def sdo(cmd=""):
'''Sudo a command in the site directory. Usable from other commands or the CLI.'''
require('site_path')
if not cmd:
sys.stdout.write(_cyan("Command to run: sudo "))
cmd = raw_input().strip()
if cmd:
with cd(env.site_path):
sudo(cmd)
def vcmd(cmd=""):
'''Run a virtualenv-based command in the site directory. Usable from other commands or the CLI.'''
require('site_path')
require('venv_path')
if not cmd:
sys.stdout.write(_cyan("Command to run: %s/bin/" % env.venv_path.rstrip('/')))
cmd = raw_input().strip()
if cmd:
with cd(env.site_path):
run(env.venv_path.rstrip('/') + '/bin/' + cmd)
def vsdo(cmd=""):
'''Sudo a virtualenv-based command in the site directory. Usable from other commands or the CLI.'''
require('site_path')
require('venv_path')
if not cmd:
sys.stdout.write(_cyan("Command to run: sudo %s/bin/" % env.venv_path.rstrip('/')))
cmd = raw_input().strip()
if cmd:
with cd(env.site_path):
sudo(env.venv_path.rstrip('/') + '/bin/' + cmd)
This next set is just some common commands that I need to run often.
:::python
def syncdb():
'''Run syncdb.'''
require('site_path')
require('venv_path')
with cd(env.site_path):
run(_python('manage.py syncdb --noinput'))
def collectstatic():
'''Collect static media.'''
require('site_path')
require('venv_path')
with cd(env.site_path):
sudo(_python('manage.py collectstatic --noinput'))
def rebuild_index():
'''Rebuild the search index.'''
require('site_path')
require('venv_path')
require('process_owner')
with cd(env.site_path):
sudo(_python('manage.py rebuild_index'))
sudo('chown -R %s .xapian' % env.process_owner)
def update_index():
'''Update the search index.'''
require('site_path')
require('venv_path')
require('process_owner')
with cd(env.site_path):
sudo(_python('manage.py update_index'))
sudo('chown -R %s .xapian' % env.process_owner)
We also use Fabric to automate some of the more complex things we need to do.
This task `curl`'s the site's home page to make sure we haven't completely borked
things. We use it in lots of other tasks as a sanity check.
:::python
def check():
'''Check that the home page of the site returns an HTTP 200.'''
require('site_url')
print('Checking site status...')
if not '200 OK' in local('curl --silent -I "%s"' % env.site_url, capture=True):
_sad()
else:
_happy()
The `_happy` and `_sad` functions just print out some simple messages to get our
attention:
:::python
from fabric.colors import red, green
def _happy():
print(green('\nLooks good from here!\n'))
def _sad():
print(red(r'''
___ ___
/ /\ /__/\
/ /::\ \ \:\
/ /:/\:\ \__\:\
/ /:/ \:\ ___ / /::\
/__/:/ \__\:\ /__/\ /:/\:\
\ \:\ / /:/ \ \:\/:/__\/
\ \:\ /:/ \ \::/
\ \:\/:/ \ \:\
\ \::/ \ \:\
\__\/ \__\/
___ ___ ___ ___
/__/\ / /\ / /\ / /\ ___
\ \:\ / /::\ / /:/_ / /:/_ /__/\
\ \:\ / /:/\:\ / /:/ /\ / /:/ /\ \ \:\
_____\__\:\ / /:/ \:\ / /:/ /:/_ / /:/ /::\ \ \:\
/__/::::::::\ /__/:/ \__\:\ /__/:/ /:/ /\ /__/:/ /:/\:\ \ \:\
\ \:\~~\~~\/ \ \:\ / /:/ \ \:\/:/ /:/ \ \:\/:/~/:/ \ \:\
\ \:\ ~~~ \ \:\ /:/ \ \::/ /:/ \ \::/ /:/ \__\/
\ \:\ \ \:\/:/ \ \:\/:/ \__\/ /:/ __
\ \:\ \ \::/ \ \::/ /__/:/ /__/\
\__\/ \__\/ \__\/ \__\/ \__\/
Something seems to have gone wrong!
You should probably take a look at that.

It's the "NUKE IT FROM ORBIT!!" option.
:::python
def KILL_IT_WITH_FIRE(app):
require('site_path')
require('venv_path')
with cd(env.site_path):
# Generate and download the reset SQL.
sudo(_python('manage.py sqlreset %s > reset.orig.sql' % app))
get('reset.orig.sql')
with open('reset.sql', 'w') as f:
with open('reset.orig.sql') as orig:
# Step through the first chunk of the file (the "drop" part).
line = orig.readline()
while not line.startswith('CREATE'):
if 'CONSTRAINT' in line:
# Don't write out CONSTRAINT lines.
# They're a problem when you change db_colum names.
pass
elif 'DROP TABLE' in line:
# Cascade drops.
# Hence with "with fire" part of this task's name.
line = line[:-2] + ' CASCADE;\n'
f.write(line)
else:
# Write other lines through untoched.
f.write(line)
line = orig.readline()
# Write out the rest of the file untouched.
f.write(line)
f.write(orig.read())
# Upload the processed SQL file.
put('reset.sql', os.path.join(env.site_path, 'reset.ready.sql'), use_sudo=True)
with cd(env.site_path):
# Use the SQL to reset the app, and fake a migration.
run(_python('manage.py dbshell < reset.ready.sql'))
sudo(_python('manage.py migrate --fake --delete-ghost-migrations ' + app))
This task uses Mercurial's local tags to add a `production` or `staging` tag in your local
repository, so you can easy see where the production/staging servers are at
compared to your local repo.
:::python
def retag():
'''Check which revision the site is at and update the local tag.
Useful if someone else has deployed (which makes your production/staging local
tag incorrect.
'''
require('site_path', provided_by=['prod', 'stag'])
require('env_name', provided_by=['prod', 'stag'])
with cd(env.site_path):
current = run('hg id --rev . --quiet').strip(' \n+')
local('hg tag --local --force %s --rev %s' % (env.env_name, current))
This task tails the Gunicorn logs on the server so you can quickly find out what's
happening when things blow up.
:::python
def tailgun(follow=''):
"""Tail the Gunicorn log file."""
require('site_path')
with cd(env.site_path):
if follow:
run('tail -f .gunicorn.log')
else:
run('tail .gunicorn.log')
We've got a lot of other tasks but they're pretty specific to our setup.
Wrangling Databases with South
------------------------------
If you're not using [South][], you need to start. Now.
No, really, I'll wait.  It's far more important than this blog post.
[South]: http://south.aeracode.org/
[Southtut]: http://south.aeracode.org/docs/tutorial/index.html
### Useful Fabric Tasks
South is awesome but its commands are very long-winded. Here's the set of fabric
tasks I use to save quite a bit of typing:
:::python
def migrate(args=''):
'''Run any needed migrations.'''
require('site_path')
require('venv_path')
with cd(env.site_path):
sudo(_python('manage.py migrate ' + args))
def migrate_fake(args=''):
'''Run any needed migrations with --fake.'''
require('site_path')
require('venv_path')
with cd(env.site_path):
sudo(_python('manage.py migrate --fake ' + args))
def migrate_reset(args=''):
'''Run any needed migrations with --fake. No, seriously.'''
require('site_path')
require('venv_path')
with cd(env.site_path):
sudo(_python('manage.py migrate --fake --delete-ghost-migrations ' + args))
Remember that running a migration without specifying an app will migrate everything,
so a simple `fab dev migrate` will do the trick.
Watching for Changes
---------------------
When developing locally you'll want to make a change to your code and have the server
reload that code automatically. The Django development server does this, and we can
hack it into our Vagrant/Gunicorn setup too.
First, add a `monitor.py` file at the root of your project (I believe I found this
code [here][monitor], but I may be wrong):
:::python
import os
import sys
import time
import signal
import threading
import atexit
import Queue
_interval = 1.0
_times = {}
_files = []
_running = False
_queue = Queue.Queue()
_lock = threading.Lock()
def _restart(path):
_queue.put(True)
prefix = 'monitor (pid=%d):' % os.getpid()
print >> sys.stderr, '%s Change detected to \'%s\'.' % (prefix, path)
print >> sys.stderr, '%s Triggering process restart.' % prefix
os.kill(os.getpid(), signal.SIGINT)
def _modified(path):
try:
# If path doesn't denote a file and were previously
# tracking it, then it has been removed or the file type
# has changed so force a restart. If not previously
# tracking the file then we can ignore it as probably
# pseudo reference such as when file extracted from a
# collection of modules contained in a zip file.
if not os.path.isfile(path):
return path in _times
# Check for when file last modified.
mtime = os.stat(path).st_mtime
if path not in _times:
_times[path] = mtime
# Force restart when modification time has changed, even
# if time now older, as that could indicate older file
# has been restored.
if mtime != _times[path]:
return True
except:
# If any exception occured, likely that file has been
# been removed just before stat(), so force a restart.
return True
return False
def _monitor():
while 1:
# Check modification times on all files in sys.modules.
for module in sys.modules.values():
if not hasattr(module, '__file__'):
continue
path = getattr(module, '__file__')
if not path:
continue
if os.path.splitext(path)[1] in ['.pyc', '.pyo', '.pyd']:
path = path[:-1]
if _modified(path):
return _restart(path)
# Check modification times on files which have
# specifically been registered for monitoring.
for path in _files:
if _modified(path):
return _restart(path)
# Go to sleep for specified interval.
try:
return _queue.get(timeout=_interval)
except:
pass
_thread = threading.Thread(target=_monitor)
_thread.setDaemon(True)
def _exiting():
try:
_queue.put(True)
except:
pass
_thread.join()
atexit.register(_exiting)
def track(path):
if not path in _files:
_files.append(path)
def start(interval=1.0):
global _interval
if interval < _interval:
_interval = interval
global _running
_lock.acquire()
if not _running:
prefix = 'monitor (pid=%d):' % os.getpid()
print >> sys.stderr, '%s Starting change monitor.' % prefix
_running = True
_thread.start()
_lock.release()
Next add a `post_fork` hook to your Gunicorn config file that uses the monitor to
watch for changes:
:::python
def post_fork(server, worker):
import monitor
import local_settings
if local_settings.DEBUG:
server.log.info("Starting change monitor.")
monitor.start(interval=1.0)
Now the Gunicorn server will automatically restart whenever code is changed. Use
whatever method for determining debug status that you like. We use
`local_settings.py` files which all have `DEBUG` variables, so that works for us.
It will *not* restart when you add new code (e.g. when you install a new app), so
you'll need to handle that manually with `fab dev restart`, but that's not too bad!
[monitor]: http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode
### Using the Werkzeug Debugger with Gunicorn
The final piece of the puzzle is being able to use the fantastic [Werkzeug
Debugger][debug] while running on the development VM with Gunicorn.
To do this, create a `debug_wsgi.py` file at the root of your project:
:::python
import os
import sys
import site
parent = os.path.dirname
site_dir = parent(os.path.abspath(__file__))
project_dir = parent(parent(os.path.abspath(__file__)))
sys.path.insert(0, project_dir)
sys.path.insert(0, site_dir)
site.addsitedir('VIRTUALENV_SITE_PACKAGES')
from django.core.management import setup_environ
import settings
setup_environ(settings)
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
from werkzeug.debug import DebuggedApplication
application = DebuggedApplication(application, evalex=True)
def null_technical_500_response(request, exc_type, exc_value, tb):
raise exc_type, exc_value, tb
from django.views import debug
debug.technical_500_response = null_technical_500_response
Have Gunicorn use this file to run your development server with `gunicorn
debug_wsgi:application`.
Make sure to replace `'VIRTUALENV_SITE_PACKAGES'` with the _full_ path to your
virtualenv's `site_packages` directory. You might want to make this a setting in
a machine-specific settings file.
[debug]: http://werkzeug.pocoo.org/docs/debug/
### Pulling Uploads
Once you give a client access to a site they'll probably be uploading images (through
Django's built-in file uploading features or with [django-filebrowser][]).
When you're making changes locally it's often useful to have these uploaded files on
your local VM, otherwise you end up with a bunch of broken images.
Here's a simple Fabric task that will pull down all the uploads from the server:
:::python
def pull_uploads():
'''Copy the uploads from the site to your local machine.'''
require('uploads_path')
sudo('chmod -R a+r "%s"' % env.uploads_path)
rsync_command = r"""rsync -av -e 'ssh -p %s' %s@%s:%s %s""" % (
env.port,
env.user, env.host,
env.uploads_path.rstrip('/') + '/',
'media/uploads'
)
print local(rsync_command, capture=False)
You might be wondering about the line that strips `/` characters and then adds them
back in. `rsync` does different things depending on whether you end a path with
a `/`, so this is actually pretty important.
In your host task you'll need to set the `uploads_path` variable to something like
this:
:::python
import os
env.site_path = os.path.join('var', 'www', 'myproject')
env.uploads_path = os.path.join(env.site_path, 'media', 'uploads')
Now you can run `fab production pull_uploads` to pull down all the files people have
uploaded to the production server.
[django-filebrowser]: http://code.google.com/p/django-filebrowser/
### Preventing Accidents
Deploying to test and staging servers should be quick and easy. Deploying to
production servers should be harder to prevent people from accidentally doing it.
I've created a little function that I call before deploying to production servers.
It forces me to type in random words from the system word list before proceeding to
make sure I *really* know what I'm doing:
:::python
import os, random
from fabric.api import *
from fabric.operations import prompt
from fabric.utils import abort
WORDLIST_PATHS = [os.path.join('/', 'usr', 'share', 'dict', 'words')]
DEFAULT_MESSAGE = "Are you sure you want to do this?"
WORD_PROMPT = ' [%d/%d] Type "%s" to continue (^C quits): '
def prevent_horrible_accidents(msg=DEFAULT_MESSAGE, horror_rating=1):
"""Prompt the user to enter random words to prevent doing something stupid."""
valid_wordlist_paths = [wp for wp in WORDLIST_PATHS if os.path.exists(wp)]
if not valid_wordlist_paths:
abort('No wordlists found!')
with open(valid_wordlist_paths[0]) as wordlist_file:
words = wordlist_file.readlines()
print msg
for i in range(int(horror_rating)):
word = words[random.randint(0, len(words))].strip()
p_msg = WORD_PROMPT % (i+1, horror_rating, word)
answer = prompt(p_msg, validate=r'^%s$' % word)
You may need to adjust `WORDLIST_PATHS` if you're not on OS X.
Working with Third-Party Apps
-----------------------------
One of the best parts about working with Django is that many problems have already
been solved and the solutions have been released as open-source applications.
We use quite a few open-source apps, and there are a couple of tricks I've learned to
make working with them easier.
### Installing Apps from Repositories
If I'm going to use an open-source Django app in a project I'll almost always install
it as an editable repository on the VM with `pip install -e`.
Others may disagree with me on this, but I think it's the best way to work.
Often I'll find a bug that I think may be in one of the third-party apps I'm using.
Installing the apps as repositories makes it easy to read their source and figure out
if the bug is really in the app.
If the bug *is* in the third-party app having the app installed as a repository makes
it simple to fix the bug, fork the project on BitBucket or GitHub, send a pull
request, and get back to work.
### Mirroring Repositories
One problem we've run into at Dumbwaiter is that the repos for third-party apps we
use are scattered across GitHub, BitBucket, Google Code, and other servers. If any
one of these services goes down we're stuck waiting for it to come back up.
A while ago I took half a day and consolidated all of these repos onto one of the
servers that we control. The basic process went like this:
* Use [hg-git][] and [hgsubversion][] to convert the git and SVN repos to Mercurial
repos.
* Set up a master `mirror` Mercurial repo with all the app repos as subrepos.
* Push the master repo and all the subrepos up to one of our Linodes.
Now we can use `-e ssh://hg@OUR_LINODE/mirror/APP@REV_THAT_WORKS#egg=APP` in our
`requirements.txt` files to install apps from our mirror. When we want to update our
dependencies we can simply pull from the upstream repos and commit in the mirror
repo.
If our mirror goes down it's not a big deal, because we have far bigger problems to
worry about than new projects.
I wrote a few scripts to automate updating apps and such, but they're extremely hacky
so I don't want to post them here. Take half a day and write your own set -- it's
definitely worth it to have your own mirror of your specific dependencies.
[hg-git]: http://hg-git.github.com/
[hgsubversion]: https://bitbucket.org/durin42/hgsubversion/wiki/Home
### Using BCVI to Edit Files
I said that when I find a bug that I think is in a third-party app I'll poke around
with the app and try to figure it out.
Luckily [BCVI][] exists. It's a utility that opens a "back channel" to your local
machine when you SSH and lets you run `vi FILE` to open that file in
Vim/MacVim/GVim/etc on your *local* machine. When you save the file it uploads it
back to the server automatically for you.
It can be a bit tricky to set up, but it's worth it. Trust me.
[BCVI]: http://sshmenu.sourceforge.net/articles/bcvi/
Improving the Admin Interface
-----------------------------
I'm going to be honest: Django's admin interface is the main reason I'm still using
it. Other frameworks like [Flask][] are great, but Django's admin saves me
*ridiculous* amounts of time when I'm making simple CRUD sites for clients.
That said, the Django admin isn't the prettiest thing around, but we can give it
a facelift.
[Flask]: http://flask.pocoo.org/
### Enter Grappelli
[Grappelli][] is a Django app that reskins the admin interface beautifully. It also
adds some functionality like drag-and-drop reordering of inlines, and allows you to
customize the dashboard to your liking. *Every* Django site I work on uses Grappelli
-- it's just that good.
The downside of Grappelli is that it changes quite a lot and breaks backwards
compatibility at the drop of a hat.
If you're going to use Grappelli you *must* freeze your requirements.txt files and
work with a single version at a time. Trying to always work from the trunk will make
you drink.
[Grappelli]: http://django-grappelli.readthedocs.org/
### An Ugly Hack to Show Usable Foreign Key Fields
A limitation of both Grappelli and the stock Django admin is that it seems like you
can't easily show fields from related models in the admin list view.
For example, if you're new to Django you might expect this to work:
:::python
class BlogEntryAdmin(admin.ModelAdmin):
list_display = ('title', 'author__name')
Unfortunately Django chokes on the `author__name` lookup. You can *display* the name
without too much fuss:
:::python
class BlogEntryAdmin(admin.ModelAdmin):
list_display = ('title', 'author_name')
def author_name(self, obj):
return obj.name
That will display the name just fine. However, it won't be a fully-fledged column in
the Django admin because you can't sort on it.
It may seem like this is the end -- if it could be a fully-functional field, why
wouldn't Django just let you use `author__name`? Luckily we can add one more line to
fix the problem:
:::python
class BlogEntryAdmin(admin.ModelAdmin):
list_display = ('title', 'author_name')
def author_name(self, obj):
return obj.name
author_name.admin_order_field = 'author__name'
Now the author name has all the functionality of a real `list_display` entry.
Using Django-Annoying
---------------------
If you haven't heard of [django-annoying][] you should definitely check it out.
My two personal favorites from the package are a pair of decorators that help make
your views much, much cleaner.
[django-annoying]: https://bitbucket.org/offline/django-annoying/wiki/Home
### The render\_to Decorator
The decorator is called `render_to` and it eliminates the ugly `render_to_response`
calls that Django normally forces you to use in every single view.
Normally you'd use something like this:
:::python
def videos(request):
videos = Video.objects.all()
return render_to_response('video_list.html', { 'videos': videos },
context_instance=RequestContext(request))
With `render_to` your view gets much cleaner:
:::python
@render_to('video_list.html')
def videos(request):
videos = Video.objects.all()
return { 'videos': videos }
Less typing `context_instance=...` over and over, and less syntax to remember.
Yes, I know about Django 1.3's `render` shortcut. You have to type `request` every
single time with `render`, so the `render_to` decorator still wins.
### The ajax\_request Decorator
The `ajax_request` decorator is like `render_to` for AJAX requests. You simply
return a Python dictionary from your view and the decorator handles the JSON encoding
and such:
:::python
@ajax_request
def ajax_get_entries(request):
blog_entries = BlogEntry.objects.all()
return { 'entries': [(entry.title, entry.get_absolute_url())
for entry in entries]}
Templating Tricks
-----------------
I'm not a frontend developer, but I've done my share of HTML hacking at Dumbwaiter.
Here are a few of the tricks I've learned.
### Null Checks and Fallbacks
A common pattern I see in Django templates looks like this:
:::django
{% templatetag openblock %} if business.title {% templatetag closeblock %}
{% templatetag openvariable %} business.title {% templatetag closevariable %}
{% templatetag openblock %} else {% templatetag closeblock %}
{% templatetag openvariable %} business.short_title {% templatetag closevariable %}
{% templatetag openblock %} endif {% templatetag closeblock %}
Here's a simpler way to do that:
:::django
{% templatetag openblock %} firstof business.title business.short_title {% templatetag closeblock %}
`firstof` will return the first non-Falsy item in its arguments.
### Manipulating Query Strings
Query strings are normally not a big deal, but every once in a while you'll have
a model listing page where you need to filter by category, and number of spaces, and
tags, etc all at once.
If you're trying to manage GET queries manually it can get pretty hairy very fast.
[This Django snippet][qstring] makes working with query strings in templates
a breeze.
[qstring]: http://djangosnippets.org/snippets/2237/
### Satisfying Your Designer with Typogrify
If you haven't heard of [Typogrify][] you should take a look at it. It makes it easy
to add all the typographic goodness your designers are looking for.
[Typogrify]: http://code.google.com/p/typogrify/
The Flat Page Trainwreck
------------------------
Creating a site for a client is very different than creating a site for yourself.
For pretty much every client we've dealt with we've heard: "can't we just create
a new page at /drink-special/ for this special deal we're running?"
Having clients go through you to make new pages is simply too much overhead. We
needed a way to let clients create new pages (like `/drink-special/`) on the fly,
without our intervention.
Django has a "flatpages" app that solves this problem. Kind of.
When using flat pages clients need to do two things that are often too much for
non-technical people:
* Manage URLs manually.
* Write all content as raw HTML in a single text field.
We've tried a lot of Django CMS apps at Dumbwaiter, and none of them made us happy.
They all seemed to have some or all of the following problems:
* They take over your site and make you write a "Django-WhateverCMS site" instead of
a "Django site".
* They're extremely feature-rich and complicated with features like
internationalization, redirects, versions, and many others. This is great if you
need the flexibility, but bad if your clients just need to create a couple of
pages.

I finally got fed up and wrote my own Django CMS app: [Stoat][]. Stoat is designed
to be sleek, with only the features that our clients need.
It's not officially version 1.0 yet, but we're using it for a few clients and it's
working well. Check it out if you're looking for a more lightweight CMS app.
[Stoat]: http://stoat.rtfd.org/
Editing with Vim
----------------
I [use Vim][vimpost] to edit everything. Naturally I've found a bunch of plugins,
mappings and other tricks that make it even better when working on Django projects.
[vimpost]: /blog/2010/09/coming-home-to-vim/
### Vim for Django
There are a lot of ways to make Vim work with Django. I won't go into all of them in
this post, but a good place to start is [this Django wiki page][vimdjango].
[vimdjango]: https://code.djangoproject.com/wiki/UsingVimWithDjango
### Filetype Mappings
Most files in a Django project have one of two extensions: `.py` and `.html`.
Unfortunately these extensions aren't unique to Django, so Vim doesn't automatically
set the correct `filetype` when you open one.
I've added a few mappings to my `.vimrc` to make it quick and easy to set the correct
`filetype`:
:::vim
nnoremap _dt :set ft=htmldjango
nnoremap _pd :set ft=python.django
I also have a few autocommands that set the filetype for me when I'm editing a file
whose name "sounds like" a Django file:
:::vim
au BufNewFile,BufRead admin.py setlocal filetype=python.django
au BufNewFile,BufRead urls.py setlocal filetype=python.django
au BufNewFile,BufRead models.py setlocal filetype=python.django
au BufNewFile,BufRead views.py setlocal filetype=python.django
au BufNewFile,BufRead settings.py setlocal filetype=python.django
au BufNewFile,BufRead forms.py setlocal filetype=python.django
### Python Sanity Checking
Lets be honest here: it takes a lot of work to turn Vim into an "IDE", and even then
it doesn't reach the level of something like Eclipse for Java. Anyone who claims it
has the same levels of integration and functionality is simply lying.

**I am a programmer, not an IDE operator.**
I know Python.
I know Django.
I don't need to hit Cmd+Space twice for every line of code I write.
When someone asks me "how do you run your site" I do **not** answer: "click the green
triangle in Eclipse".
However, I am human.  To help me with those problems I've turned to [Syntastic][] and Kevin
Watters' [Pyflakes fork][] for Vim.
Syntastic is a Vim plugin that adds on-the-fly syntax-checking for many different
file formats. If you have Pyflakes installed it will automatically show you errors
in your code.
Pyflakes doesn't have IDE-level integration with your code. It doesn't check that
whatever libraries you `import` actually exist. It simply checks that your files are
probably-valid Python, and tells you when they're not.
This is enough for me.  The less-stupid,
more-subtle mistakes slip by it, but to be fair many of them would have slipped by an
"IDE" as well.
[Pyflakes fork]: https://github.com/kevinw/pyflakes
[Syntastic]: http://www.vim.org/scripts/script.php?script_id=2736
### Javascript Sanity Checking and Folding
Syntastic also supports Javascript if you have Javascript Lint installed (`brew
install jsl` on OS X). It's not perfect but it *will* catch things like using
trailing commas in object literals.
Some people like using CTags to get an overview of their code. I take a more
low-tech approach and am in love with code folding. When I fold my code
I automatically get an overview of everything in each file.
By default Vim doesn't fold Javascript files, but you can add some basic, perfectly
serviceable folding with these two lines in your .vimrc:
:::vim
au FileType javascript setlocal foldmethod=marker
au FileType javascript setlocal foldmarker={,}
### Django Autocommands
I *rarely* work with raw HTML files any more. Whenever I open a file ending in
`.html` it's almost always a Django template (or a [Jinja][] template, which has
a very similar syntax). I've added an autocommand to automatically set the correct
filetype whenever I open a `.html` file:
[Jinja]: http://jinja.pocoo.org/
:::vim
au BufNewFile,BufRead *.html setlocal filetype=htmldjango
I also have some autocommands that tweak how a few specific files are handled:
:::vim
au BufNewFile,BufRead urls.py setlocal nowrap
au BufNewFile,BufRead settings.py normal! zR
au BufNewFile,BufRead dashboard.py normal! zR
This automatically unfolds `urls.py`, `dashboard.py` and `settings.py` (I prefer
seeing those unfolded) and unsets line wrapping for `urls.py` (lines in a `urls.py`
file can get long and are hard to read when wrapped).
Conclusion
----------
I hope that this longer-than-expected blog entry has given you at least one or two
things to think about.
I've learned a lot while working with Django for Dumbwaiter every day, but I'm sure
there's still a lot I've missed. If you see something I could be doing better please
let me know!
{% endblock %}


| htmlview - A htmlview gadget handle |
|
Returns the event URL of a htmlview gadget.
The event URL is the URL of the last link that was clicked when a htmlview's style is set to 2 (NONAVIGATE). This allows you to then detect what link has been clicked. See also: CreateHTMLView, HTMLViewGo, HTMLViewBack, HTMLViewForward, HtmlViewCurrentURL, HtmlViewStatus, HtmlViewRun. |
|
; A Basic Blitz Web Browser!
win=CreateWindow("Basic Blitz Web Browser",100,100,500,500,0,35) ; Create htmlview gadget - for HTMLViewEventURL to return a string, we need to set style to 2 (NONAVIGATE) html = CreateHtmlView(0,0,500,480,win,2) ; Ensure the HTML view will stretch to meet the size of the window when it is resized SetGadgetLayout html,1,1,1,1 ; Go to URL HtmlViewGo html,"http:\\www.blitzbasic.com" ; Create label gadget that will display event url label=CreateLabel("",0,480,500,20,win,3) ; Ensure that the label stays at the bottom of the window SetGadgetLayout label,1,1,0,1 Repeat id = WaitEvent() If id=$803 Then Exit ; If gadget event occurs... If id=$401 And EventSource()=html url$=HtmlViewEventURL$(html) Select EventData() Case 0 ;page load event ; Set label's text to that of the htmlview event url SetGadgetText label,"loaded "+url$ Case 1 ;user navigate event SetGadgetText label,"navigating to "+url$ HtmlViewGo html,url$ End Select EndIf Forever |


|
What do you think of the Xbox, Playstation 3, PSP...? We are building a team of members to help us understand the gamer's opinion on new products, technology, games, consoles, gadgets, computers and other things you use. The team is called the Team Warfare League Panel. All we ask you to do is participate in an online survey about once a month. When you do, we may reward you with cash, gift certificates, other prizes and information. Please know that all of the information you provide is always kept confidential. Join the Team today! If you have any further questions, please visit the F.A.Q. and Privacy Policy Section on our new panel website - www.teamwarfareleaguepanel.com. Privacy And Confidentiality Team Warfare has partnered with Socratic Technologies, Inc. a full-service market research firm that values your privacy. All of your responses will be kept confidential and only reported in the aggregate. Your personal information has not, and will not be sold or traded to any companies. For more information about Socratic's privacy policy, please visit www.sotech.com/main/eval.asp?PID=106. If you have questions about the survey, please contact the Member Services Manager, Ryan Hill, at<EMAIL_ADDRESS>and reference project 557-001. Ryan can also be reached at 1-800-5-SOCRATIC (1-800-576-2728), or 001-415-430-2200 outside USA. If you would like to be removed from our contact list, please reply to this email and type "Remove - Team Warfare" in the subject line, or call 1-800-5-SOCRATIC (1-800-576-2728) or 001-415-430-2200 outside USA. You may also request your removal by writing to: Socratic Technologies, Inc., 2505 Mariposa Street, San Francisco, CA 94110 USA. Socratic Technologies, Inc. is a member of the Interactive Marketing Research Organization (IMRO) and we subscribe to the privacy policies and code of research ethics published by this group. You can visit IMRO at www.imro.org for more information. |


|
Guild Wars 2 - Elite Insights
2.27+
JSON doc
|
Class representing a player More...
Properties | |
| string | Account [get, set] |
| Account name of the player More... | |
| int | Group [get, set] |
| Group of the player More... | |
| bool | HasCommanderTag [get, set] |
| Indicates if a player has a commander tag More... | |
| string | Profession [get, set] |
| Profession of the player More... | |
| string [] | Weapons [get, set] |
| Weapons of the player 0-1 are the first land set, 1-2 are the second land set 3-4 are the first aquatic set, 5-6 are the second aquatic set When unknown, 'Unknown' value will appear If 2 handed weapon even indices will have "2Hand" as value More... | |
| JsonStatistics.JsonDPS [][] | DpsTargets [get, set] |
| Array of Total DPS stats Length == # of targets and the length of each sub array is equal to # of phases More... | |
| List< int > [][] | TargetDamage1S [get, set] |
| Array of int representing 1S damage points Length == # of targets and the length of each sub array is equal to # of phases More... | |
| List< JsonDamageDist > [][] | TargetDamageDist [get, set] |
| Per Target Damage distribution array Length == # of targets and the length of each sub array is equal to # of phases More... | |
| JsonStatistics.JsonGameplayStats [][] | StatsTargets [get, set] |
| Stats against targets Length == # of targets and the length of each sub array is equal to # of phases More... | |
| JsonStatistics.JsonPlayerSupport [] | Support [get, set] |
| Support stats Length == # of phases More... | |
| List< JsonDamageModifierData > | DamageModifiers [get, set] |
| Damage modifiers against all More... | |
| List< JsonDamageModifierData > [] | DamageModifiersTarget [get, set] |
| Damage modifiers against targets Length == # of targets More... | |
| List< JsonBuffsUptime > | BuffUptimes [get, set] |
| List of buff status More... | |
| List< JsonPlayerBuffsGeneration > | SelfBuffs [get, set] |
| List of buff status on self generation Key is "'b' + id" More... | |
| List< JsonPlayerBuffsGeneration > | GroupBuffs [get, set] |
| List of buff status on group generation More... | |
| List< JsonPlayerBuffsGeneration > | OffGroupBuffs [get, set] |
| List of buff status on off group generation More... | |
| List< JsonPlayerBuffsGeneration > | SquadBuffs [get, set] |
| List of buff status on squad generation More... | |
| List< JsonBuffsUptime > | BuffUptimesActive [get, set] |
| List of buff status on active time More... | |
| List< JsonPlayerBuffsGeneration > | SelfBuffsActive [get, set] |
| List of buff status on self generation on active time More... | |
| List< JsonPlayerBuffsGeneration > | GroupBuffsActive [get, set] |
List of buff status on group generation on active time
| |
| List< JsonPlayerBuffsGeneration > | OffGroupBuffsActive [get, set] |
List of buff status on off group generation on active time
| |
| List< JsonPlayerBuffsGeneration > | SquadBuffsActive [get, set] |
| List of buff status on squad generation on active time More... | |
| List< JsonDeathRecap > | DeathRecap [get, set] |
| List of death recaps Length == number of death More... | |
| List< JsonConsumable > | Consumables [get, set] |
| List of used consumables More... | |
| List< long > | ActiveTimes [get, set] |
| List of time during which the player was active (not dead and not dc) Length == number of phases More... | |
| Properties inherited from GW2EIBuilders.JsonModels.JsonActor | |
| string | Name [get, set] |
| Name of the actor More... | |
| uint | Condition [get, set] |
| Condition damage score More... | |
| uint | Concentration [get, set] |
| Concentration score More... | |
| uint | Healing [get, set] |
| Healing Power score More... | |
| uint | Toughness [get, set] |
| Toughness score More... | |
| uint | HitboxHeight [get, set] |
| Height of the hitbox More... | |
| uint | HitboxWidth [get, set] |
| Width of the hitbox More... | |
| ushort | InstanceID [get, set] |
| ID of the actor in the instance More... | |
| List< JsonMinions > | Minions [get, set] |
| List of minions More... | |
| JsonStatistics.JsonDPS [] | DpsAll [get, set] |
| Array of Total DPS stats Length == # of phases More... | |
| JsonStatistics.JsonGameplayStatsAll [] | StatsAll [get, set] |
| Stats against all Length == # of phases More... | |
| JsonStatistics.JsonDefensesAll [] | Defenses [get, set] |
| Defensive stats Length == # of phases More... | |
| List< JsonDamageDist > [] | TotalDamageDist [get, set] |
| Total Damage distribution array Length == # of phases More... | |
| List< JsonDamageDist > [] | TotalDamageTaken [get, set] |
| Damage taken array Length == # of phases More... | |
| List< JsonRotation > | Rotation [get, set] |
| Rotation data More... | |
| List< int > [] | Damage1S [get, set] |
| Array of int representing 1S damage points Length == # of phases More... | |
| List< int[]> | ConditionsStates [get, set] |
| Array of int[2] that represents the number of conditions Array[i][0] will be the time, Array[i][1] will be the number of conditions present from Array[i][0] to Array[i+1][0] If i corresponds to the last element that means the status did not change for the remainder of the fight More... | |
| List< int[]> | BoonsStates [get, set] |
| Array of int[2] that represents the number of boons Array[i][0] will be the time, Array[i][1] will be the number of boons present from Array[i][0] to Array[i+1][0] If i corresponds to the last element that means the status did not change for the remainder of the fight More... | |
| List< int[]> | ActiveCombatMinions [get, set] |
| Array of int[2] that represents the number of active combat minions Array[i][0] will be the time, Array[i][1] will be the number of active combat minions present from Array[i][0] to Array[i+1][0] If i corresponds to the last element that means the status did not change for the remainder of the fight More... | |
| List< double[]> | HealthPercents [get, set] |
| Array of double[2] that represents the health status of the actor Array[i][0] will be the time, Array[i][1] will be health % If i corresponds to the last element that means the health did not change for the remainder of the fight More... | |
Class representing a player
|
getset |
Account name of the player
|
getset |
List of time during which the player was active (not dead and not dc)
Length == number of phases
|
getset |
List of buff status
|
getset |
List of buff status on active time
|
getset |
List of used consumables
|
getset |
Damage modifiers against all
|
getset |
Damage modifiers against targets
Length == # of targets
|
getset |
List of death recaps
Length == number of death
|
getset |
Array of Total DPS stats
Length == # of targets and the length of each sub array is equal to # of phases
|
getset |
Group of the player
|
getset |
List of buff status on group generation
|
getset |
Indicates if a player has a commander tag
|
getset |
List of buff status on off group generation
|
getset |
Profession of the player
|
getset |
List of buff status on self generation
Key is "'b' + id"
|
getset |
List of buff status on self generation on active time
|
getset |
List of buff status on squad generation
|
getset |
List of buff status on squad generation on active time
|
getset |
Stats against targets
Length == # of targets and the length of each sub array is equal to # of phases
|
getset |
Support stats
Length == # of phases
|
getset |
Array of int representing 1S damage points
Length == # of targets and the length of each sub array is equal to # of phases
If the duration of the phase in seconds is non integer, the last point of this array will correspond to the last point
ex: duration === 15250ms, the array will have 17 elements [0, 1000,...,15000,15250]
|
getset |
Per Target Damage distribution array
Length == # of targets and the length of each sub array is equal to # of phases
|
getset |
Weapons of the player
0-1 are the first land set, 1-2 are the second land set
3-4 are the first aquatic set, 5-6 are the second aquatic set
When unknown, 'Unknown' value will appear
If 2 handed weapon even indices will have "2Hand" as value


My Contact Details
My address
077464737363637
<EMAIL_ADDRESS>Sign Up for our Monthly Newsletters
Username
Password
Can't Find What You're Looking for?


* If you’re lucky enough to live in the mountains, you’re lucky enough. For the rest of us, we’ll just have to live vicariously through Kevin Russ
today’s Very Short List:
culture 1 May 2013
Andy Forch is the co-founder of Huckberry
Subscribe
* Happiness and airplane travel go together about as well as oil and water, something which RouteHappy
* Cheaper than a seat on SpaceX, The Scale of the Universe <:http:> is a one-way ticket to all of the hot spots in the observable universe. [3 of 3]
http://link.nyobserver.com/516ca68465217dc6e1b9a3a6z7f2.obn/UXfgDcJSEITKXVV0Bdbbc very short list is a
delightful e-mail that shares
cultural gems from a
different curator every day.
If you have any problems reading this e-mail, click here
http://link.nyobserver.com/516ca68465217dc6e1b9a3a6z7f2.obn/UXfgDcJSEITKXVV0Cedbe
Subscribe
Forward
My Account
Unsubscribe
tech 29 Apr 2013
food 26 Apr 2013
Karyn Campbell on artists who play with food.
culture 24 Apr 2013
Editorial Policy
Privacy Policy
Contact Us
Press
Terms + Conditions
very fine print: ©2013
Observer VSL LLC.
321 West 44th Street, 6th Floor
New York, NY 10036 USA
All rights reserved.
Questions?<PHONE_NUMBER>.
This message was intended for<EMAIL_ADDRESS>If you believe this has been sent to you in error, please safely unsubscribe


Toggle navigation
UpCASE
Settings
Signed in as
Hercules
Your Profile
Your Collections
Create a new Collection
Settings
Logout


Bedu travels el sitio donde podras encontrar los mejores destinos.
Tomate un momento para ti.
Conoce másSome quick example text to build on the card title and make up the bulk of the card's content.
Go somewhereSome quick example text to build on the card title and make up the bulk of the card's content.
Go somewhereSome quick example text to build on the card title and make up the bulk of the card's content.
Go somewhereSome quick example text to build on the card title and make up the bulk of the card's content.
Go somewhereSome quick example text to build on the card title and make up the bulk of the card's content.
Go somewhereSome quick example text to build on the card title and make up the bulk of the card's content.
Go somewhere


Date: 31 March 2019
Time: 11:00 AM
Venue: Lathe Lab Mechanical Department
Entry Fee:₹100
prize:₹3000
The participants should machine a given workpiece in lathe .The dimensions for the final product will be given.


Heap Practice From Documentation
With Leetcode solution to top-k-frequent-elements
https://docs.python.org/2/library/heapq.html
https://leetcode.com/problems/top-k-frequent-elements/
>>> import heapq
5 4 3 1 2 8 7
# Create heap in linear time from an existing array
>>> heap = [5,4,3,1,2,8,7]
>>> heapq.heapify(heap)
>>> heap
[1, 2, 3, 4, 5, 8, 7]
1 2 3 4 5 8 7
# Push an element to an existing heap
>>> heapq.heappush(heap, 0)
>>> heap
[0, 1, 3, 2, 5, 8, 7, 4]
0 1 3 2 5 8 7 4
# Pop the root and heapify
>>> heapq.heappop(heap)
0
1 2 3 4 5 8 7
# Merge 2 heaps
>>> heap2 = [10,11,12]
>>> mergedGenerator = heapq.merge(heap, heap2)
>>> list(mergedGenerator)
[1, 2, 3, 4, 5, 8, 7, 10, 11, 12]
heap heap2 Iterable 1 10 1 2 3 + 11 12 = 2 3 4 5 8 7 4 5 8 7 10 11 12
# Largest and Smallest k elements
>>> k = 3
>>> heapq.nlargest(k, heap), heapq.nsmallest(k, heap)
([8, 7, 5], [1, 2, 3])
# Leetcode 347. Top K Frequent Elements
>>> def topKFrequent(nums, k):
... freqCount = {}
... for num in nums:
... freqCount[num] = freqCount.get(num, 0) + 1
... heap = []
... for key in freqCount:
... heap.append((freqCount[key],key))
... mostFrequent = heapq.nlargest(k, heap)
... return [b for a,b in mostFrequent]
>>> assert topKFrequent([1,1,2,2,2,3,4,4,4,4], 4) == [4,2,1,3]
Written on May 5, 2019


Adnan Menderes, (born 1899, Aydın, Tur.—died Sept. 17, 1961, İmralı), Turkish politician who served as prime minister from 1950 until deposed by a military coup in 1960.
The son of a wealthy landowner, Menderes was educated at the American College in İzmir and the Faculty of Law at Ankara. Later in life he sold or distributed most of his estates to small shareholders, maintaining only one farm, which became a model of modern agricultural methods. In 1930 he entered parliament as a member of Kemal Atatürk’s Republican People’s Party (RPP). The RPP was at that time the only legal party in Turkey and was firmly pro-Western. It had broken drastically with many social and cultural traditions of the past and had introduced a rigidly controlled state economy.
In 1945 Menderes was expelled from the RPP, and he and three others founded (1946) the Democrat Party (DP), which became Turkey’s first opposition party. The 1950 elections, which were the first free elections held in Turkey in more than 25 years, resulted in a landslide victory for Menderes and his party. Menderes was more tolerant than the RPP of traditional ways of life. While still pro-Western in foreign policy, he tried to establish closer ties with Muslim states. Recognizing the deep-seated religious fervour of the populace, Menderes relaxed much of the official antipathy of Atatürk and the RPP towards some of the more conservative manifestations of Islāmic religious feeling.
The DP encouraged private enterprise as opposed to a planned economy, but it eventually brought the country to insolvency by a policy of heedless importation of foreign goods and technology. While the lot of the average villager did improve, it was done at the sacrifice of national economic integrity.
In spite of Turkey’s crushing economic problems, Menderes maintained his popularity with the peasantry, and in the 1954 elections the DP again won by a substantial majority, returning Menderes to office. Always intolerant of criticism, Menderes then set out to silence his opposition. Press censorship was instituted, journalists were jailed at whim, and local elections were rigged. These policies not only angered the intellectuals but alienated the military, a group that saw itself as the guardians of Kemalist ideals and felt that the Atatürk reforms were being directly challenged.
Although the national economy continued to decline, Menderes still had popular support and won the 1957 elections. But the opposition to him was intensifying, and on May 27, 1960, a military coup overthrew his government. Menderes and hundreds of Democrat Party leaders were arrested. During a trial lasting 11 months, Menderes was accused of embezzling state funds, extravagance, and corruption, among other charges. He was sentenced to death and, following a suicide attempt, was hanged.


Pipes
问题描述 :
After writing a solver for the "moveable maze" game last week, you have grown tired of it. After all, you already know the optimal solution. To entertain yourself, you find another puzzle game called "Pipes", and play that for a while. On one puzzle, you have not been able to find a solution by hand, and you think that there is no solution.
The game is played on a grid with R rows and C columns. Each square of the grid contains a black dot in the centre and black lines in the direction of some, none, or all of its north, east, south, and west neighbouring squares, with the following restriction: if two opposite directions both have lines, then at least one of the other two directions has a line as well. In other words, it is forbidden for a square to consist of a straight line.
The objective of the game is to rotate each square, as many times as you like, such that for each square, if it has a line going in a compass direction (that is, north, east, south, or west), then it has a neighbour in that compass direction and that neighbour has a line going in the opposite compass direction. In other words, each edge in the grid should either have a line on both sides or neither side.
Your task is to determine whether a given grid has a solution.
输入:
The first line of each test case contains the two integers R and C, separated by spaces, with 1 <= R,C <= 12.
The following R lines of input each contain one row of the grid, from north to south. Each of these lines contains exactly C strings of letters, separated by spaces, that correspond to squares of the grid, from west to east. Their format is as follows:
- If the string is the single character x, then the square does not contain a line to any of its neighbours.
- Otherwise, the string contains some of the characters N, E, S, W, which indicate that a black line extends from this square’s centre in the direction of its north, east, south, or west neighbour, respectively. No character will appear in the string more than once.
Input is terminated by a line containing 0 0. These zeros are not a test case and should not be processed.
输出:
The first line of each test case contains the two integers R and C, separated by spaces, with 1 <= R,C <= 12.
The following R lines of input each contain one row of the grid, from north to south. Each of these lines contains exactly C strings of letters, separated by spaces, that correspond to squares of the grid, from west to east. Their format is as follows:
- If the string is the single character x, then the square does not contain a line to any of its neighbours.
- Otherwise, the string contains some of the characters N, E, S, W, which indicate that a black line extends from this square’s centre in the direction of its north, east, south, or west neighbour, respectively. No character will appear in the string more than once.
Input is terminated by a line containing 0 0. These zeros are not a test case and should not be processed.
样例输入:
3 3 NW NW x NES NESW W E W x 2 2 ES x x N 0 0
样例输出:
SOLVABLE UNSOLVABLE
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 1010100; const int INF = 0x3f3f3f3f; int n,m,tot; struct Hash { struct Node {int v; int id; Node *next;}; int mod; Node *table[5555],memo[N]; void init() { tot = 0; mod = 5501; memset(table,0,sizeof(table)); } int operator [] (int x) { int idx = x%mod; for (Node *i = table[idx]; i ; i = i->next) if (x==i->v) return i->id; memo[tot] = (Node) {x,tot,table[idx]}; table[idx] = &memo[tot]; return tot ++; } }hash; char s[55][55]; int mat[55][55][2],f[2][N],*cur,*nex; int tomin(int &a,int b) { if (a>b)a=b; } int work() { for (int i = 0; i < 2*n+1; i ++) for (int j = 0; j < 2*m+1; j ++) if (s[i][j]=='#') s[i][j] = '0'; for (int i = 0; i < n; i ++) for (int j = 0; j < m; j ++) { mat[i][j][0] = s[i*2+1][j*2+2]-'0'; mat[i][j][1] = s[i*2+2][j*2+1]-'0'; } cur = f[0]; nex = f[1]; memset(f,INF,sizeof(f)); hash.init(); cur[hash[0]] = 0; for (int i = 0; i < n; i ++) { for (int j = 0; j < m; j ++) { for (int st = 0; st < tot; st ++) if (cur[st]!=INF) { int v = hash.memo[st].v; int a = v>>m>>m&3; int b = v>>j>>j&3; if (!a && !b) { if (j!=m-1) tomin(nex[hash[v^2<<m<<m^1<<j<<j]],cur[st]+mat[i][j][0]+mat[i][j][1]); } else if (!a && b) { tomin(nex[st],cur[st]+mat[i][j][1]); if (j!=m-1) tomin(nex[hash[v^b<<m<<m^b<<j<<j]],cur[st]+mat[i][j][0]); } else if (a && !b) { if (j!=m-1) tomin(nex[st],cur[st]+mat[i][j][0]); tomin(nex[hash[v^a<<m<<m^a<<j<<j]],cur[st]+mat[i][j][1]); } else if (a && b) { int k,cnt; if (a==1 && b==1) { for (k = j+1,cnt = 0; k < m; k ++) { int vp = v>>k>>k&3; if (vp==1) cnt ++; else if (vp==2) cnt --; if (cnt==-1) break; } tomin(nex[hash[v^a<<m<<m^b<<j<<j^3<<k<<k]],cur[st]); } else if (a==2 && b==2) { for (k = j-1,cnt = 0; k >= 0; k --) { int vp = v>>k>>k&3; if (vp==1) cnt ++; else if (vp==2) cnt --; if (cnt==1) break; } tomin(nex[hash[v^a<<m<<m^b<<j<<j^3<<k<<k]],cur[st]); } else if (a==2 && b==1) { tomin(nex[hash[v^a<<m<<m^b<<j<<j]],cur[st]); } else if (a==1 && b==2) { if (i==n-1 && j==m-1) tomin(nex[hash[v^a<<m<<m^b<<j<<j]],cur[st]); } } } swap(cur,nex); for (int k = 0; k < tot; k ++) nex[k] = INF; } } return cur[0]; } int main() { int cas; scanf("%d",&cas); while (cas--) { scanf("%d%d\n",&n,&m); for (int i = 0; i < 2*n+1; i ++) gets(s[i]); printf("%d\n",work()); } return 0; }
本来还想着4p的，可这两个人害羞！
else if也是要比较两次
约瑟夫也用说这么长……很成熟的一个问题了，分治的方法解起来o(n)就可以了，有兴趣可以看看具体数学的第一章，关于约瑟夫问题推导出了一系列的结论，很漂亮
简洁的代码
为避免精度问题，PI值请使用arccos(-1)。应该是acos
这是什么编译器啊，不通过
隐藏最深的bug是(start+end)/2有可能上溢
正是我要找的，适合新手
比较基础，找些自信
其实国内大部分公司对算法都不够重视。特别是中小型公司老板根本都不懂技术，也不懂什么是算法，从而也不要求程序员懂什么算法，做程序从来不考虑性能问题，只要页面能显示出来就是好程序，这是国内的现状，很无奈。
必须试过啊
神奇的网站


{{ partial "header.html" . }}
Shops are grouped by country. Click on a country name header to expand the group.


Eyetech is a new company that provides Online Diabetic retinal retification for the defects with a
detail report generation certified from medical organization.
Our Mission
To support the diabetic patients to provide the best vision solution
SERVICES
{% if current_user.is_authenticated %}
{% else %}
{% endif %}
Online Checkup
CONTACT
Contact us and we'll get back to you as soon as possible.


Contact
Use this form to ask general questions, office updates, or request an appointment.
Full Name:
Phone Number:
Email Address:
Message:
Send Message


Yoodo Gank will be representing Malaysia in the PMCO Global Finals
The PMCO Global Finals will be happening at the Putra World Trade Centre in Kuala Lumpur, from 31 November until 2 December 2019. With that said, Yoodo will be sending their PUBG Mobile Team, Yoodo Gank, one of the highest-ranked Malaysian team to represent Malaysia in the grand finals where they will be among the 16 teams who will be duking it for their share of the RM10.5 million prize pool.
Head over to the official website, if you are keen on witnessing the action in person. With that said, would you be interested in attending the PMCO 2019 Fall Global Final which will take place in PWTC? Let us know on our Facebook page, and for more updates like this stay tuned to TechNave.com.


Date: 17 Feb, 2015
To gain popularity in the industry, we select only the freshest seasonal products and combine them with exclusive wine list, which features small wine producers and select local Scottish craft ales.


A summary of the common properties of the noise blocks is provided in the documentation of package Blocks.Noise. This BandLimitedWhiteNoise block generates reproducible, random noise at its output according to a band-limited white noise distribution. This is performed by using a normal distribution with mu=0 and sigma = sqrt(noisePower/samplePeriod).
In order for this block to produce meaningful results, you should set the following parameters:
Ideal white noise contains all frequencies, including infinitely high ones. However, these usually cannot be observed in physical systems, since all physical systems in one way or the other contain low-pass filters. It is thus sufficient to generate a limited range of frequency content in the noise signal, as long as it exceeds the frequencies of the subsequent dynamics by a sufficiently high factor (of e.g. 100).
Ideal white noise has a flat, i.e. constant, power spectral density for all frequencies. It has thus infinitely high power, because the total power of a signal can be obtained by integrating the power spectral density over all frequencies. The following three ways to think of the power of a signal may be helpful:
In order to set the correct level of the band-limited white
noise power spectral density, the variance of its normal
distribution can thus be influenced directly. Recalling that the
samplePeriod of the noise signal generates frequency content in the
range ±0.5/samplePeriod, the variance must be increased to generate
sufficient total signal power. The total power must match the
product of the noisePower and its frequency bandwidth
1/samplePeriod: signal power = signal variance = noisePower /
samplePeriod
.
Example NoiseExamples.DrydenContinuousTurbulence demonstrates how to utilize this block to model wind gust.


In this walk through we will create some data in a Google Sheet, import it into a collection we’ve created. Modify it and send it back to our Google Sheet. As part of the procees we will need to authorize our dataset tool and setup access.
Setup our local collection. Create a new dataset collection named “ZBS-Character-List.ds”
dataset init zbs-cast-list.ds
Download zbs-cast-list.csv. We will use this when we create our Google Sheet for this walk through.
Open your browser and create a new Google Sheet by going to https://sheets.google.com. You can pick the “Blank” sheet from the template gallery under “Start a new spreadsheet”. This should you a new untitled spreadsheet. Set the title to something meaninful, I’m going to set my title to “zbs-cast-list”.
In Google Sheets go to the file menu and select “import”. Select the “upload” tab, find zbs-cast-list.csv and “open” it. You should then see an “Import file” dialog, select “Replace current sheet” then press “Import Data” button at the bottom of the box.
You should wind up with a spreadsheet that starts out something like this –
ID,Name,Title,Year
1,Jack Flanders,The Fourth Tower of Inverness,1972
2,Little Freida,The Fourth Tower of Inverness,1972
3,Dr. Mazoola,The Fourth Tower of Inverness,1972
4,The Madonna Vampyra,The Fourth Tower of Inverness,1972
5,Chief Wampum,The Fourth Tower of Inverness,1972
6,Old Far-Seeing Art,The Fourth Tower of Inverness,1972
7,Lord Henry Jowls,The Fourth Tower of Inverness,1972
8,Meanie Eenie,The Fourth Tower of Inverness,1972
9,Lady Sarah Jowls,The Fourth Tower of Inverness,1972
...
You sheet should have four columns A to D (ID, Name, Title, Year) and 195 rows with id ranging from 1 to 194 in column 1. You can describe the range of your sheet as A1:D195 (A 1 through D 195). We’re going to use this range when importing and exporting.
Look at the URL for your Google Sheet. It’ll be similar to mine
https://docs.google.com/spreadsheets/d/1Rf-fbGg9OPWnDsWng9oyQmMIWzMqx717uuKeBlzDaCc/edit#gid=0
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Notice the part of the URL between “/d/” and “/edit”. For my sheet it is “1Rf-fbGg9OPWnDsWng9oyQmMIWzMqx717uuKeBlzDaCc”. This is the sheet ID. It is unique to my spreadsheet so yours will be different. We are going to need that number later.
Look at the bottom of the Google Sheet window. You’ll see the tab for your sheet. By default this is named “Sheet1”, since I chose to replace my current empty sheet it named my sheet “zbs-cast-list” as that was the name of the file I imported. You’ll need to know the sheet name as well as they sheet ID.
This is the hardest part of the process. Google sometimes updates this procedure, and this worked as of 08/08/2018. You might have to make adjustments in the future.
We need to get some credentials and authorization keys to access your Google Sheet before we can import it into our dataset collection. If you have not done this previously go to https://developers.google.com/sheets/api/quickstart/go. We only need to complete “Step 1”.
Click the blue button labeled Enable the Google Sheets API
Make up a project name (e.g. zbs-cast-list).
Click the blue button labeled Download Client Configuration
Currently, you need to move the file from your downloads folder to your
current working directory (e.g. on my Mac I did
mv ~/Downloads/credentials.json ./
Once your “credentials.json” file is generated and downloaded to your
working directory you need to trigger authorization for dataset. To
do so we type in for importing our spreadsheet into our local collection.
The first time we do this a link (URL) will be displayed. Copy that link
into your web browser. You will goto a page that allows you to “authorize”
the application. Follow the instructions.
NOTE: The "credentials.json" file and OAuth authorization is
required for data to access your Google Sheet. The OAuth
authorization process uses the "credentials.json" file to get
a token to use on subsequent access by _dataset_. This OAuth
token is usually stored in your `$HOME/.credentials` directory as
sheets.googleapis.com-dataset.json. If this file doesn't exist
then the first time you run the _dataset_ command with a GSheet
option it'll prompt you to use your web browser to authorize
_dataset_ to access your Google spreadsheet.
The command that will trigger the authorization process the first time is also the command we will eventually use to import our data. Replace SHEET_ID with the number we see in the URL and SHEET_NAME with the name of the spreadsheet. Our CELL_RANGE will be “A1:D195” and our COL_NP_FOR_ID will be 1
dataset import zbs-cast-lis.ds SHEET_ID SHEET_NAME COL_NO_FOR_ID [CELL_RANGE]
For my URL, SHEET_ID, SHEET_NAME, CELL_RANGE and COL_NO_FOR_ID looked like
dataset import zbs-cast-lis.ds \
"1Rf-fbGg9OPWnDsWng9oyQmMIWzMqx717uuKeBlzDaCc" \
"zbs-cast-list" \
1 "A1:D192"
Yours will have a different SHEET_ID and SHEET_NAME.
After your authorize the sheet access via your web browser then next time you run the command you’ll see data imported into zbs-cast-list.ds. You can count the keys to see what was imported.
dataset zbs-cast-list.ds count
You are now ready to modify and update your local collection.
dataset provides a mechanism to synchronize data with a table (e.g.
a CSV file or Google Sheet, we’re interested in the later).
Synchronizationis accomplished by mapping the column headings to object
paths in our dataset collection as well as rows to objects. To define
this relationship so dataset knowns what to do we use a “data frame”.
For dataset this means describing a set of keys (which will map to rows
in the table), a set of dotpaths (this well become columns mapped into
each row) and labesl (the names of the columns in the table form). Let’s
create a “frame” for synchronizing zbs-cast-list.ds with our Google Sheet.
First we need to make sure we know our fields in our JSON objects. We can see a random sample using the keys verb and retrieving the resulting key list as a list of objects and pretty printing them.
dataset keys -sample=1 zbs-cast-list.ds | \
dataset read -p -i - zbs-cast-list.ds
Here is an example of the output
{
"_Key": "19",
"ID": 19,
"Name": "Comtese Zazeenia",
"Title": "Moon Over Morocco",
"Year": 1973
}
Notice that we a _Key
field and an “ID” field. _Key
is the internal
id for the JSON object used by dataset. We will want to
use the _Key
field explicitly when we defined our frame. This
will establish the relationship between dataset’s objects and
the spreadsheet. We’re going to want to include “all” keys in the
collection so we’ll be using the ‘-all’ option (you could
limit the frame to specific records by providing a keylist
to the frame definition).
Step 1. define our frame
dataset frame-create -all zbs-cast-list.ds gsheet-sync \
._Key=ID .Name=Name .Title=Title .Year=Year
This returns a new frame definition. This includes the relationship between our object attributes (dot paths) and the column label.
Step 2. Review the frame you defined.
dataset frame -p zbs-cast-list.ds gsheet-sync | more
You should check your recreate the frame and if the dot paths or labels look incorrect. Otherwise we’re ready to synchronize our collection with our Google Sheet.
Let’s change item 43 in our Google Sheet from “Jack Flanders” to “Molly Flanders”. We want our collection to pick up this change. We need to “recieve” data into our collection from our Google Sheet. We need to do a “sync-receive”.
dataset sync-recieve zbs-cast-list.ds gsheet-sync \
1tXbMC1Dt5B8sFr1MvJAuwkS3TatVssu0f4YcAJoZgOE \
zbs-cast-list
We can check that we recieved our data by “reading” the record 43 in our collection.
dataset read -p zbs-cast-list.ds 43
Molly has been promoted to director and Jack is back in the cast. Let’s update our collection then “send” our data back to the Google Sheet.
dataset join -overwrite zbs-cast-list.ds 43 '{"name":"Jack Flanders"}'
Now let’s update send our frame back up to our Google Sheet.
dataset sync-send zbs-cast-list.ds gsheet-sync \
1tXbMC1Dt5B8sFr1MvJAuwkS3TatVssu0f4YcAJoZgOE \
zbs-cast-list
Technically all the rows/columns in our Google Sheet we updated. If we changed our frame to only have key 43 then it would have only updated the row with the matching ID of 43.
We can also export our collection to Google Sheet. Exporting overwrites any content in the sheet with our collections’ frame’s column and row order. “sync-send” respects the existing spreadsheet column and row order, export imposes a the collection frame’s column and row order.
This command to export our collection into Google sheets looks like
dataset export COLLECTION_NAME FRAME_NAME SHEET_ID SHEET_NAME
Like “sync-receive” and “sync-send” we use frame to define our export. In our next example we’re create a new sheet called “new-cast-list” in our Google Sheet, then we can export our whole zbs-cast-list.ds into it.
dataset export zbs-cast-list.ds gsheet-sync \
1tXbMC1Dt5B8sFr1MvJAuwkS3TatVssu0f4YcAJoZgOE \
new-cast-list
You should now see populated new-cast-list sheet.
Related topics: dotpath, export-csv, frame, import-csv, import-gsheet, export-gsheet, sync-receive and sync-send


@@include("../blocks/modules/header/header.html")
@@include("../blocks/modules/about/about.html")
@@include("../blocks/modules/steps/steps.html")
@@include("../blocks/modules/form/form.html")
@@include("../blocks/modules/advantage/advantage.html")
@@include("../blocks/modules/card/card.html")
@@include("../blocks/modules/price/price.html")
@@include("../blocks/modules/FAQ/FAQ.html")
@@include("../blocks/modules/video/video.html")
@@include("../blocks/modules/reviews/reviews.html")
@@include("../blocks/modules/partners/partners.html")
@@include("../blocks/modules/footer/footer.html")


"MUTH-LABBEN "occurring only in the title of Psalm 9. Some interpret the words as meaning “on the death of Labben,” some unknown person. Others render the word, “on the death of the son;” i.e., of Absalom (2 Samuel 18:33). Others again have taken the word as the name of a musical instrument, or as the name of an air to which the psalm was sung.
"MUTH-LABBEN "occurring only in the title of Psalm 9. Some interpret the words as meaning “on the death of Labben,” some unknown person.
Others render the word, “on the death of the son;” i.e., of Absalom (2 Samuel 18:33). Others again have taken the word as the name of a musical instrument, or as the name of an air to which the psalm was sung.


by John C. Pezzullo
Revised 2015-07-22: Apply fractional shifts for the
first few iterations, to increase robustness for ill-conditioned data.
This page performs logistic regression, in which a dichotomous outcome is predicted by one or more variables. The program generates the coefficients of a prediction formula (and standard errors of estimate and significance levels), and odds ratios (with confidence intervals).


Provides the user with functions to develop their trading strategy, uncover actionable trading ideas, and monitor consensus shifts with crowdsourced earnings and economic estimate data directly from <www.estimize.com>. Further information regarding the web services this package invokes can be found at <www.estimize.com/api>.
| Version: | 1.0.0 |
| Depends: | R (≥ 3.1.3), RCurl, RJSONIO |
| Suggests: | testthat |
| Published: | 2015-05-23 |
| Author: | Thomas P. Fuller |
| Maintainer: | Thomas P. Fuller <thomas.fuller at coherentlogic.com> |
| License: | LGPL-3 |
| Copyright: | (C) 2015 Coherent Logic Limited; ALL RIGHTS RESERVED. |
| URL: | http://www.r-project.org, http://coherentlogic.com/middleware-development/r-package-for-the-estimize-com-api?source=cran, https://www.estimize.com?source=cran |
| NeedsCompilation: | no |
| Materials: | NEWS |
| In views: | Finance, WebTechnologies |
| CRAN checks: | restimizeapi results |
| Reference manual: | restimizeapi.pdf |
| Package source: | restimizeapi_1.0.0.tar.gz |
| Windows binaries: | r-devel: restimizeapi_1.0.0.zip, r-release: restimizeapi_1.0.0.zip, r-oldrel: restimizeapi_1.0.0.zip |
| OS X binaries: | r-release: restimizeapi_1.0.0.tgz, r-oldrel: restimizeapi_1.0.0.tgz |
Please use the canonical form https://CRAN.R-project.org/package=restimizeapi to link to this page.


Earlier this year a blog on the Exchange Team site was poste by Ross Smith IV. In this blog he encouraged to use Kerberos as authentication method for Outlook clients.
In a lot of Exchange environments you will see that it is implemented. When you are using a CAS Array you will need to create an alternate service account (ASA) for this. This can be done by using the RollAlternateserviceAccountPassword.ps1 script. Keep in mind that when using the CreateScheduledTask parameter the scheduled task will run as the account who created the scheduled task.
After registering the correct SPN’s on the ASA account Kerberos will work in most cases. In some scenario’s a typo is made which results in incorrect SPN’s being registered. When this is the case you can solve it by using setspn or AdsiEdit.
But what if Kerberos sometimes works and sometimes not, or does only work for specific users? If it doesn’t work a user will not be able to access his/her mailbox.
The easiest way to figure out if Kerberos is to change the Outlook profile.
On the security tab of the account you will need to change the value of Logon network security _to _NTLM. If the user can access his/her mailbox after this you know that Kerberos is causing the issue.
Besides this an event will be logged in the system event log. Because a small set of logging is enabled on the Windows Servers you won’t see the Kerberos issue on that side. To enabled the logging you will need to make a change in the registry:
- start regedit
- browse to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters
- create a Dword called LogLevel
- change the value of the Dword to 0x1
Logging is directly enabled after creating the registry key and after a refresh you will see several Kerberos errors in the log.
Another option is to create a network trace using Wireshark or Netmon. In both cases you will see the following message in the trace:
0xD – KDC_ERR_BADOPTION: KDC cannot accommodate requested option
When you will search the internet for this error you will see you are not the only one. But let’s start from the begin instead of going to directly to the solution.
One of the first things you will need to do is run SetSPN -L “ASA account” to verify that all correct SPN’s are registered. The SPN’s should be unique. Despite I have seen environments where the domain controllers also contain two SPN’s named ExchangeAB _followed by the netbios and fqdn. To verify if the SPN’s are unique you can use _SetSPN -Q “SPN VALUE” , for example SetSPN -Q ExchangeAB/*.
As displayed in the screenshot above you will see ExchangeAB will be found four times. Two times on the Exchange Server and two times on the DC.
As fas as we can see at this moment everything looks OK. Time to continue troubleshooting. But with which step can you continue when you have the error above? Klist.exe or Kerbtray.exe will not help a lot because in most cases renewing the tickets won’t solve the issue.
After some research together with a customer we found the root cause of the issue.
Microsoft did change the UDP packet size starting from Windows 2003. In Windows XP the UDP packet size was set to 2000, starting from 2003 it has been set to 1465. I think you know what will happen when Kerberos will send a package. Kerberos will use UDP by default . This will result in incompleted packages which will arrive at servers containing Windows 2003 or above as OS.
But why does the issue only happens for some users? This depends on the Kerberos ticket size. The size of a Kerberos ticket is determind by:
- length of the password
- membership of groups
- do the groups contain other nested groups
To solve this issue you will need to make a registry change:
- start regedit
- browse to HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\ Kerberos\Parameters
- create a Dword called MaxPacketSize
- change the value of the Dword to 1
By making this change all Kerberos packages which are bigger then 1K will be send by using Kerberos over TCP.
Restart the computer and change the Outlook profile to Negotiate Authentication. Verify if you can access the mailbox. Using klist.exe or kerbtray.exe verify of the tickets will be created correctly. Both tools are part of the resource kit for Windows 2003. In Windows 7 and 2008 klist is a part of the OS.
In this screenshot two Kerberos tickets are listed which are being used by Exchange. If all authentication is performed by using Kerberos you will see the following Kerberos tickets:
- exchangeMDB
- exchangeRFR
- exchangeAB
- http
When you will look in the event log of the client you won’t find any Kerberos messages.
Microsoft has published a complete document about troubleshooting Kerberos authentication issues. You can find the document here.


The Logic Server library (.dll and .so) has a functional interface and an object-oriented interface. C programmers call the functional Logic Server interface directly. These are the functions that begin with 'ls' and that are documented in the API Reference. They are defined in logicserver.h.
There are no special considerations when using the Logic Server from C.
The sample program in the directory samples/c/hello is a console version of the basic hello program. It includes a make file for Visual C++ users. It is built by linking with the appropriate library in amzi/lib.
Borland C++ users should link with amzi/lib/amzib.lib. This is a .lib file created by running Borland's 'implib' utility on amzi.dll.
All of the LSAPI functions that have character strings as arguments or return values have two versions. One version ends in 'A' (for ANSI) and the other ends in 'W' (for wide).
You still use the normal names of each function, but they are #defined to either the 'A' or 'W' version depending on whether or not _UNICODE is defined. If you explicitly want to use an ANSI version of a function in a _UNICODE application, you can explicitly call the 'A' version of the function.
The functions mbstowcs() and wcstombs() are used to convert between wide and multibyte (ANSI) strings, so multibyte character sets can also be used with the Logic Server.
Copyright ©1987-2011 Amzi! inc. All Rights Reserved. Amzi! is a registered trademark and Logic Server is a trademark of Amzi! inc.


About Me
Hello everyone!
My name is Lily Wang, and I am an aspiring optometrist as well as a Microbiology student at the
University of Georgia. I got my first DSLR camera in high school and fell in love with
photography. I bring my camera everywhere I go and take pictures of about anything that
captures my attention.
Need a picture? I got you.


Get your own personalized loans to achieve your goals
Consolidating debt? Paying for a large expense like
home improvement or a special occasion? We have you
covered.
Home Improvement Loans
Whether you want to remodel your
kitchen or upgrade security. Lendy
has you covered.
Auto Financing
With Lendy you can get any kind of
vehicle you want in any condition
you prefer.
Credit card Consolidation
Refinance your credit cards with a
personalized loan for Lendy and
simplify your finances.


| I l@ve RuBoard |
The writing is on the wall…
You may not usually associate elegance with police detectives, picturing instead some sort of doughnut and coffee cliché. But consider how detectives might use a blackboard to coordinate and solve a murder investigation.
Suppose the chief inspector starts off by setting up a large blackboard in the conference room. On it, he writes a single question:
H. DUMPTY (MALE, EGG): ACCIDENT OR MURDER?
Did Humpty really fall, or was he pushed? Each detective may make contributions to this potential murder mystery by adding facts, statements from witnesses, any forensic evidence that might arise, and so on. As the data accumulates, a detective might notice a connection and post that observation or speculation as well. This process continues, across all shifts, with many different people and agents, until the case is closed. A sample blackboard is shown in Figure 5.6 on the next page.
Some key features of the blackboard approach are:
None of the detectives needs to know of the existence of any other detective—they watch the board for new information, and add their findings.
The detectives may be trained in different disciplines, may have different levels of education and expertise, and may not even work in the same precinct. They share a desire to solve the case, but that's all.
Different detectives may come and go during the course of the process, and may work different shifts.
There are no restrictions on what may be placed on the blackboard. It may be pictures, sentences, physical evidence, and so on.
We've worked on a number of projects that involved a workflow or distributed data gathering process. With each, designing a solution around a simple blackboard model gave us a solid metaphor to work with: all of the features listed above using detectives are just as applicable to objects and code modules.
A blackboard system lets us decouple our objects from each other completely, providing a forum where knowledge consumers and producers can exchange data anonymously and asynchronously. As you might guess, it also cuts down on the amount of code we have to write.
Computer-based blackboard systems were originally invented for use in artificial intelligence applications where the problems to be solved were large and complex—speech recognition, knowledge-based reasoning systems, and so on.
Modern distributed blackboard-like systems such as JavaSpaces and T Spaces [URL 50, URL 25] are based on a model of key/value pairs first popularized in Linda [CG90], where the concept was known as tuple space.
With these systems, you can store active Java objects—not just data—on the blackboard, and retrieve them by partial matching of fields (via templates and wildcards) or by subtypes. For example, suppose you had a type Author, which is a subtype of Person. You could search a blackboard containing Person objects by using an Author template with a lastName value of "Shakespeare." You'd get Bill Shakespeare the author, but not Fred Shakespeare the gardener.
The main operations in JavaSpaces are:
| Name | Function |
|---|---|
| read | Search for and retrieve data from the space. |
| write | Put an item into the space. |
| take | Similar to read, but removes the item from the space as well. |
| notify | Set up a notification to occur whenever an object is written that matches the template. |
T Spaces supports a similar set of operations, but with different names and slightly different semantics. Both systems are built like a database product; they provide atomic operations and distributed transactions to ensure data integrity.
Since we can store objects, we can use a blackboard to design algorithms based on a flow of objects, not just data. It's as if our detectives could pin people to the blackboard—witnesses themselves, not just their statements. Anyone can ask a witness questions in the pursuit of the case, post the transcript, and move that witness to another area of the blackboard, where he might respond differently (if you allow the witness to read the blackboard too).
A big advantage of systems such as these is that you have a single, consistent interface to the blackboard. When building a conventional distributed application, you can spend a great deal of time crafting unique API calls for every distributed transaction and interaction in the system. With the combinatorial explosion of interfaces and interactions, the project can quickly become a nightmare.
Organizing Your BlackboardWhen the detectives work on large cases, the blackboard may be- come cluttered, and it may become difficult to locate data on the board. The solution is to partition the blackboard and start to organize the data on the blackboard somehow. Different software systems handle this partitioning in different ways; some use fairly flat zones or interests groups, while others adopt a more hierarchical treelike structure. |
The blackboard style of programming removes the need for so many interfaces, making for a more elegant and consistent system.
Suppose we are writing a program to accept and process mortgage or loan applications. The laws that govern this area are odiously complex, with federal, state, and local governments all having their say. The lender must prove they have disclosed certain things, and must ask for certain information—but must not ask certain other questions, and so on, and so on.
Beyond the miasma of applicable law, we also have the following problems to contend with.
There is no guarantee on the order in which data arrives. For instance, queries for a credit check or title search may take a substantial amount of time, while items such as name and address may be available immediately.
Data gathering may be done by different people, distributed across different offices, in different time zones.
Some data gathering may be done automatically by other systems. This data may arrive asynchronously as well.
Nonetheless, certain data may still be dependent on other data. For instance, you may not be able to start the title search for a car until you get proof of ownership or insurance.
Arrival of new data may raise new questions and policies. Suppose the credit check comes back with a less than glowing report; now you need these five extra forms and perhaps a blood sample.
You can try to handle every possible combination and circumstance using a workflow system. Many such systems exist, but they can be complex and programmer intensive. As regulations change, the work-flow must be reorganized: people may have to change their procedures and hard-wired code may have to be rewritten.
A blackboard, in combination with a rules engine that encapsulates the legal requirements, is an elegant solution to the difficulties found here. Order of data arrival is irrelevant: when a fact is posted it can trigger the appropriate rules. Feedback is easily handled as well: the output of any set of rules can post to the blackboard and cause the triggering of yet more applicable rules.
Tip 43
Use Blackboards to Coordinate Workflow
We can use the blackboard to coordinate disparate facts and agents, while still maintaining independence and even isolation among participants.
You can accomplish the same results with more brute-force methods, of course, but you'll have a more brittle system. When it breaks, all the king's horses and all the king's men might not get your program working again.
Do you use blackboard systems in the real world—the message board by the refrigerator, or the big whiteboard at work? What makes them effective? Are messages ever posted with a consistent format? Does it matter?
| 30. | For each of the following applications, would a blackboard system be appropriate or not? Why?
|
| I l@ve RuBoard |


Resource Title
Download A resource description contains useful descriptive information about the resource and its origins. It also describes what information is contained within the dataset so users are informed prior to downloading the resource.
Additional Information
- Identifier
- 2e10dc73-349f-4385-b3d0-a13c38f0037b
- Organisation
- Organisation
- Issued Date
- 3 October 2017
- Last Updated
- 23 September 2018
- Languages
- English, Urdu
- Licenses
- Access URL
- http://<IP_ADDRESS>/dataset/0ceb75bc-0a71-4be5-861e-e6600118f022/resource/97b02d3d-aff2-4b56-b474-23ded01fceb9/download/medical-stores-isb.json
- File Format
- CSV
- File Size
- 8.03 MB
Preview
File Preview...
6,574Datasets
45Organisations
24Groups
50Tags


Take Me to The Kitchen
January, 18th 2015
There are two areas of the restaurant: the dining room and the kitchen. The dining room is where people view the menu, make their order and prepare to experience their meal. They may complain to the waiter if their food is cold. They might fuss if they wait too long for the bill. It’s an enviroment for the consumer mindset.
The kitchen, on the other hand, is a big mess. Everyone is moving quickly, focusing on their work. It’s more of a, “outta my way!” type of environment. Everyone is jumping in and getting started. Dev Bootcamp is the kitchen.
Prior to starting phase zero, my impression of DBC was that it seems like an intense, fast-paced environment. In addtion to programming knowledge, DBC promotes vulnerable and open learning. To put it in simpler terms for my family and other “non-technical’ people, I like to use a construction metaphor.
“Pretend I’m taking a course to build a house in a very short amount of time,” I say. “Imagine learning all those skills very quickly; skills like how to reading blueprints, designing a sky light or using a nail gun. I'm setting out to acquire all those skills, in a short period of time, and then build my own house. That new house will be my resume."
My expectations remain the same after seeing the video. I’d be lying if I said I wasn’t nervous, because I definitely am. Beyond feeling nervous, I think the strongest emotion is that I know what I’m in for: DBC will be fast-paced. I'll have to be vulnerable and expose my weaknesses, and a lot of my ignorance, to my cohort. Most importantly, it's me to get the work done and acquire the skills I need to build my dream house. I’m ready!


This example shows that slideshow can be instantiated even if it's hidden or inside a hidden element. In such cases, slideshow internally delays the initialization until it's displayed. Same technique is used to resize slideshow when it's hidden. Supported only in latest version of all browsers.


Geocoding historical adresses
Adresse :
Date :
Maximum number of results :
Do you want precise (house number) or rough (street, neighboourhood, city) localisation
use precise lcoalisation
Geocode!
(OPTIONAL) Editing already geocoded adresses
RUID : Permanent key to your geocoding results:
(OPTIONAL) export results as csv
Export results associated to curretnruid as CSV file
(Will open a new tab, click then on "save as csv button")
Geocoding point properties
User provided geocoding query
historical name
normalized name
fuzzy date
Historical source
Numerical origin process
Aggregated distance
Spatial precision (m)
Confidence in result
Semantic distance
Temporal distance
Building number distance


If you specify a name, Hudson will assign a unique port number as an environment variable. This is preferable as it lets Hudson manage TCP port allocations. To avoid platform specific issues, all upper case names are recommended.
If you specify a numeric value, Hudson will make sure that port number is reserved while a build is in progress. As a result of this, builds may block while another build that uses the same port number is in progress. This is useful when your build hard-codes a port number and you cannot change that.


@use super::page; @(access_token: &str, canvas_course_id: &str, sis_course_id: &str, modules: &[(String, i32, String)]) @:page("Copy results to Ladok", {
Results from the exportable column(s) in the gradebook of @sis_course_id will be copied to Ladok, where they will appear as results in draft status.
After that, you need to log in to ladok to mark the results as ready, after which the examiner can attest them.
The following module(s) will be exported: