July 14, 2014

Backflow Preventer Water Discharge and Vibration

I was working on the some new irrigation sprinkler heads in the backyard. They were with the factory nozzle caps that had a hole for flushing dirt. I turned on the zone valve from the sprinkler controller, flushed the heads, and turned off the valve. I then tried on some other regular sprinklers. Now I was told that something was wrong at the front yard.

I went there and found the backflow preventer from public water supply near my curb was discharging a lot of water from its vent, and vibrating a great deal with big noise. It must have been something related to the backyard sprinkler work. I quickly turned off the major valve going to all irrigation zones. However, the backflow preventer did not stop. I then had to turn off the valve between public water and the backflow preventer to stop the annoyance.

I went online and did some research. It’s impossible that my water pressure was higher than public water to cause that. Given what I was doing in the backyard, some dirt may have got back into water pipes. Because the backyard is at a higher location than the backflow preventer (that’s why a backflow preventer is required per code), the dirt may have slip to the backflow preventer, causing some O-rings stuck. The simplest thing I could try was to flush again.

So I turned on the major valve to irrigations zones, and turned on the value for the zone with the new irrigation heads. Because these heads were widely open, the water pressure would be very low. Then I turned on the public water value. The high pressure public water flushed with least resistance through backflow preventer, then the irrigation zone in question, and a lot of water came out into the backyard. The backflow preventer did not discharge water and did not vibrate! After a few minutes, allowing the dirt to be removed from the system, I turned off the irrigation zone valve. The backflow preventer did not discharge water and did not vibrate! Then I turned on and off some other normal irrigation zones and regular faucets. The backflow preventer did not discharge water and did not vibrate! It worked.

In summary, if the backflow preventer discharges water from its vent and vibrates, it may be because of dirt stuck in it. Try to flush it before calling a plumber:

  • Turn off the public water valve to stop water discharge and vibration;
  • Open certain faucets or irrigation heads wide to allow dirt a route to be removed from the system;
  • Turn on the public water valve to flush the dirt for a few minutes.
June 28, 2014

Watch Amazon Instant Video on Android

If you want to watch Amazon Instant Video on your Android phone or tablet, you may be surprised to find that there is no such app available on Google Play Store. You can of course try to use the web Browser app in Android, get to Amazon’s website, and log in to Instant Video; but when you click any title, it does not play, and you see this message: “You can watch it on Kindle Fire, mobile devices, game consoles and other compatible devices”. Amazon’s list of Compatible Mobile Devices includes only Amazon Kindle, its new Fire Phone, and Apple iPad/iPhone/iPod Touch series. As you already know, Android phone/tablet is not on the list. It is unacceptable that Amazon Instant Video subscribers cannot use Android phones or tablets to watch the titles.

Android users basically have only one workaround – pretending to be using a Desktop web browser, like watching on your Windows PC.

Install Dolphin Browser

We need a bowser app on Android that can pretend to be a Desktop web browser. Luckily, Dolphin is such a browser on Android that you can set User agent to “Desktop”. That way the web servers would believe you are using a desktop computer than a phone/tablet. You can install Dolphin from Play Store.

When Dolphin is running, touch the little dolphin icon to the right of the web URL box, then choose Settings icon (to the left of Dolphin icon in the pop up), choose Customize, then touch User agent and change to Desktop.

Use Adobe Flash Instead of Microsoft Silverlight

If you think that’s it, you are wrong. Now you run Dolphin, log in to your Amazon account, and get to Instant Video. When you click to watch a video, it does not play and says that it needs Microsoft Silverlight. Silverlight is a web browser plug-in for PC. Amazon does not know your browser is in fact running on Android. It thinks you are running on Windows. The problem is, there is no Silverlight on Android! Microsoft does not provide that support for Android.

Amazon used to use Adobe Flash for playing videos in web browser. Some old posts over the internet worked with that assumption. But Amazon became favoring Microsoft Silverlight from Adobe Flash.

However, Amazon still allows you to use Flash. You need to click Settings in the web page and get to Amazon Instant Video Settings. Scroll down to near the bottom, you find WEB PLAYER PREFERENCES, and you choose Adobe Flash Player instead of Silverlight (Recommended). Now that annoying Download Silverlight message is gone.

Install Adobe Flash Player

But, most likely your Dolphin still does not play the movie. On my HP Touchpad CM10 (Android 4.0.4), Dolphin shows a little cube with a few question marks – basically no Adobe Flash Player is available in my Android tablet. Abode stopped support of Flash Player on mobile platforms a few years back. Most Android systems do not come with Adobe Flash Player installed today.

However, you can still download the stagnant Flash Player 11.1 for Android from Flash Player archives at Adobe. For example, depending on your Android version, you can download:

After the apk is downloaded, just install it and you are done. Now you can come back to Dolphin and reload the page, your Amazon Instant Video now plays!

June 17, 2014

Remove Hands Free Activation on Samsung Galaxy Rush from Boost Mobile

After rooting Samsung Galaxy Rush from Boost Mobile, there are a lot of possibilities. For example, it is now easy to get rid of Hands Free Activation, which would pop up when the phone is turned on. If it no longer uses Boost Mobile, there is no need to activate the phone at Boost Mobile.

There is a workaround to avoid seeing the Activation app even before rooting:

  • Turn on Airplane mode. The phone stops trying to connect to cellular networks. The Hands Free Activation detects that and will not pop up.
  • Then turn on Wi-Fi. Even though cellular network is not available, Wi-Fi can still be used by the phone to go online.

But the workaround has a drawback. Even though the Activation app does not pop up, its icon remains in the notification bar in the top of screen. The green icon with a check symbol takes precious space. If you swipe down, you will find it is impossible to dismiss it in the notification drawer. It is a system app that unprivileged user cannot stop or remove.

Once the phone is rooted, it is possible to disable or remove this Activation nuisance. The corresponding system app is System Update, Version 1.2.40JB, com.samsung.sdm, SprintDM.apk. There are a few different ways:

  • Install Titanium Backup at Play Store. Run Titanium Backup, select this app and uninstall it.
  • Install Astro File Explorer or ES File Explorer at Play Store. Find the apk file and rename to say SprintDM.bak.
  • Install Root Uninstaller from ROOT UNINSTALLER at Play Store. This tool supports backing up, disabling and uninstalling system apps. This is a good tool if you are not sure to permanently remove a system app, and you want to make a backup copy and/or just disable the system app. It is a free trail version so has some usage limitations. I used it to backup System Update (SprintDM.apk) to sdcard, and then disabled that app.
  • Install Root Uninstaller from dohkoos at Play Store. This tool is much smaller than the other Root Installer. There is no usage limitations. But it only supports uninstalling apps. If you are sure to remove the system app permanently, this is a handy tool.

All the tools above request root access, therefore the Super User Deny/Allow will pop up. You need to choose Allow for them to do their job. After System Update is disabled or uninstalled, you need to reboot the phone. The Hands Free Activation no longer appears in the notification bar, neither pops up to bother.

June 16, 2014

Root Android Phone: Samsung Galaxy Rush from Boost Mobile

Introduction and Preparation

Credits to the AndroidForums thread and TheUnlockr article.

There are basically two parts:

  • Install ClockworkMod Recovery (CWM) on the phone. This needs Odin3 (running on your PC) to flash CMW and replace the Samsung stock recovery on the phone.
  • From within ClockworkMod, install a Superuser zip to root the phone.

To root the phone, download these:

  • Odin3. I used Odin3-v3.04.zip. This will run on Windows PC. Extract the files in the zip to anywhere on your PC, and find Odin3 v3.04.exe.
  • CWM for Galaxy Rush. Either CWM-Rush-M830-Final.tar or CWM-Touch-Rush-m830.tar works. The difference is the touch version is more modern, while the non-touch version uses Volume Up/Down and Power buttons to navigate within CWM. I prefer the non-touch version, CWM-Rush-M830-Final.tar. CWM will be served by Odin3 to the phone.
  • Superuser (Superuser- This is the root exploit that CWM is going to install on the phone.

Copy Superuser Zip File to Phone

Superuser- can be copied to the phone before or after CWM is flashed to the phone.

There is no need to insert a micro-SD card to the phone; the phone’s internal storage is sufficient.

Connect the phone to PC with a USB cable, the phone appears as SPH-M830 (Samsung model number for Galaxy Rush) on Windows 8:


Double click SPH-M830, it shows phone storage as a USB drive Phone:


Double click the drive and copy the Superuser zip file to it:


Flash ClockworkMod

Now install CWM to the phone as recovery tool using Odin on PC.

  • PC: Right click Odin3 v3.04.exe and run as administrator. Leave it running for now.
  • Phone: Unplug USB cable connecting to PC.
  • Phone: Power off.
  • Phone: Press and hold Volume Down and Power buttons until it boots. At the Warning prompt, press Volume Up button to continue to the Download mode.
  • Phone: Plug USB cable connecting to PC. Windows may install driver for the phone.
  • PC: Odin3 should find the phone device in the ID:COM box. The phone is connected to Odin3, and Odin3 can load files including CWM to the phone.
  • PC: Odin3: Uncheck all options, except Auto Reboot. Click PDA button, then choose the CWM file CWM-Rush-M830-Final.tar. Click Start. This starts loading CWM to phone.
  • Phone: It should show downloading progress. When done, it reboots.
  • PC: Odin3 should say PASS. Close Odin3.
  • Phone: Unplug USB cable. This is no longer needed.

If there is no problem, the phone has CWM as the recovery now.

Root It

With CWM rooting the phone is quite simple.

  • Power off the phone.
  • Press and hold Volume Up and Power buttons until it boots. The phone enters Recovery mode, i.e., enters ClockworkMod. In the non-touch version, press Volume Up/Down to navigate through menu items, and press Power button to choose a menu item.
  • Choose install zip from sdcard, then choose zip from sdcard. Then select and install Superuser- It takes a few seconds.
  • Choose reboot system now.

After the phone reboots, it is rooted.

Unroot It

After rooting, you may change the phone software in many different ways, for example, removing some apps that were impossible to remove. In case you need to revert back to the unrooted Samsung stock rom for Galaxy Rush, follow the instructions here:

  • Download Stockrom.zip, copy it to the phone.
  • Press and hold Volume Up and Power buttons to boot into ClockworkMod.
  • Wipe data/factory reset
  • Wipe cache
  • Wipe dalvik cache
  • Install StockRom.zip
  • Reboot
June 15, 2014

abs Functions in C and C++


The C standard library provides absolute value functions for integral and floating point types (For free close-to-standard drafts, see C89, C99, and C11):

int           abs(int j);             // stdlib.h  C89 C99 C11
long int      labs(long int j);       // stdlib.h  C89 C99 C11
long long int llabs(long long int j); // stdlib.h      C99 C11
double        fabs(double x);         // math.h    C89 C99 C11
float         fabsf(float x);         // math.h        C99 C11
long double   fabsl(long double x);   // math.h        C99 C11

The C language does not support function overloading, so each function needs a unique name.

C++ inherits all the above C standard library functions, i.e., you can still use these functions. Moreover, because C++ supports function overloading, we can call all these overloaded functions through unified name std::abs. This is way more convenient. See the table below:

int           abs(int j);             // cstdlib  C++98 C++11
long          abs(long j);            // cstdlib  C++98 C++11
long long     abs(long long j);       // cstdlib        C++11
float         abs(float x);           // cmath    C++98 C++11
double        abs(double x);          // cmath    C++98 C++11
long double   abs(long double x);     // cmath    C++98 C++11

You can call absolute value functions using other names similar in C (some other variants are not shown), but generally you will not need to do so:

long          labs(long j);           // cstdlib  C++98 C++11
long long     llabs(long long j);     // cinttypes      C++11
float         fabs(float x);          // cmath    C++98 C++11
double        fabs(double x);         // cmath    C++98 C++11
long double   fabs(long double x);    // cmath    C++98 C++11

Inlining and Performance

As one could imagine, the C++ std::abs function overloads are either an alias of, or an inline function calling, the corresponding C function. The C++ benefit is unified naming; the implementation just reuses the C implementation – there is no need to re-implement. Due to inlining, std::abs should not have performance overhead, and the naming benefit should come free.

For example, in my Visual Studio 2012, std::abs(double) and std::abs(float) can be found in math.h as the following:

inline double __CRTDECL abs(_In_ double _X)
        {return (fabs(_X)); }
inline float __CRTDECL abs(_In_ float _X)
        {return (fabsf(_X)); }

This is for fabsf(float):

inline float fabsf(_In_ float _X)
        {return ((float)fabs((double)_X)); }

This is the root C function fabs(double):

_CRT_JIT_INTRINSIC double  __cdecl fabs(_In_ double _X);

Obviously the C++ abs functions have an inlined call to the corresponding C function. The float C function fabsf(float) calls fabs(double) with additional float<->double conversions. Inlining itself should have virtually no overheads.

One may need to be careful about the performance difference of std::abs(float) and std::abs(double), in fact their underlying C functions fabsf(float) and fabs(double). Depending on the platform, these two functions may have quite different performance.

On x64 with Visual Studio 2012, the absolute floating point value is achieved using SSE. When a std::abs(double) or fabs call is inlined, the assembly code is as follows:

andpd    xmm0, QWORD PTR __xmm@7fffffffffffffff7fffffffffffffff ; clear sign bits

When a std::abs(float) or fabsf call is inlined, the assembly code is:

cvtss2sd xmm0, xmm0                                             ; float -> double
andpd    xmm0, QWORD PTR __xmm@7fffffffffffffff7fffffffffffffff ; clear sign bits
cvtsd2ss xmm0, xmm0                                             ; double -> float

As you can see, the SSE instruction ANDPD natively works on double values (and in fact the instruction clears sign bits of two 64-bit double values in XMM0 at once). To get the absolution value of a float, it needs to convert to double, clear the sign bit, and convert back to float. Therefore, std::abs(float) is in fact slower than std::abs(double) on x64.

Performance Comparison Example

Below is a small example program to show the performance absolute value functions on float and double types.

#include <windows.h>	// QueryPerformanceCounter, QueryPerformanceFrequency
#include <cmath>		// std::abs, fabs
#include <vector>		// std::vector
#include <algorithm>	// std::sort
#include <numeric>		// std::accumulate
#include <iostream>		// std::cout

// timing support
struct timing
	// stamp time
	timing() { QueryPerformanceCounter(&m_t); }

	// get time difference in milliseconds.
	double operator - (const timing& other) const { return (m_t.QuadPart-other.m_t.QuadPart)*1000.0/freq().QuadPart; }

	static LARGE_INTEGER freq() { LARGE_INTEGER f; QueryPerformanceFrequency(&f); return f; }

// print statistical information
void stats(std::vector<double>& mss)
	std::sort(mss.begin(), mss.end());
	double mean = std::accumulate(mss.begin(), mss.end(), 0.0) / mss.size();
	double minv = mss.front();
	double maxv = mss.back();
	double median = mss[mss.size()/2];
	std::cout<<" ["<<mss.size()<<"]: mean="<<mean<<", median="<<median<<", min="<<minv<<", max="<<maxv<<"\n";

// measure performance of std::abs
template<typename Real>
void std_abs(std::vector<Real>& v)
	Real* p = &v.front();
	Real* e = p + v.size();
	while( p!=e )	// avoid vector overhead in debug
		*p = std::abs(*p);

// measure performance of fabsf
void f_abs(std::vector<float>& v)
	float* p = &v.front();
	float* e = p + v.size();
	while( p!=e )	// avoid vector overhead in debug
		*p = fabsf(*p);

// measure performance of fabs
void f_abs(std::vector<double>& v)
	double* p = &v.front();
	double* e = p + v.size();
	while( p!=e )	// avoid vector overhead in debug
		*p = fabs(*p);

// test driver
template<typename Real>
void test_abs(size_t count, size_t repeat)
	std::vector<double> t_std_abs;
	std::vector<double> t_f_abs;

	std::vector<Real> v(count);
	// warm up: walk through memory

	// measure times
	for(size_t i=0; i<repeat; ++i)
		timing t0;
		timing t1;
		timing t2;


	// statistics
	std::cout<<"  std::abs() "; stats(t_std_abs);
	std::cout<<"  C abs()    "; stats(t_f_abs);

int main(int argc, char* argv[])
#ifdef _DEBUG
	size_t count = 1000000;		// debug is slower, use less
	size_t count = 10000000;
	size_t repeat = 20;	// for statistical significance

	std::cout<<"float:  "<<count<<" abs, in ms\n";
	test_abs<float>(count, repeat);
	std::cout<<"double: "<<count<<" abs, in ms\n";
	test_abs<double>(count, repeat);
	return 0;

Built with Visual Studio 2012, below is the running result for Release build (Intel i5 3GHz):

float:  10000000 abs, in ms
  std::abs()  [20]: mean=24.9129, median=25.239, min=22.4168, max=26.9544
  C abs()     [20]: mean=24.6979, median=25.2444, min=22.3905, max=25.6948
double: 10000000 abs, in ms
  std::abs()  [20]: mean=13.5362, median=13.9866, min=12.6494, max=14.135
  C abs()     [20]: mean=13.6213, median=13.9969, min=12.7048, max=14.2889

Basically it shows no difference between the C++ and C functions (std::abs(float) vs. fabsf, std::abs(double) vs. fabs), but it shows that the double version run much faster than the float version. In fact, the double version runs at near 750M operations (abs+read/write+loop) per second.

Just for the reference, below is an example running the Debug build:

float:  1000000 abs, in ms
  std::abs()  [20]: mean=88.6267, median=86.4029, min=72.9652, max=118.84
  C abs()     [20]: mean=57.6703, median=56.0603, min=47.2727, max=77.3424
double: 1000000 abs, in ms
  std::abs()  [20]: mean=65.3075, median=67.8592, min=60.3175, max=68.3168
  C abs()     [20]: mean=24.0356, median=25.1282, min=22.3303, max=25.2725

Obviously the Debug build is much slower than the Release build (20 to 50x slower). And the C++ version is slower than the C version. But no useful conclusion should be drawn here because the instrumentation could be very different, since this is Debug build.

If you are using an up-to-date build environment and you observe performance difference between the C and C++ versions of the absolute value functions, this is what I suggest:

  • Make sure you are running a Release build. Don’t waste your time on a Debug build.
  • Make sure you are comparing an apple with an apple. For example, comparing fabsf(float) with std::abs(float), not fabs(double) with std::abs(float).

I highly doubt any C++ implementation would have a performance bug here.

In the end, I think you will appreciate that using C++ is a better experience with no performance overhead for abs operations.

June 12, 2014

Flash Padavan Custom Firmware on Asus RT-N65R (RT-N65U)

Introduction to Asus RT-N65R/RT-N65U

Asus RT-N65R is a powerful home wireless router. You can find both RT-N65R and RT-N65U models, but they are exactly the same hardware. RT-N65R is the retail version sold by Best Buy and so on, and RT-N65U is supposedly sold by Asus directly. The only difference is the firmware on board. In fact, if you go to Asus support website, you will find the firmware updates for RT-N65R and the firmware updates for RT-N65U are exactly the same. From now on, you can assume that they are the same model.

Why do you need to consider this router? There are a few reasons.

  • The router is very affordable. It is not 802.11ac so not the fastest. But that’s why you may get it for cheap. The AC models are almost all well above $100, but you may get this one for less than $50.
  • The router is feature-rich and powerful.
    • Dual-band 802.11n with theoretical 750Mbps speed
    • Pretty good range coverage for most homes
    • 2 USB ports for storage, printers and so on
    • Ralink RT3883 500MHz CPU, 128MB RAM, 16MB Flash
  • You can install custom firmware. Given its powerful CPU and ample RAM/Flash, with USB storage drive, it can easily be turned into an always-on Linux server. You may use it as file server, VOIP server, and so on. This is the most appealing reason that I bought this router.

The in-depth review can be found at SmallNetBuilder.com. There are some concerns with this router that you may want to know:

  • Even though the 2 USB ports are USB 3.0, do not insert USB 3.0 devices. The hardware has flaws. Inserting USB 3.0 devices would interfere with 2.4GHz band and causing devices on this band to disconnect from the router. It is however fine if you only use USB 2.0 devices on the 2 ports. For details, see here. If you have to use USB 3.0 devices, you need to look at other models.
  • The router runs warm/hot. Some users worry that heat may prematurely damage the router. Asus says it is designed to withstand that heat. Just remember to have enough clearance on all sides when positioning the router.

The factory AsusWrt web UI is pretty and powerful. It looks like this:

However, custom firmware offers more features and flexibility. DD-WRT and Tomato supports some Asus routers, but not RT-N65U. Recent Asus routers run the unified AsusWrt firmware, which is mostly open source (except certain modules from chip vendors). That makes the (benevolent) hackers easier to create custom firmware. Although stock AsusWrt is already quite flexible for hackers, custom firmware such as AsusWrt-Merlin is even more flexible. AsusWrt-Merlin however does not support RT-N65U yet.

Flash Padavan Custom Firmware and Install Entware

Luckily the Padavan custom firmware supports RT-N65U (and some other Asus routers such as RT-N56U/R, RT-N14U). From here, you can see the Padavan firmware has a lot of built-in features. If that is not enough, the Padavan firmware supports Entware. Entware is a package repository for embedded devices. If you have no clue, Entware for router is like App Store for smart phone. Running Entware package manager utility opkg, you can download and install many software packages on the router, and turn it into a versatile little server machine. For example, you can install Asterisk PBX, with whose SIP support the router can be a VOIP server.

Flashing custom firmware to AsusWrt router is very easy.

  • Download the proper Padavan firmware here. I used the latest “full” version RT-N65U_3.0.3.8-081_full.trx. Also download the matching .md5 file – you do not want to flash a corrupt firmware binary to the router. If you are on Windows, you may want to download Microsoft File Checksum Integrity Verifier to generate md5 from the downloaded firmware and verify it is not corrupt.
  • Before flashing the new custom firmware, save your current router settings. Go to Advanced Settings | Administration | Restore/Save/Upload Settings, then backup the current router settings to a local file on your PC. In case you need to revert your custom firmware back to AsusWrt, you will be able to restore the router settings easily with the backup settings file.
  • Installing Padavan firmware is considered “Firmware Upgrade”. You just need to go to Advanced Settings | Administration | Firmware Upgrade. From there you upload the Padavan firmware file (RT-N65U_3.0.3.8-081_full.trx), similar to this (courtesy to Ricky Gao, screenshot is for RT-N16):


  • Once router is flashed, reboot it, and enter the settings if they are different from your original settings. It should work the same way as AsusWrt now.

There are some more steps you may want to do.

  • Disable Telnet and Enable SSH. Telnet is not safe and SSH is better. You will need to use SSH often in hacking this router. P.S., this Padavan firmware is not affected by the Heartbleed vulnerability.


  • If you use Windows, install PuTTY if you haven’t. Using PuTTY as your SSH client connecting to the router, see here. When you connect to router SSH server for the first time, PuTTY prompts a message like “The server's host key is not cached in the registry...”. Just accept it. For details, check here.
  • Once you login to the router through SSH, you can now prepare to use Entware. The first step is to get USB storage for Entware packages, following instructions here. I use a USB thumb drive.
    • You do not need a swap partition on a USB drive, because USB drive is slow and not meant to sustain many writes. RT-N65U probably has enough RAM for most services.
    • Be careful when creating file system on a small USB drive such as 1GB or 512MB. The default command may create too few inodes. When many small files are installed by Entware on the partition, it can run out of inodes before the space is used up, and no more files can be created. You may want to change -i option when making file system.
  • Use Entware opkg to install software packages. For example, update Entware and install nano. The default editor in Padavan firmware is vi, which is too hard to use for anyone from Windows background. Gnu nano will be very useful when you edit the script and configuration files in hacking the router:
 opkg update opkg install nano 

That’s it at the moment. The router is now open to a lot of explorations!

June 1, 2014

The Relationship Between Testability and Good Design

See the Dr. Dobbs article The Relationship Between Testability and Good Design.

If you find it hard to write unit tests for your code, your code probably has a bad design. Maybe your class assumes too many different and separate responsibilities, and putting all these things together creates unnecessary couplings. If you separate it into several classes and let each do one thing, writing individual unit tests would be obvious. The separation of concerns design principle encourages that distinct responsibilities be taken care of by distinct entities.

May 17, 2014





【原文:美国环境医学科学研究院推出报告称:“一些动物实验表明,食用转基因食品有严重损害健康的风险,包括不育,免疫问题,加速老化,胰岛素的调节和主要脏腑及胃肠系统的改变”。美国科学院环境医学研究院得出的结论引起了轰动。 报告强烈建议:转基因食品对病人有严重的安全威胁,号召成员医生不要让他们的病人食用转基因食品,并教育所在社区民众尽量避免食用转基因食品。】

注:“美国环境医学科学研究院”不知具体是哪个机构,经搜索,基本肯定是The American Academy of Environmental Medicine (AAEM),网址:http://www.aaemonline.org/,它对转基因持反对立场:http://www.aaemonline.org/gmopost.html。这到底是一个什么样的机构呢?不要以为名头有美国就是国立机构,这个美国环境医学科学研究院只是一群主要是开诊所的医生的社会团体。“环境医学”在美国不是主流医学,通常被认为是Alternative Medicine,相当于中国的偏方。他们给病人开很另类的处方,比如少用手机防辐射等等,医生的水平实在不敢让人恭维:http://www.sciencebasedmedicine.org/environmental-medicine/。该机构被QuackWatch列为Questionable(可疑)组织:http://www.quackwatch.org/04ConsumerEducation/nonrecorg.html。其成员性质决定了他们不可能做转基因方面第一手的研究,其报告也没有什么参考价值。至于“美国科学院环境医学研究院”,这是一个不存在的机构。美国科学院的正式名称是National Academy of Sciences(美国国家科学院)。美国科学院包括Institute of Medicine(美国国家医学院),但是美国科学院从来没有过什么环境医学研究院。美国国家医学院一下有若干学部(Board),但是也没有环境医学部。

【原文:同年4月,美国政府主管食品**的部门FDA宣布撤消它在数年前颁布的CRY 9C转基因玉米种植的工业指南,主要原因之一,就是该转基因作物对人类健康安全有严重威胁。】




May 11, 2014

Simple Metronome / Beat Maker for Android

My first Android app using Android Studio v0.5.2: Simple Metronome (Beat Maker) for practicing piano and other instruments. The UI and functionality is minimally simplistic:


This is not yet signed and I have not put in on Google Play, therefore you need to download the apk file below and install by yourself. It does not need any user permissions, i.e., it does not read phone state, contacts, location and so on.


  • Phone or Pad with Android 2.2.1 and above
  • Allow installation of non-Market apps (Settings | Application | Unknown sources, or Settings | Security | Unknown sources, depending on your Android version)

Download link: https://drive.google.com/uc?export=download&id=0BxP5vLC_LRogR2diN3BPOEF1NG8


Get every new post delivered to your Inbox.

Join 40 other followers