PyCharm suppress inspections list

I've been searching for a complete reference to PyCharm's #noinspection markup for some time. I found #noinspection PyUnresolvedReferences for suppressing the warning about an unused import statement with Google, and I was able to guess at PyProtectedMember myself, but it was clear that many remained.

Unfortunately the tooltip action in PyCharm only gives the option to suppress some warnings, revealing for instance the #noinspection PyBroadException markup but few others.

I decided I had had enough and used the excellent Agent Ransack to search for PyUnresolvedReferences within the installation directory. Once I found it I was able to extract the rest. I believe the following to be a complete list. I've found PyArgumentList to be particularly useful when PyCharm is upset about valid syntax (e.g. the functional syntax for enumerations in Python 3.4: enum.Enum('vehicle', 'car bicycle truck') or modules with opaque functions).

PyAbstractClass
PyArgumentEqualDefault
PyArgumentList
PyAssignmentToLoopOrWithParameter
PyAttributeOutsideInit
PyAugmentAssignment
PyBroadException
PyByteLiteral
PyCallByClass
PyCallingNonCallable
PyChainedComparisons
PyClassHasNoInit
PyClassicStyleClass
PyComparisonWithNone
PyCompatibility
PyDecorator
PyDefaultArgument
PyDeprecatedModules
PyDeprecation
PyDictCreation
PyDictDuplicateKeys
PyDocstring
PyDocstringTypes
PyExceptClausesOrder
PyExceptionInherit
PyFromFutureImport
PyGlobalUndefined
PyInconsistentIndentation
PyInitNewSignature
PyInterpreter
PyListCreation
PyMandatoryEncoding
PyMethodFirstArgAssignment
PyMethodMayBeStatic
PyMethodOverriding
PyMethodParameters
PyMissingConstructor
PyNestedDecorators
PyNonAsciiChar
PyNoneFunctionAssignment
PyOldStyleClasses
PyPackageRequirements
PyPep8
PyPep8Naming
PyPropertyAccess
PyPropertyDefinition
PyProtectedMember
PyRaisingNewStyleClass
PyRedeclaration
PyRedundantParentheses
PyReturnFromInit
PySetFunctionToLiteral
PyShadowingBuiltins
PyShadowingNames
PySimplifyBooleanCheck
PySingleQuotedDocstring
PyStatementEffect
PyStringException
PyStringFormat
PySuperArguments
PyTrailingSemicolon
PyTupleAssignmentBalance
PyTupleItemAssignment
PyTypeChecker
PyUnboundLocalVariable
PyUnnecessaryBackslash
PyUnreachableCode
PyUnresolvedReferences
PyUnsupportedFeatures
PyUnusedLocal

Discussion

Deploying Django 1.7 (Python 3) on Ubuntu 14.04

Since the DigitalOcean guide is out of date, here's a new one as short as possible using the default sqlite instead of postgres for simplicity.

Patch:

$ sudo apt-get update
$ sudo apt-get upgrade

We'll use pyvenv-3.4 because virtualenv is for Python 2.
It was shipped in Ubuntu 14.04 with a broken pip, so we'll repair that as well as create our virtual environment at /opt/djenv:

$ pyvenv-3.4 --without-pip /opt/djenv
$ cd /opt/djenv
$ source bin/activate
(djenv) $ curl https://bootstrap.pypa.io/get-pip.py | python

(deactivate exits the virtual environment and source /opt/djenv/bin/activate enters it)

Install django and gunicorn much like Robin Winslow describes on his blog:

(djenv) $ which pip         # check pip points to the right place
/opt/djenv/bin/pip
(djenv) $ pip install django django-extensions     # install django dependencies
(djenv) $ pip install gunicorn
(djenv) $ pip freeze        # see our installed dependencies
Django==1.7.1
django-extensions==1.4.9
gunicorn==19.1.1
six==1.8.0
(djenv) $ django-admin.py startproject projectname  # create new django project
(djenv) $ pip freeze > projectname/requirements.txt # save dependencies into project

The Django 1.7 tutorials haven't quite caught up, when you deploy you'll need to add 127.0.0.1 or localhost to ALLOWED_HOSTS within settings.py or you'll get a Bad Request (400) error when DEBUG = False, answered in this Stack Overflow question.

ALLOWED_HOSTS = ['127.0.0.1', 'localhost']

The deployed static file setup can also be a little confusing. You'll create a new, empty folder on your webserver named static wherever you'd like - root project folder perhaps, alongside manage.py. Specify the full path to this folder within your settings.py as STATIC_ROOT, and whatever relative URL you desire and will be configuring within nginx as STATIC_URL, e.g.:

STATIC_URL = '/static/'
STATIC_ROOT = '/opt/djenv/projectname/static/'

Whenever you change your actual static files, likely located in paths such as /opt/djenv/projectname/appname/static/appname/ and /opt/djenv/projectname/otherappname/static/otherappname/ you need to re-run the collectstatic command so they'll all be gathered and automatically copied into the folder we created - you'll never do this manually:

(djenv) /opt/djenv/projectname$ ./manage.py collectstatic

And of course you must have nginx configured to serve both django running on gunicorn and static files, something like:

server {
    server_name yourdomainorip.com;

    access_log off;

    location /static/ {
        alias /opt/djenv/static/;
    }

    location / {
            proxy_pass http://127.0.0.1:8001;
            proxy_set_header X-Forwarded-Host $server_name;
            proxy_set_header X-Real-IP $remote_addr;
            add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
    }
}

Launching gunicorn with gunicorn_django is deprecated, instead of gunicorn_django --workers=3 --bind yourdomainorip.com:8001 you'll want to use something like:

(djenv) /opt/djenv/projectname$ gunicorn --env DJANGO_SETTINGS_MODULE=projectname.settings projectname.wsgi:application --bind 127.0.0.1:8001

Finally you can configure gunicorn to launch automatically with an Upstart script /etc/init/gunicorn.conf:

start on startup

script
  . /opt/djenv/bin/activate
  cd /opt/djenv/projectname
  gunicorn --env DJANGO_SETTINGS_MODULE=projectname.settings projectname.wsgi:application --bind 127.0.0.1:8001
end script

You can also control it via command-line e.g.: start gunicorn stop gunicorn restart gunicorn.

Discussion

Raspberry Pi Ajax JavaScript display

3 Raspberry Pis

I recently created a couple eBay store slideshows for a local business. I used two Raspberry Pi's and some CoffeeScript code to fetch images asynchronously. I may release the code later, for now here's an annotated shell script for configuring the Raspberry Pi's.

I sourced these steps from various online guides and did my best to understand each of the command parameters and eliminate those that were superfluous. I also attempted to be consistent in my auto-startup methods, to the best of my ability.

One unique attribute of this configuration is the ability to VNC into either the publicly visible desktop, or a private desktop.

Nginx is installed as a basic webserver because opening our html file locally (file://) doesn't support cross-domain headers for our AJAX requests.

Node.js is installed simply for its package manager, which is used to install the standalone corsproxy tool. This is a simple local proxy for bypassing the same-origin policy restriction that would prevent our cross-domain AJAX requests from succeeding. (I preface my AJAX request URLs with http://localhost:9292/ to use the proxy.)

Other components include hiding the mouse cursor on inactivity and keeping the Raspberry Pi awake.

Chromium is the browser of choice here. I experimented with numerous others but the benefit of similarity to my development environment (Google Chrome) was too great.

This script also configures nginx and sets the site to launch on startup. It assumes the web folder to be at /home/pi/Desktop/web-js and opens main.html, you may need to change these.

When connecting to the Pi with VNC, the public display will be port 5900, the private 5901.

#!/bin/sh

apt-get update

# install x11vnc server for public desktop access (display 0)
apt-get -y install x11vnc

# configure to auto-start
mkdir /home/pi/.config/autostart
cat <<EOM >/home/pi/.config/autostart/x11vnc.desktop
[Desktop Entry]
Encoding=UTF-8
Type=Application
Name=X11VNC
Exec=x11vnc -forever -usepw -bg -ultrafilexfer -display :0
StartupNotify=false
Terminal=false
Hidden=false
EOM

# install tightvncserver for a separate private desktop (display 1)
apt-get -y install tightvncserver

# configure to auto-start
mkdir /home/pi/.config/autostart
cat <<EOM >/home/pi/.config/autostart/tightvnc.desktop
[Desktop Entry]
Encoding=UTF-8
Type=Application
Name=TightVNC
Exec=vncserver :1 -geometry 1600x900 -depth 16 -pixelformat rgb565:
StartupNotify=false
Terminal=false
Hidden=false
EOM

# install basic webserver nginx to handle cross-domain headers (file:// won't work)
apt-get -y install nginx

# configure
cat <<EOM >/etc/nginx/sites-available/web-js
server {
    root /home/pi/Desktop/web-js;
    index main.html
    server_name localhost;
}
EOM

# enable site, disable default
cd /etc/nginx
rm sites-enabled/default
ln -s /etc/nginx/sites-available/web-js sites-enabled/web-js

# install node.js for node package manager
cd ~
wget http://node-arm.herokuapp.com/node_latest_armhf.deb
dpkg -i node_latest_armhf.deb

# install standalone corsproxy tool
npm install -g corsproxy

# hide cursor on inactivity
apt-get -y install unclutter

# install chromium browser
apt-get -y install chromium

# remove chrome didn't shut down safely restore tabs yellow bar
# (this doesn't appear to work)
sed -i 's/"exited_cleanly": false/"exited_cleanly": true/' /home/pi/.config/chromium/Default/Preferences

# keep raspberry pi awake & launch app on startup
cat <<EOM >/etc/xdg/lxsession/LXDE/autostart
# commented these out
#@lxpanel --profile LXDE
#@pcmanfm --desktop --profile LXDE
#@xscreensaver -no-splash

@xset s off
@xset -dpms
@xset s noblank
@corsproxy
@chromium --disable-hang-monitor --kiosk --disable-java --disable-restore-session-state --disable-sync --disable-translate http://localhost
EOM

reboot

Discussion

Most d20 dice are notably imbalanced

I recently saw the question asked How accurate are the d20 dice used in role playing games? on the skeptics stack exchange website.

There's a very persuasive and popular video of Lou Zocchi speaking about his GameScience dice. Essentially the sharper the edges on the die the more fair and balanced the roll, and the difference is a notable one.

Over at 1000d4 there's a closeup of Zocchi's dice comparison chart and an excellent article with their own updated comparison of GameScience dice dimensions to other manufacturers. His dice are indeed highly consistent.

The Awesome Dice blog conducted a thorough comparison of a GameScience d20 with a Chessex d20 rolling them 10,000 times each. The GameScience die is more fair except the number 14 rolls significantly less often because the opposite side has a chunk of plastic from being snipped off the mold. (Rounder dice like the Chessex have this but it's polished away with the rounding of the corners.)

So his dice are better than most, but still don't offer the equal access to every number we tend to expect from a die.

Delta's D&D Hotspot demonstrates how to use Pearson's chi-squared test to determine if a die is imbalanced. Around this time last year I conducted my own test with these methods, rolling an Orange, Purple, and Green Chessex d20 500 times each (a minimum for this test). In the following spreadsheets if the result is higher than the fairness limit for the number of rolls, the die is imbalanced.

Chessex Orange, Green, and Purple

The results were frightening. My intuitive "feel" of the die wasn't superstitious but actually quite correct! My Purple d20 really is strongly biased in favor of rolling 1's and 20's. Also the Green d20 has a very noticeable deformation on the 17, opposite the 4. When the die is showing 4, it wobbles unevenly. The data shows this bias away from 4 quite clearly.

What does it all mean? Cheap dice do in fact suffer from a dramatic imbalance, Lou Zocchi was correct. Though even his have a bias against 14. Thus I haven't switched to his die, instead I now use a pseudorandom number generator

Rolling Pebble, Pebble watch app

that I know to have a uniform distribution. Choosing die specific to the situation feels too much like cheating. It's an unfortunate discovery but true nevertheless.

Data

Orange 638 < 754 Balanced (Probably)

Green 1,940 > 754 Imbalanced

Purple 858 > 754 Imbalanced

Discussion

Fixing Exchange email alerts in Symantec Backup Exec

(Exchange 2010 SP3) Sending email from Symantec Backup Exec 2010 as Administrator is problematic, through both SMTP and MAPI. The Administrator account is locked down to prevent this by default and apparently "re-stamped" with permissions on a certain basis so you really don't want to attempt to lift the restriction.

You can verify the lockout with PowerShell from the server running Backup Exec:

Send-MailMessage -To someone@somewhere.local -From someone@somewhere.local -Subject test

The logged in (Administrator's) credentials are used, and it will appear to succeed but in fact fail silently. The Exchange server will receive "The account DOMAIN\Administrator provided valid credentials, but is not authorized to use the server" in its Application log.

The failure is even more silent within Backup Exec when you test email notification. What will error is configuring MAPI, with a message that the server cannot be found, which appears inaccurate.

The solution is to use an alternative account with administrative privileges for Backup Exec:

  1. Create a new account in the Administrators or Domain Administrators group depending on your requirements.
  2. Within Backup Exec, proceed to Tools → Backup Exec Services… → Services credentials… → Change service account information.
  3. Check Grant Backup Exec system service rights to the service account.
  4. You will need to Restart all services after the change.
  5. You'll want to change the Network logon account to match: Network → Logon Accounts… → Edit…

This should be sufficient. In reality I added the account to the Create a token object and Log on as a service user rights in the server's group policy according to this Symantec document (the other rights are provided as a member of Administrators). However I believe this is what the Grant Backup Exec system service rights to the service account option does?

After this I gave the account a mailbox on Exchange and was able to configure email alerts from Backup Exec from that mailbox without issue.

Discussion