Main Site

This is Gem Newman's blog. Return to the main site.

Quotation

Showing posts with label computers. Show all posts
Showing posts with label computers. Show all posts

16 January 2017

LUEE Episode 116: Risk

On this episode of Life, the Universe & Everything Else, Ashlyn, Laura, Gem, and Lauren talk about how bad we are at assessing risk. Also on this episode: Do we get more risk averse as we get older? Is margarine going to kill you, or will a hippopotamus get you first? Will the world end not with a bang but a Boolean?

Life, the Universe & Everything Else is a program promoting secular humanism and scientific skepticism that is produced by the Winnipeg Skeptics.

Note: Music featured in this episode include samples from "Death from the Skies" by George Hrab (featuring Phil Plait), "Paranoid Android" by Radiohead, and "Binnorie" by Mediæval Bæbes.

Links: Relative risk (Wikipedia) | Spreading disease or spreading deliciousness: the butter vs. margarine debate rages on (dietitian at home) | Global catastrophic risk (Wikipedia) | Death from the Skies! (Wikipedia) | Holocene extinction (Wikipedia) | Existential risk from artificial general intelligence (Wikipedia) | AI Risk Analysts are the Biggest Risk (Singularity Weblog) | There is a blind spot in AI research (Nature News) | Program good ethics into artificial intelligence (Nature News & Comment ) | TRC #429.5: Programming Ethics Into AI (The Reality Check) | Potential Risks from Advanced Artificial Intelligence: The Philanthropic Opportunity (Open Philanthropy Project ) | If Aliens Exist, They May Come to Get Us, Stephen Hawking Says (Space.com) | Risk Preferences and Aging: The "Certainty Effect" in Older Adults' Decision Making (Journal of Psychology and Aging) | Differences in risk aversion between young and older adults (NAN) | Differences in Risk Aversion between Young and Older Adults (Neuroscience and Neuroeconomics) | Aging and loss decision making: increased risk aversion and decreased use of maximizing information, with correlated rationality and value maximization | It is surprisingly rare for an alligator to kill a person (BBC Earth) | Chart: The animals that are most likely to kill you this summer (The Washington Post) | The Odds of Dying | 25 shocking things more likely to kill you than a shark (WNYY) | Choking Prevention and Rescue Tips | 10 Things More Likely to Kill You than Islamic Terror | List of selfie-related injuries and deaths (Wikipedia) | Animal bites (WHO)

Contact Us: Facebook | Twitter | Email

Listen: Direct Link | iTunes | Google Play | Stitcher | RSS Feed

30 May 2016

tread

I made a thing. It's called tread, and it's a simple terminal RSS feed reader that I wrote in Python.


tread has most of the basic features you would expect from a feed reader, including read/unread tracking and starred items. It even supports displaying images via imgii. And if you don't mind fiddling with a YAML file, it's also fairly configurable.

Since it's available on PyPI, installing tread is actually pretty easy:

pip3 install tread

The source code, along with the readme and basic usage instructions, is available here. (But fair warning: the code is awful, and you don't want to look at it too closely.) I do not guarantee it to be bug-free (in fact, I guarantee the opposite!), but if for some reason you want a Google Reader replacement that runs in a terminal window, I've got you covered.

Because of some esoteric requirements of curses (the most aptly named library, as bcj is fond of pointing out), tread requires Python 3.5 and does not run natively on Windows.

20 February 2015

Configuring Flask, uWSGI, and Nginx (Updated!)

This is an updated version of a previous post, which is preserved here.


In a departure from what I often write about, I'm going to talk a little bit about something that is tangentially related to what I actually do for a living: running a web server. So I'm going to give a brief tutorial on setting up uWSGI (in Emperor mode) and Nginx so that you can run one or more Python Flask instances on a server.

Installation
Flask
uWSGI
Nginx
Port Forwarding
Sources

Why? Well, I'm far from a pro at anything related to networking or web development, but I have been writing a few web tools lately just for fun. Initially, I had several different Flask/Werkzeug instances running in what was essentially a dev mode on different ports on my server, and I had each of these ports forwarded. But...


...this was ungainly, running multiple Werkzeug instances was inefficient, I didn't want to have to forward all of those ports, and damn it, I wanted to do things right. But, as this isn't my area of expertise, it took me a while to put all of these pieces together, because many of the examples that I was able to find were light on the details. I'm putting this here in the hope that someone else in my situation might find it useful.

Installation

So here are the relevant details. I'm running Ubuntu 14.04 and I'm using Python 3.4 (and 2.7.9), Flask 0.10, uWSGI 2.0.9, and Nginx 1.1.19. If you are missing any of these, you'll want to install them with your package manager of choice.* For example:

$ sudo apt-get install python
$ sudo apt-get install uwsgi
$ sudo apt-get install nginx
$ pip3 install flask

Some caveats: First, if you're running Python 2.x, you'll want to ensure that Flask is available for it, as well. (You can try pip install flask, depending on your configuration.) Second, if you're planning to run multiple Flask applications using multiple versions of Python, you may have to build uWSGI core from source and specify which Python plugin to use for each application. Building uWSGI from source isn't the worst thing in the world; instructions for building the application and the necessary plugins are available here.

The goal here is to run multiple Flask servers on one machine without having to worry about port numbers and the like. We'll start with just one, and I'm sure that you can figure the rest out from there.

Flask

First you need a Flask application to run. How about this one? I wrote it a few months ago because I wanted to translate GET requests to POST requests. (At the time that I'm writing this, that particular application hasn't been updated to use Python 3.)

Navigate to the directory you'd like to install it to (probably /opt/ or /var/www/), then clone it. You'll want to verify that it runs locally on its own first.

$ cd /opt
$ git clone https://github.com/spurll/post.git
$ post/run.py

In a web browser on the same server, navigate to http://localhost:9999 and verify that the application is accessible. If you're running headless (as I am) you can always spawn the process to the background with post/run.py & and then curl localhost:9999 and verify that you don't get an error back. You can now kill the Python process.

Flask is now set up!

uWSGI

First, test that uWSGI will run your application correctly on its own:

$ cd /opt/post
$ uwsgi --socket 127.0.0.1:9999 --protocol=http -w run:app

In this case, run is the name of the Python source file that contains our application (/opt/post/run.py) and app is the name of the Werkzeug/Flask application object contained in that file. Verify that the application is accessible again from http://localhost:9999 as above.

If everything is working correctly, kill the uWSGI instance. It's now time to configure uWSGI's Emperor mode. This allows us to essentially have one master process that oversees all of our web applications, starting (and restarting) them when needed and logging as appropriate. You will probably have to install a few plugins, too, using your package manager of choice. (Note that if you want to support multiple Python versions, you may need to build these plugins from source, as mentioned above.) Assuming you want to use the standard plugins:

$ sudo apt-get install uwsgi-plugin-python
$ sudo apt-get install uwsgi-plugin-http

By default, your uWSGI master configuration file will probably be located at /etc/init/uwsgi.conf. Edit it with your editor of choice (I'm a Vim guy, myself):

$ sudo vim /etc/init/uwsgi.conf

It should look something like this:

description "uWSGI"
start on runlevel [2345]
stop on runlevel [06]
respawn

env UWSGI=/usr/bin/uwsgi
env LOGTO=/var/log/uwsgi/emperor.log

exec $UWSGI --master --emperor /etc/uwsgi/apps-enabled --die-on-term --uid www-data --gid www-data --logto $LOGTO

You can change the location of the Emperor's log file by changing the LOGTO environment variable. You can also modify which user (--uid) and group (--gid) the Emperor will run as.

Now it's time to configure the applications. Your application-specific configuration files (in this case, for the POST program that we installed to /opt/post/) will probably be found at /etc/uwsgi/apps-available/. Create a new file there and call it post.ini. It should like something like this:

[uwsgi]

# Variables
url_mount = /%n
base = /opt/%n
app = run
callable = app

# Plugins
plugins-dir = /usr/lib/uwsgi/plugins
plugins = python,http

# URL Script Mounting
mount = %(url_mount)=%(base)/%(app).py
manage-script-name = true

# Generic Config
pythonpath = %(base)
venv = %(base)/venv            # If using virtualenv
socket = /opt/run/%n.sock
module = %(app)
logto = /var/log/uwsgi/%n.log

Here, url_mount is the mount-point for the application (for example, if you're running the application at http://www.yourserver.com/post, the value would be /post), base is the base directory of our application (the directory that contains the module we want to run), app contains the name of the module to run (in this case run, for run.py), callable is the name of the Werkzeug/Flask callable application object (if you don't supply this, uWSGI will assume that it's called application), and socket defines the location of the socket you'd like Nginx to use when communicating with your uWSGI server. The %n references the name of our file (sans extension) to maintain consistency.

You'll need to ensure that the location of your sockets (in this case, /opt/run/) exists and that the appropriate user (in this case, www-data) has write permissions.

This configuration assumes that you want to run your program using the modules installed on your system's Python. Plugins might prove to be an issue. You'll want to point plugins-dir to the appropriate path, and make sure that you have the appropriate plugin. If you're running Python 3.x (or you want to specify a specific Python plugin for uWSGI for some other reason), you can point plugins at something like python34 (which you may have to build) instead.

To run the application in a virtual environment, you can add a line defining home:

home = %(base)/virtualenv

Where virtualenv is the directory containing the Python virtual environment you'd like to use. (In our case, that would be at /opt/post/virtualenv/, if we were using a virtual environment.)

Once you're ready, create a symbolic link to place the post.ini file you've created in the apps-enabled directory:

$ sudo ln -s /etc/uwsgi/apps-available/post.ini /etc/uwsgi/apps-enabled/post.ini

You can start the uWSGI process (if you haven't already) like this:

$ sudo service uwsgi start

As soon as your Emperor process sees an application configuration file in apps-enabled it will start up a uWSGI instance to serve requests for that application. If you'd like to set up additional Flask applications at this time, simply install them and create uWSGI configuration files for each (and don't forget to link them to apps-enabled!). If you're having trouble, take a look at the logs (which are probably in /var/log/uwsgi/).

The uWSGI Emperor is now set up!

Nginx

We're almost there!

The default configuration file for Nginx should be located at /etc/nginx/sites-available/default. Feel free to edit this one, or create your own. By default, Nginx will point requests on port 80 (the default HTTP port) to /usr/share/nginx/www. If you'd like to point them somewhere else (such as /var/www/) you can change that here. Here's a brief Nginx configuration file that you can use to run connect your uWSGI server to the outside world:

# server unix:///path/to/your/site.sock; # For a file socket.
# server 127.0.0.1:9999;                 # For a port.

upstream post {
    server unix:///opt/run/post.sock;
}

server {
    listen 80;
    server_name your.server.url;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    root /var/www;
    index index.html index.htm;

    # GET to POST
    location /post {
        include uwsgi_params;
        uwsgi_pass post;
    }
}

Replace your.server.url with the URL for your server (you can use localhost for testing purposes). This configuration assumes that you'd like your application to be accessible at http://your.server.url/post. If you'd like it to take the place of the main page at http://your.server.url/, modify the location appropriately.

Note that current versions of uWSGI no longer support the (long-deprecated) uwsgi_modifier1 30; to pass this mount information on to uWSGI, so if you're running multiple applications (or don't want to host your application on /) you will probably want to pay attention to the script mounting information for uWSGI above.

Once you're done, create a soft link to /etc/nginx/sites-enabled/ for each of the entries in /etc/nginx/sites-available/. Now you can start your Nginx service.

$ sudo service nginx start

Every time you modify the Nginx configuration file, you'll have to restart the it.

Port Forwarding

If you're running this server from your home or office and you need external access, don't forgot to forward port 80 so that Nginx is accessible. Instructions for your router are probably available here.

Sources

I used several sites while putting this all together. If you're stuck, they may contain additional information that I neglected to include here. Here are the most helpful of the bunch:

Deploying Flask on uWSGI
Multiple Django and Flask Sites with Nginx and uWSGI Emperor
How to Setup Nginx
uWSGI Example Configuration

I also had some help from my friends and colleagues BCJ and Curtis when I was initially setting up Nginx. Thanks, gents!


* Since you're probably not going to be running uWSGI under your own user account, you'll probably want to either use a virtual environment or satisfy any package requirements via sudo pip3. Otherwise, you will probably end up with errors like:

Traceback (most recent call last):
  File "/opt/post/run.py", line 9, in 
    from post import app
  File "/opt/post/post/__init__.py", line 1, in 
    from flask import Flask
ImportError: No module named 'flask'

22 September 2014

Configuring Flask, uWSGI, and Nginx

An updated version of this post, which covers uWSGI 2.0.9 and Python 3.4 is available here.


In a departure from what I often write about, I'm going to talk a little bit about something that is tangentially related to what I actually do for a living: running a web server. So I'm going to give a brief tutorial on setting up uWSGI (in Emperor mode) and Nginx so that you can run one or more Python Flask instances on a server.

Why? Well, I'm far from a pro at anything related to networking or web development, but I have been writing a few web tools lately just for fun. Initially, I had several different Flask/Werkzeug instances running in what was essentially a dev mode on different ports on my server, and I had each of these ports forwarded. But...


...this was ungainly, running multiple Werkzeug instances was inefficient, I didn't want to have to forward all of those ports, and damn it, I wanted to do things right. But, as this isn't my area of expertise, it took me a while to put all of these pieces together, because many of the examples that I was able to find were light on the details. I'm putting this here in the hope that someone else in my situation might find it useful.

Installation

So here are the relevant details. I'm running Ubuntu 12.04 (I know, I know, I should update) and I'm using Python 2.7.2, Flask 0.10, uWSGI 2.0.6, and Nginx 1.1.19. If you are missing any of these, you'll want to install them with your package manager of choice. For example:

$ sudo apt-get install python
$ sudo apt-get install uwsgi
$ sudo apt-get install nginx
$ pip install flask

The goal here is to run multiple Flask servers on one machine without having to worry about port numbers and the like. We'll start with just one, and I'm sure that you can figure the rest out from there.

Flask

First you need a Flask application to run. How about this one? I wrote it a few months ago because I wanted to translate GET requests to POST requests.

Navigate to the directory you'd like to install it to (probably /opt/ or /var/www/), then clone it. You'll want to verify that it runs locally on its own first.

$ cd /opt
$ git clone https://github.com/spurll/post.git
$ post/run.py

In a web browser on the same server, navigate to http://localhost:9999 and verify that the application is accessible. If you're running headless (as I am) you can always spawn the process to the background with post/run.py & and then curl localhost:9999 and verify that you don't get an error back. You can now kill the Python process.

Flask is now set up!

uWSGI

First, test that uWSGI will run your application correctly on its own:

$ cd /opt/post
$ uwsgi --socket 127.0.0.1:9999 --protocol=http -w run:app

In this case, run is the name of the Python source file that contains our application (/opt/post/run.py) and app is the name of the Werkzeug/Flask application object contained in that file. Verify that the application is accessible again from http://localhost:9999 as above.

If everything is working correctly, kill the uWSGI instance. It's now time to configure uWSGI's Emperor mode. This allows us to essentially have one master process that oversees all of our web applications, starting (and restarting) them when needed and logging as appropriate. You will probably have to install a few plugins, too, using your package manager of choice. For example:

$ sudo apt-get install uwsgi-plugin-python
$ sudo apt-get install uwsgi-plugin-http

By default, your uWSGI master configuration file will probably be located at /etc/init/uwsgi.conf. Edit it with your editor of choice (I'm a Vim guy, myself):

$ sudo vim /etc/init/uwsgi.conf

It should look something like this:

description "uWSGI"
start on runlevel [2345]
stop on runlevel [06]
respawn

env UWSGI=/usr/bin/uwsgi
env LOGTO=/var/log/uwsgi/emperor.log

exec $UWSGI --master --emperor /etc/uwsgi/apps-enabled --die-on-term --uid www-data --gid www-data --logto $LOGTO

You can change the location of the Emperor's log file by changing the LOGTO environment variable. You can also modify which user (--uid) and group (--gid) the Emperor will run as.

Now it's time to configure the applications. Your application-specific configuration files (in this case, for the POST program that we installed to /opt/post/) will probably be found at /etc/uwsgi/apps-available/. Create a new file there and call it post.ini. It should like something like this:

[uwsgi]

# Variables
base = /opt/post
app = run
callable = app

# Generic Configuration
plugins = http,python
pythonpath = %(base)
socket = /opt/run/%n.sock
module = %(app)
logto = /var/log/uwsgi/%n.log

Here, base is the base directory of our application (the directory that contains the module we want to run), app contains the name of the module to run (in this case run, for run.py), callable is the name of the Werkzeug/Flask callable application object (if you don't supply this, uWSGI will assume that it's called application), and socket defines the location of the socket you'd like Nginx to use when communicating with your uWSGI server. The %n references the name of our file (sans extension) to maintain consistency.

You'll need to ensure that the location of your sockets (in this case, /opt/run/) exists and that the appropriate user (in this case, www-data) has write permissions.

This configuration assumes that you want to run your program using the modules installed on your system's Python. To run the application in a virtual environment, add a line defining home:

home = %(base)/virtualenv

Where virtualenv is the directory containing the Python virtual environment you'd like to use. (In our case, that would be at /opt/post/virtualenv/, if we were using a virtual environment.)

Once you're ready, create a symbolic link to place the post.ini file you've created in the apps-enabled directory:

$ sudo ln -s /etc/uwsgi/apps-available/post.ini /etc/uwsgi/apps-enabled/post.ini

You can start the uWSGI process (if you haven't already) like this:

$ sudo service uwsgi start

As soon as your Emperor process sees an application configuration file in apps-enabled it will start up a uWSGI instance to serve requests for that application. If you'd like to set up additional Flask applications at this time, simply install them and create uWSGI configuration files for each (and don't forget to link them to apps-enabled!). If you're having trouble, take a look at the logs.

The uWSGI Emperor is now set up!

Nginx

We're almost there!

The default configuration file for Nginx should be located at /etc/nginx/sites-available/default. Feel free to edit this one, or create your own. By default, Nginx will point requests on port 80 (the default HTTP port) to /usr/share/nginx/www. If you'd like to point them somewhere else (such as /var/www/) you can change that here. Here's a brief Nginx configuration file that you can use to run connect your uWSGI server to the outside world:

# server unix:///path/to/your/site.sock; # For a file socket.
# server 127.0.0.1:9999;                 # For a port.

upstream post {
    server unix:///opt/run/post.sock;
}

server {
    listen 80;
    server_name your.server.url;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    root /var/www;
    index index.html index.htm;

    # GET to POST
    location /post {
        include uwsgi_params;
        uwsgi_param SCRIPT_NAME /post;
        uwsgi_modifier1 30;
        uwsgi_pass post;
    }
}

Replace your.server.url with the URL for your server (you can use localhost for testing purposes). This configuration assumes that you'd like your application to be accessible at http://your.server.url/post. If you'd like it to take the place of the main page at http://your.server.url/, things are even simpler:

...
    # GET to POST
    location / {
        include uwsgi_params;
        uwsgi_pass post;
    }
}

Once you're done, create a soft link to /etc/nginx/sites-enabled/ for each of the entries in /etc/nginx/sites-available/. Now you can start your Nginx service.

$ sudo service nginx start

Every time you modify the Nginx configuration file, you'll have to restart the it.

Port Forwarding

If you're running this server from your home or office and you need external access, don't forgot to forward port 80 so that Nginx is accessible. Instructions for your router are probably available here.

Sources

I used several sites while putting this all together. If you're stuck, they may contain additional information that I neglected to include here. Here are the most helpful of the bunch:

Deploying Flask on uWSGI
Multiple Django and Flask Sites with Nginx and uWSGI Emperor
How to Setup Nginx

I also had some help from my friends and colleagues BCJ and Curtis when I was initially setting up Nginx. Thanks, gents!

15 September 2014

LUEE Episode 88: Experimenting on Your Thoughts

In this extended round-table episode of Life, the Universe & Everything Else, Gem is joined by Ashlyn, Ian, and Laura to discuss thought experiments that range from the classical to the incomprehensible to the downright bizarre.

Life, the Universe & Everything Else is a program promoting secular humanism and scientific skepticism that is produced by the Winnipeg Skeptics and the Humanists, Atheists & Agnostics of Manitoba.

Announcement: We're going monthly! That means you'll get podcasts half as often, but we'll make the podcasts twice as awesome to make up for it!

Note: If any of our listeners are concerned about information hazards and wish to skip over the discussion of Roko's Basilisk, the content in question begins at the 1h24m mark and ends at 1h35m46s.

Links: Thought experiment (Wikipedia) | The Drowning Child | The Life You Can Save (Wikipedia) | Charity Reviews and Recommendations (GiveWell) | Foundation Beyond Belief | Prisoner's dilemma (Wikipedia) | Ship of Theseus (Wikipedia) | Children prefer certain individuals over perfect duplicates (ScienceDirect) | Original Position (Stanford Encyclopedia of Philosophy) | Original position (Wikipedia) | Timeless Decision Theory | Newcomb's paradox (Wikipedia) | Newcomb's problem (LessWrong Wiki) | Roko's Basilisk (r/Futurology) | Streisand effect (Wikipedia) | Thought Experiment (Futility Closet)

Contact Us: Facebook | Twitter | Email

Listen: Direct Link | iTunes | Stitcher | RSS Feed

15 September 2013

WiFi and Cell Phones: Should You Really Be Worried?

What follows is the text of my presentation from the Winnipeg Skeptics' fourth annual SkeptiCamp Winnipeg, an open conference celebrating science and critical thinking.


Some of this presentation is adapted from a 2013 position paper my project team wrote for Bad Science Watch last year as part of our investigation into anti-WiFi activism in Canada. Bad Science Watch is an independent, non-profit science advocacy organization that aims to protect Canadian consumers by countering bad science in media and politics. The organisation is always looking for volunteers (and, of course, donations!). You can find out more at BadScienceWatch.ca.

So, cell phones and WiFi: What seems to be the problem?

Well, the problem is in the last few years we have an increasing number of people who are complaining that radiation generated by our modern conveniences (like computers, cell phones, appliances, and power lines) is responsible for a host of debilitating ailments in certain people who are "electromagnetically hypersensitive". Activists are pushing for stricter government regulation, removal of wireless technology from schools, and radio-free zones.

To make sure that everyone's on the same page, I'll start with a bit of basic science.

First of all, what is radiation?

Well, "radiation" can mean a few different things. Generally, it's the process by which energetic waves or particles travel through space. If you want to classify radiation broadly, there are two main ways you can do it: first, you can ask, "Is it particle radiation or electromagnetic radiation?" and second, "Is it ionizing or non-ionizing?"

Particle Radiation

Particle radiation occurs when large, unstable elements decay into smaller, more stable elements. Particle radiation often comes in the form of alpha particles (groups of two protons and two neutrons), beta particles (which are free electrons or positrons), or free neutrons. This sort of radioactive decay also results in a little bit of electromagnetic radiation (in the form of gamma rays), which we'll talk about in a second. Particle radiation is a form of ionizing radiation (we'll get to that too, but generally speaking that's the bad stuff). We won't be talking much about particle radiation today, but when people talk about stuff being "radioactive" this is often what they mean.

Electromagnetic Spectrum

The second type of radiation is electromagnetic radiation. This is an energetic wave that propagates through space. Visible light is a type of electromagnetic radiation, and so are radio waves. EM radiation is a particular form of the more general electromagnetic field, which is a field produced by the movement of electrically charged objects, and which affects the behaviour of charged particles. Electromagnetic fields can be natural (the Earth and the Sun, for example, have their own EM fields), or they can be artificial. Artificial fields can be produced intentionally (microwaves use them to cook food, computers and phones use them to communicate), or they can be produced as a by-product of technology (pretty much anything that uses electricity will have an EM field).

Non-ionizing Electromagnetic Radiation

Unlike particle radiation (which is generally ionizing), electromagnetic radiation can be either ionizing or non-ionizing. Radiation at non-ionizing frequencies may be sufficiently powerful to cause substances to heat up, but is not powerful enough to strip electrons from molecules (creating ions) and break molecular bonds.

Ionizing Electromagnetic Radiation

The radio, microwave, infrared, and visible spectra are made up of non-ionizing radiation, while x-rays and gamma rays are forms of ionizing radiation, and ultraviolet radiation sort of straddles the line between the two.

High doses of non-ionizing radiation are known to cause thermal effects (think of putting your hand on an incandescent light bulb, or microwaving a pizza pocket), but low doses are not known to have any deleterious effects to living things. By contrast, high doses of ionizing radiation can result in serious burns and radiation sickness, while low, steady doses can result in genetic damage and cancerous tumours.

So that's generally what scientific investigations into radiation has found: ionizing radiation causes direct damage to living systems, and non-ionizing radiation doesn't (although it can heat stuff up). So what's electromagnetic hypersensitivity?

Electromagnetic hypersensitivity (or EHS) is a term used to describe the adverse, subjective medical symptoms that some people report experiencing after exposure to certain frequencies of non-ionizing electromagnetic radiation (generally, the weak fields produced by WiFi hotspots, cell phones, or power lines). The symptoms associated vary from patient to patient, but often include fatigue, inability to sleep, headache, stress, muscle aches, and rashes. Sufferers report that their symptoms are worse in the city than in the country, and that they're especially bad when they're in close proximity to a device (such as a mobile phone) that emits a wireless signal.

Determining the prevalence of EHS is difficult, and estimates vary wildly depending on who's asking the questions, with the World Health Organization reporting a few individuals per million, while surveys conducted by support groups peg the number as high as one in thirty. But the effects of this syndrome are not limited to those who describe themselves as hypersensitive. Because these symptoms can compromise quality of life, parents groups and teachers unions in Ontario and British Columbia are pressuring schools to remove all WiFi installations (with some success), a group called Citizens for Safe Technology is calling for BC Hydro to suspend its Smart Meter program, and according to news reports some sufferers taken to the hills, moving as far beyond the reach of cellular signals and power lines as they can.

So what's the deal? Are these symptoms real or is it "all in their heads"?

First of all: What I just did? Don't do that. While psychogenic illnesses certainly do exist (and we would do ourselves a great disservice to deny that), framing the issue in terms of diseases that are "real" or "all in your head" is, at best, unhelpful, not to mention wildly inaccurate.

So, let's try that again: Are these symptoms really caused by a sensitivity to electromagnetic fields, or is something else going on?

Well, in 2004 the World Health Organization held a workshop on electromagnetic hypersensitivity. The working group proposed that we should no longer refer to "EHS", because "electromagnetic hypersensitivity" implies a causal relationship between the reported symptoms and electromagnetic fields, and that relationship hasn't been established. Because the actual cause of these symptoms isn't known to be EMF, the WHO suggested that the syndrome be referred to as "idiopathic environmental intolerance attributed to electromagnetic fields" (or IEI-EMF) instead. Catchy, isn't it?

So that's where things stood in 2004: causality hadn't been established, and many scientists were skeptical, as there was no known mechanism by which non-ionizing radiation could result in these symptoms. How have things progressed since then?

Well, there's been a fair amount of research: some of it good, some of it not so good. The highest quality papers that we were able to identify involved double-blind, controlled provocation studies in which individuals who identified themselves as "hypersensitive" were exposed either to a source of EMF or to an inactive control. Subjects were asked to report on the severity of their symptoms, which allowed researchers to determine whether symptoms differed depending on whether the source of electromagnetic radiation was turned "on" or "off". While subjects reportedly experienced symptoms of EHS while in the presence of the device, researchers were able to find no consistent correlation between symptom severity and the presence or absence of electromagnetic fields. In addition, while many hypersensitive individuals claimed to be able to perceive the presence of EMF, it turned out that the majority were unable to do so under double-blind laboratory conditions. Is it just me, or does this remind anyone else of the JREF's million-dollar challenge?

While these and similar studies have fared well in replication and peer review, studies do exist purporting to show that EHS symptoms are correlated to EMF. However, they tend to exhibit basic methodological problems not present in the provocation trials. The body of the literature suggests that the symptoms of EHS are not caused by exposure to EMF, and several systematic reviews, including those published by Röosli in 2008 and Rubin et al. in 2010, concluded that the nocebo effect (the placebo effect's evil twin) played a significant role in the onset of EHS symptoms.

A 2006 study investigating several treatments for EHS symptoms, including "shielding" devices, "filters", supplementation, cognitive behavioural therapy, and even acupuncture, found that only cognitive behavioural therapy outperformed placebo. The body of available evidence suggests that electromagnetic hypersensitivity is a psychogenic disorder. EHS is frequently compared to other controversial idiopathic conditions such as chronic Lyme disease.

Rather than addressing the methodological problems identified in their research or investigating plausible alternative causes of EHS, activists in Canada have generally focused on limiting access to WiFi, Smart Meters, and other devices that they claim (without evidence) to be the cause of EHS. One of the most prominent promoters of the link between EHS and EMF in Canada is Dr. Magda Havas, who teaches environmental studies at Trent University. She's published many papers on the subject, including one that claims to show that EMF (somehow) increases blood sugar. Dr. Steven Novella points out that this particular paper is actually nothing more than a four-patient case study (a series of well-documented anecdotes). Additionally, exposure to EMF was often guessed-at instead of measured, and no blinding was employed at all.

Another Havas study (which apparently did not pass peer review) purported to show that use of cordless phones resulted in huge spikes in heart-rate on an EKG; however, when Lorne Trottier and Harvey Kofsky investigated, they were able to replicate the spike on the EKG when it wasn't even hooked up to a patient! The best explanation seems to be that the EKG was experiencing electrical interference from the cordless phone—something that is specifically warned about in the heart rate monitor's user manual.

Okay, enough about EMF. Don't cell phones and WiFi cause cancer? I remember reading about something about the WHO classifying cell phones as a carcinogen a few years ago, don't I?

No. Well, that's not actually true. The International Agency for Research on Cancer has classified radiofrequency electromagnetic fields in Group 2B, which means that they are "possibly carcinogenic". While this puts radio waves in the same category as DDT, it also puts them in the same category as coffee, pickles, and "being a carpenter". It's worth pointing out that beer, wine, and other alcoholic beverages actually fall under group 1 (the "definitely known to be carcinogenic" group).

There's a lot of nuance here, but I'll try to break it down. First of all, the categories aren't divided up by how carcinogenic we think they are; they're divided up by how sure we are that they're at least a little carcinogenic. If we're quite positive that they're a little bit carcinogenic (like alcohol), they go in Group 1. If the evidence shows that something is probably carcinogenic, it goes in Group 2A. If the evidence is quite muddled (as is the case with radiofrequency EMF), regardless of how carcinogenic we think it might be, it goes in Group 2B. So saying that cell phones are in the same category as DDT (or carpentry) can be misleading. It has nothing to do with how dangerous we think it might be, it has to do with how sure we are that it might be dangerous (in this case, not sure at all). Several large, randomized, controlled trials have found no link between cell phone use and cancer, while others have found a correlation. I don't have time to delve deep into the details today, but so far I'm not convinced.

Several companies market products aimed at "protecting" customers from the putative harmful effects of EMF, including "Stetzer" filters and cellphone cases designed to block electromagnetic radiation. These devices offer no demonstrated health benefit, and as for the cases, to the degree that they may indeed block EM radiation, they would also interfere with the functioning of your device: that "radiation" is how mobile phones work. But that won't stop companies from making a quick buck at the consumer's expense.

Smart Meter

I want to talk specifically about Smart Meters for just a moment. Is anyone familiar with these? They record your electricity usage, like any other meter, but they report readings back to the utility automatically. The thing is, they do so wirelessly, which is apparently the chief cause for concern, and the data that they gather is much more temporally specific, opening the door for pricing that differs by time of day or season. I want to point out that there are potential concerns related to these devices that do not relate to health. I think that making this distinction is important, and it's one I harp on quite a bit whenever I'm asked to talk about genetically engineered foodstuffs. Whether or not I sympathize with criticisms of Smart Meters that relate to privacy, market forces, or information security, I want to stress that using bad arguments (like EHS) to support a potentially just conclusion is intellectually dishonest, and it's a good way to alienate potential allies, particularly if those people take critical thinking seriously.

It's important to point out that, given the balance of the available evidence, removing sources of EMF (such as WiFi or Smart Meters) is very unlikely to have any effect on those suffering from this EHS. Not only will these efforts inconvenience many people and incur substantial monetary costs, they're not actually going to get us any closer to helping anyone. And that, in my mind, is the biggest problem.

The WHO released a fact sheet on the subject of electromagnetic fields and health. I'll quote their conclusions here:

"The symptoms [of EHS] are certainly real and can vary widely in their severity. Whatever its cause, EHS can be a disabling problem for the affected individual. EHS has no clear diagnostic criteria and there is no scientific basis to link EHS symptoms to EMF exposure. Further, EHS is not a medical diagnosis, nor is it clear that it represents a single medical problem."

To physicians, they further recommend: "Treatment of affected individuals should focus on the health symptoms and the clinical picture, and not on the person's perceived need for reducing or eliminating EMF in the workplace or home."

So, cell phones and WiFi: Should you be worried? I'm not.

Thanks to Catrina Duffy, Adrian Powell, Ryan Gray, and Jason Locklin, who joined me in spending countless hours poring through the literature on this project.

Links and References
Bad Science Watch
BSW Position Paper on Electromagnetic Hypersensitivity
Skeptic North: Why, WiFi? Why?
Science-Based Medicine: CFLs, Dirty Electricity and Bad Science
IARC Agent Classification Monographs

08 October 2011

Thoughts on Steve Jobs

So, as you may have heard, Steve Jobs is dead. I was slightly disappointed to hear that, because I did see him as somewhat innovative. I wasn't surprised, however; we knew it was coming. I was annoyed when the kooks started crowing that he was another casualty of science-based medicine (further discussion here), but this, too, was not unexpected.


I have a MacBook Air running OSX Lion, and I love it. But I also have a desktop that dual boots to Ubuntu 11.04 and Windows 7. And that giant, glowing Apple logo on the back on my MacBook annoys the hell out of me, because of the way it seems to be taken as a status symbol and a fashion statement.

I own an iPhone 3G, and I got up at 05:00 yesterday to preorder the new iPhone 4S. But I jailbreak my iPhones, because although I like the hardware and the OS I'm not willing to let Apple dictate how I use my own property. And I don't intend to stop jailbreaking, even when Bill C-32 makes it illegal to do so this winter.

So that's where I'm coming from when it comes to Apple: I like many Apple products, but I don't much care for Apple as a company. That's probably why I was so intrigued by Adam Cadre's comments about Apple and about Steve Jobs. They differed widely from the run-of-the-mill eulogising that I've seen on the Internet for the last few days.

People always used to complain about Microsoft's monopolistic practices, but Apple, I discovered, was far worse. I use a Microsoft operating system on a Dell computer which is hooked up to a Unicomp keyboard and a Logitech trackball and from which I use a Mozilla browser to go to Amazon and buy music which I transfer to a Shenzhen Zhanyue MP3 player. Apple wants me to use an Apple operating system on an Apple computer which is hooked up to an Apple keyboard and an Apple mouse in order to use an Apple browser to go to an Apple store and buy music to transfer to an Apple MP3 player. And it will use any of those entry points to try to strongarm people into signing up for the whole package. Now, you might say, what's wrong with that? That's capitalism! To which I would reply, exactly. Apple exemplifies the fact that underlying capitalism is the philosophy of the cancer cell.

The second thing that turned me against Apple was its dealing with Apple Corps, the media company founded by the Beatles in 1968 — eight years and three months before Apple Computer. In 1978, Apple Corps filed a trademark infringement suit against Apple Computer, which settled up by paying Apple Corps $80,000 and promising not to enter the music business. Apple Computer then went right ahead and entered the music business — became the world's leading music company, in fact. And, yes, further settlements were reached that made this retroactively agreed to. But, well, you've heard the saying that "it's better to ask forgiveness than to ask permission"? You know who says that? Assholes say that. If you've made a promise not to enter the music business, and you then plunge into the music business on the theory that with the money you generate you can pay off the people you've wronged, you're acting like an asshole. And you can say, hey, that's capitalism... to which I would reply, exactly. Apple exemplifies the fact that capitalism rewards those with the fewest scruples.

Seriously, read the whole thing. It's worth it.

19 August 2011

Stand back: I'm going to try Boolean logic!

Fair warning: unless you're really into hardcore computer geekery, you're probably going to want to ignore this post. This has nothing much to do with skepticism, so feel free to skip it.

I do a lot of work in MATLAB, a programming language not without its quirks. One of its (many) missing features is the ternary operator, also known as the inline if statement. I'll give you a trivial example.

In many languages, you can do something like this:

fprintf(file, 'The statement is %s!\n', statement ? 'true' : 'false');

In MATLAB, however, you have to do this:

if statement
    fprintf(file, 'The statement is true!\n');
else
    fprintf(file, 'The statement is false!\n');
end

Even if you don't understand the statements above, you probably get the idea. The first one is a lot more succinct than the second. There are cases in which you would need to completely restructure your function in order to remove a ternary operator. Although the uses of this operator are fairly esoteric, suffice it to say that this is a useful feature to have.

I came across a problem which really needed to be solved with an inline if. I was fooling around with function handles, and eventually came up with the following (warning: MATLAB code ahead):

iif = @(condition, ifTrue, ifFalse)(feval(@ result, trueOrFalse)(result{trueOrFalse + 1}), {ifFalse ifTrue}, condition));

Yes, that is a function handle declaration with a nested anonymous function. If you're not accustomed to dealing with function handles, I wouldn't be offended if you bowed out now.

In any event, this code allows me to replicate the inline if functionality that MATLAB is missing! Observe:

fprintf(file, 'The statement is %s!\n', iif(statement, 'true', 'false'));

Not bad! Needless to say, I felt pretty good about myself.

Of course, my friend Curt had to come along and burst my bubble. He pointed out that I was so obsessed with writing things in one line that I'd overlooked the fact that I could have just as easily written iif as a standard function and still used it as an inline if:

function result = iif(condition, ifTrue, ifFalse)
    if condition
        result = ifTrue;
    else
        result = ifFalse;
    end
end

I can still execute the iif function in one line, as above, but this version is clearly easier to read. I benchmarked the two of them several times with 10,000 random comparisons that evaluated to true or false. The function version of iif completed the benchmark in under 0.1 seconds, while the evaluating the function handle took a dismal 2.2 seconds.

Blast.

15 November 2010

Opus Dei is after your computer!

Stuff like this? This is why skepticism is important.

Most of the time, I’d argue it’s pretty much a scam to pay someone to remove viruses from your PC anyway: if you have a Mac, it’s a non-issue, and there’s enough free virus scanners out there that there’s no real reason to pay.

Still, if you were going to pay someone to remove viruses from your computer, how much would it be worth to you? Fifty bucks? One hundred bucks? But surely no one sane would you pay twenty million bucks, right?

Wrong. Since 2004, composer Roger Davidson has been paying Datalink Computer Products owner Vickram Bedi and employee Helga Ivarsdottir to keep his computer clear of viruses.

...

Apparently, these viruses were not only so powerful as to damage machines in the repair shop that were simply in the vicinity of Davidson’s PC, but that the virus was born on a hard drive in a remote village of Honduras, created as part of a plot to infiltrate the United States government by Polish priests linked to Opus Dei. Worse? Davidson’s life was in danger.

Tip o' the insane international conspiracy to Shunjie Lau.