Today Apple's Steve Jobs announced the subscription service for magazine subscription is now supported. The similar service has been available in Amazon for its Kindle for sometime. But regardless the availability, Dol we really want to read magazines on an electronic gadget?
Here's my experience using different e-readers, both on PC, iPhone, iPad and Kindle. First of all, reading magazines on iPad has the most interesting experience because its bigger footprint than iPhone and interactivity thru its touch screen. For the easiness to our eyes, Kindle prevails, but with no color as its main downside. Reading on PC's monitor is also a good experience, except it's too bulky to carry notebook during travel, let alone reading on desktop.
Another aspect we need to pay attention is the cost of subscription (and yes, this is really a turnoff, at least for me). For example, I subscribe to Reader's Digest for about $2 a year, while on Amazon they charge about $2 per edition (one magazine a year, so total subscription is about $20). A paper TIME magazine subscription, through Ad subsidy, only charge me about $15/year. Amazon charges about $2 per magazine. I bet Apple will charge about the same. It's so non-sense and doesn't make sense! Both Apple, Amazon and the publishers want to rip us off and trick us to pay so much for less! Publishing an e-Magazine costs almost nothing (99.9% of the cost is from the operational costs including the editors/writers, unlike paper-based magazines where they have to print it and distribute it).
Another issue with e-Magazine is the magazines we already one are unsharable, unless they are DRM-free. With paper magazine, we can lend the magazine to friends and let them read free-of-charge and as long as we let them borrow it. Some e-book readers have this borrow-a-book feature, but it is still limited and not convenience to use. Also, format compatibility is a big issue right now, at least between Amazon's AZW and others' EPUB (iBook uses EPUB as well as Nook and other majority of e-readers). If we buy a magazine from Amazon, it cannot be read on iPad, unless we install Kindle-for-iPad/iPhone application for it.
The only benefit of subscribing to e-Magazine right now is that it reduces clutters of magazines. A Kindle can store thousands of magazines (depends on the content. If the magazine has alot of pictures, the size will be bigger), iPad can even store much more.
So, the bottom line is that we're (or at least me) not ready to migrate to read e-magazine yet. Maybe some people can take some advantages of reading an e-magazine, but for most people it is not cost-effective yet. Once it's become so ubiquitous and ads are everywhere in the e-magazines to offset the cost, perhaps it's the time we shall migrate to this environment-friendly magazine. Oh, don't forget also by reading paper e-magazine, we support many people's live too, from workers at printing facilities, paper companies, newstand guys to truck drivers!
Tuesday, February 15, 2011
Android vs iOS based Tablets
Many web sites do comparison between Android-based tablets and iPad, but unfortunately almost none of them mention about one important thing: upward/downward binary-compatibility.
What does that mean? OK, we now that a software or an application is actually stored in file. On desktop operating systems (Windows, Mac, Linux etc.), these files are executable on their respective O/S, but only for specific machine.
iPad (or iPhone) Applications are actually binary applications similar the ones we find on Windows or Mac in that they contain machine instructions directly instruct each step to be taken by CPU. The instruction set is specific to the CPU it is built on (for example, iPad app cannot run on Windows or Linux, unless we have an emulator to translate the machine code on-the-fly).
The mechanism of running application is Android is slightly different. Although Android O/S kernel is based on Linux, its applications run on top of a Java virtual machine called "Dalvik". It specifies its own instruction set, outside the platform it runs on (Linux). It acts as a new realm in a realm. The benefit is that we can run Android application on any machine we like (as long as we have the Android O/S compiled and run on the specific CPU). theoritically, an application built for Android running on MIPS CPU can also run on Intel CPU so on.
Why it is important? because developers are no more tied to develop an application specific to a CPU. They can just develop once and it will run on various machines.
What does that mean? OK, we now that a software or an application is actually stored in file. On desktop operating systems (Windows, Mac, Linux etc.), these files are executable on their respective O/S, but only for specific machine.
iPad (or iPhone) Applications are actually binary applications similar the ones we find on Windows or Mac in that they contain machine instructions directly instruct each step to be taken by CPU. The instruction set is specific to the CPU it is built on (for example, iPad app cannot run on Windows or Linux, unless we have an emulator to translate the machine code on-the-fly).
The mechanism of running application is Android is slightly different. Although Android O/S kernel is based on Linux, its applications run on top of a Java virtual machine called "Dalvik". It specifies its own instruction set, outside the platform it runs on (Linux). It acts as a new realm in a realm. The benefit is that we can run Android application on any machine we like (as long as we have the Android O/S compiled and run on the specific CPU). theoritically, an application built for Android running on MIPS CPU can also run on Intel CPU so on.
Why it is important? because developers are no more tied to develop an application specific to a CPU. They can just develop once and it will run on various machines.
Saturday, February 12, 2011
Query syntax in Google Spreadsheet
I was calculating my expenses related to medical for the purpose of Tax report. All my data is recorded in a spreadsheet in Google Spreadsheet. After experimenting, I am now pleased with its formula, especially the power of query syntax (similar to SQL syntax).
Assume a spreadsheet named "2010" where it contains tax-deductible data. Row 1 cells contain title. Actual data starts from row 2 to row 419 (range is A2 to J419)
Cells in column G contains expenses related to medical. Each Cell in column J contain text, where for medical-related expense it should contain "medical" etc.
Now, to calculate the sum of all medical-related expenses, we can put the following formula somewhere in empty cell down below as:
=query('2010'!$G$2:$J$419;"select sum(G) where J contains 'edical' "; 0)
contains query is not exact-matching, so the logic is still TRUE even if we have "medical" or "Medical".
The reason I omit "m" in "medical" is to avoid case-sensitive query (I might put "Medical" instead of "medical" in my data). We can also put LOWER() function for J to force case-insensitive matching so it will still match any case of the letters, for example:
In this case, I put the formula in another spreadsheet (that's why you see prefix '2010' there to refer to spreadsheet named "2010").
To do logical NOT, the syntax is "NOT J contains 'edical". If you want to do logical AND, put AND in front of NOT, so it will be: "NOT J contains 'medical' AND NOT J contains 'dental' "
The best so far is as below:
=ArrayFormula(IFERROR(query('2010'!$G$2:$J$419;"select sum(G) where LOWER(J) contains 'medical'"), 0))
and the next row will fill with:
=iferror(CONTINUE(B2, 2, 1))
There are many more formulas we can experiment: MATCH(), FILTER() and so on.
Assume a spreadsheet named "2010" where it contains tax-deductible data. Row 1 cells contain title. Actual data starts from row 2 to row 419 (range is A2 to J419)
Cells in column G contains expenses related to medical. Each Cell in column J contain text, where for medical-related expense it should contain "medical" etc.
Now, to calculate the sum of all medical-related expenses, we can put the following formula somewhere in empty cell down below as:
=query('2010'!$G$2:$J$419;"select sum(G) where J contains 'edical' "; 0)
contains query is not exact-matching, so the logic is still TRUE even if we have "medical" or "Medical".
The reason I omit "m" in "medical" is to avoid case-sensitive query (I might put "Medical" instead of "medical" in my data). We can also put LOWER() function for J to force case-insensitive matching so it will still match any case of the letters, for example:
=query('2010'!$G$2:$J$419;"select sum(G) where LOWER(J) contains 'medical' "; 0)
In this case, I put the formula in another spreadsheet (that's why you see prefix '2010' there to refer to spreadsheet named "2010").
To do logical NOT, the syntax is "NOT J contains 'edical". If you want to do logical AND, put AND in front of NOT, so it will be: "NOT J contains 'medical' AND NOT J contains 'dental' "
The best so far is as below:
=ArrayFormula(IFERROR(query('2010'!$G$2:$J$419;"select sum(G) where LOWER(J) contains 'medical'"), 0))
and the next row will fill with:
=iferror(CONTINUE(B2, 2, 1))
There are many more formulas we can experiment: MATCH(), FILTER() and so on.
Tuesday, January 4, 2011
Another Interview Question
This is an interview question for software engineer position at USAA:
"A train leaves San Antonio for Houston at 60 mph. Another train leaves Houston for San Antonio at 80 mph. Houston and San Antonio are 300 miles apart. If a bird leaves San Antonio at 100 mph, and turns around and flies back once it reaches the Houston train, and continues to fly between the two, how far will it have flown when they collide?"
First, we need to draw a line to analyze this:
When these two trains collide, the distance between them is d = 0, or 60*t = 300 - 80*t, solving this equation we get t = 300/140 hours = 15/7 = 2.143 hours. Meanwhile, for the bird the equation is: 100*t = 300 - 80*t, or t = 300/180 = 1.667 hours. This is the time when the bird reaches Houston train and turns around. How far it has traveled from SA? 100*1.667 = 166.7 miles. For this duration, SA train has traveled 60*1.667 = 100.02 miles toward Houston. The distance between the bird (now flying back toward SA) and SA train is = 166.7 - 100.02 = 66.68 miles. How many minutes before the bird hits the SA train? We use the similar equation:
Or, 60*T = 66.68 - 100*T T = 66.68/160 = 0.41675 hours. Total travel time for the bird: t + T = 1.667 + 0.41675 = 2.08375 hours (and it occurs before these two trains collide each other). Total travel distance for the bird: 100 mph * 2.08375 hours = 208.375 miles
"A train leaves San Antonio for Houston at 60 mph. Another train leaves Houston for San Antonio at 80 mph. Houston and San Antonio are 300 miles apart. If a bird leaves San Antonio at 100 mph, and turns around and flies back once it reaches the Houston train, and continues to fly between the two, how far will it have flown when they collide?"
First, we need to draw a line to analyze this:
|<------------------------- 300 ------------------------------| SA H --------60-------> <--------80 ------------------|
When these two trains collide, the distance between them is d = 0, or 60*t = 300 - 80*t, solving this equation we get t = 300/140 hours = 15/7 = 2.143 hours. Meanwhile, for the bird the equation is: 100*t = 300 - 80*t, or t = 300/180 = 1.667 hours. This is the time when the bird reaches Houston train and turns around. How far it has traveled from SA? 100*1.667 = 166.7 miles. For this duration, SA train has traveled 60*1.667 = 100.02 miles toward Houston. The distance between the bird (now flying back toward SA) and SA train is = 166.7 - 100.02 = 66.68 miles. How many minutes before the bird hits the SA train? We use the similar equation:
|<------------------------- 66.68 ------------------------------| SA H --------60-------> <--------100 -------------------|
Or, 60*T = 66.68 - 100*T T = 66.68/160 = 0.41675 hours. Total travel time for the bird: t + T = 1.667 + 0.41675 = 2.08375 hours (and it occurs before these two trains collide each other). Total travel distance for the bird: 100 mph * 2.08375 hours = 208.375 miles
Interesting Algorithm question in Facebook Interview
The question is:
It sounds tricky, but actually the answer is very simple.
Here's the illustration:
Using common method of binary searching, our guess starts from: min + (max-min)/2 or a number in the middle of the range (divide-and-conquer). If our guess is lower than the number, we're given "LOWER" and vice versa.
As the number to be guessed is random, it is possible the number falls right in the middle of the range and matches our first guess. So the answer of this question is (the key of this question is "minimum number of guesses") is 1.
"Given a number in range of 1 to n, what is minimum number of guesses needed to find a specific number if you're just given an answer either "higher" or "lower" for each guess you make"
It sounds tricky, but actually the answer is very simple.
Here's the illustration:
the number to be guessed | V |----------------------------------------------------------------------| min ^ max | | your guess
Using common method of binary searching, our guess starts from: min + (max-min)/2 or a number in the middle of the range (divide-and-conquer). If our guess is lower than the number, we're given "LOWER" and vice versa.
As the number to be guessed is random, it is possible the number falls right in the middle of the range and matches our first guess. So the answer of this question is (the key of this question is "minimum number of guesses") is 1.
Thursday, December 30, 2010
SSE built-in functions in GCC
int __builtin_ia32_comieq (v4sf, v4sf) int __builtin_ia32_comineq (v4sf, v4sf) int __builtin_ia32_comilt (v4sf, v4sf) int __builtin_ia32_comile (v4sf, v4sf) int __builtin_ia32_comigt (v4sf, v4sf) int __builtin_ia32_comige (v4sf, v4sf) int __builtin_ia32_ucomieq (v4sf, v4sf) int __builtin_ia32_ucomineq (v4sf, v4sf) int __builtin_ia32_ucomilt (v4sf, v4sf) int __builtin_ia32_ucomile (v4sf, v4sf) int __builtin_ia32_ucomigt (v4sf, v4sf) int __builtin_ia32_ucomige (v4sf, v4sf) v4sf __builtin_ia32_addps (v4sf, v4sf) v4sf __builtin_ia32_subps (v4sf, v4sf) v4sf __builtin_ia32_mulps (v4sf, v4sf) v4sf __builtin_ia32_divps (v4sf, v4sf) v4sf __builtin_ia32_addss (v4sf, v4sf) v4sf __builtin_ia32_subss (v4sf, v4sf) v4sf __builtin_ia32_mulss (v4sf, v4sf) v4sf __builtin_ia32_divss (v4sf, v4sf) v4si __builtin_ia32_cmpeqps (v4sf, v4sf) v4si __builtin_ia32_cmpltps (v4sf, v4sf) v4si __builtin_ia32_cmpleps (v4sf, v4sf) v4si __builtin_ia32_cmpgtps (v4sf, v4sf) v4si __builtin_ia32_cmpgeps (v4sf, v4sf) v4si __builtin_ia32_cmpunordps (v4sf, v4sf) v4si __builtin_ia32_cmpneqps (v4sf, v4sf) v4si __builtin_ia32_cmpnltps (v4sf, v4sf) v4si __builtin_ia32_cmpnleps (v4sf, v4sf) v4si __builtin_ia32_cmpngtps (v4sf, v4sf) v4si __builtin_ia32_cmpngeps (v4sf, v4sf) v4si __builtin_ia32_cmpordps (v4sf, v4sf) v4si __builtin_ia32_cmpeqss (v4sf, v4sf) v4si __builtin_ia32_cmpltss (v4sf, v4sf) v4si __builtin_ia32_cmpless (v4sf, v4sf) v4si __builtin_ia32_cmpunordss (v4sf, v4sf) v4si __builtin_ia32_cmpneqss (v4sf, v4sf) v4si __builtin_ia32_cmpnlts (v4sf, v4sf) v4si __builtin_ia32_cmpnless (v4sf, v4sf) v4si __builtin_ia32_cmpordss (v4sf, v4sf) v4sf __builtin_ia32_maxps (v4sf, v4sf) v4sf __builtin_ia32_maxss (v4sf, v4sf) v4sf __builtin_ia32_minps (v4sf, v4sf) v4sf __builtin_ia32_minss (v4sf, v4sf) v4sf __builtin_ia32_andps (v4sf, v4sf) v4sf __builtin_ia32_andnps (v4sf, v4sf) v4sf __builtin_ia32_orps (v4sf, v4sf) v4sf __builtin_ia32_xorps (v4sf, v4sf) v4sf __builtin_ia32_movss (v4sf, v4sf) v4sf __builtin_ia32_movhlps (v4sf, v4sf) v4sf __builtin_ia32_movlhps (v4sf, v4sf) v4sf __builtin_ia32_unpckhps (v4sf, v4sf) v4sf __builtin_ia32_unpcklps (v4sf, v4sf) v4sf __builtin_ia32_cvtpi2ps (v4sf, v2si) v4sf __builtin_ia32_cvtsi2ss (v4sf, int) v2si __builtin_ia32_cvtps2pi (v4sf) int __builtin_ia32_cvtss2si (v4sf) v2si __builtin_ia32_cvttps2pi (v4sf) int __builtin_ia32_cvttss2si (v4sf) v4sf __builtin_ia32_rcpps (v4sf) v4sf __builtin_ia32_rsqrtps (v4sf) v4sf __builtin_ia32_sqrtps (v4sf) v4sf __builtin_ia32_rcpss (v4sf) v4sf __builtin_ia32_rsqrtss (v4sf) v4sf __builtin_ia32_sqrtss (v4sf) v4sf __builtin_ia32_shufps (v4sf, v4sf, int) void __builtin_ia32_movntps (float *, v4sf) int __builtin_ia32_movmskps (v4sf)
The following built-in functions are available when -msse is used.
v4sf __builtin_ia32_loadaps (float *) Generates the movaps machine instruction as a load from memory. void __builtin_ia32_storeaps (float *, v4sf) Generates the movaps machine instruction as a store to memory. v4sf __builtin_ia32_loadups (float *) Generates the movups machine instruction as a load from memory. void __builtin_ia32_storeups (float *, v4sf) Generates the movups machine instruction as a store to memory. v4sf __builtin_ia32_loadsss (float *) Generates the movss machine instruction as a load from memory. void __builtin_ia32_storess (float *, v4sf) Generates the movss machine instruction as a store to memory. v4sf __builtin_ia32_loadhps (v4sf, v2si *) Generates the movhps machine instruction as a load from memory. v4sf __builtin_ia32_loadlps (v4sf, v2si *) Generates the movlps machine instruction as a load from memory void __builtin_ia32_storehps (v4sf, v2si *) Generates the movhps machine instruction as a store to memory. void __builtin_ia32_storelps (v4sf, v2si *) Generates the movlps machine instruction as a store to memory.
Subscribe to:
Posts (Atom)