As a hiring manager looking for good software engineers, this article rings so true...
http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html
Like he says, I'm all for hiring programmers who know Java, and even who have had most of their practical experience in Java. But if they *think* exclusively in Java, then I don't want them for the kind of software we develop.
Wednesday, August 28, 2013
Sunday, June 16, 2013
Phone Number Word Search
Mnemonic phone numbers. You know what I'm talking about: a computer store which lists its phone number as "Run-Fast". Alternatively, they could have used "Sum-Fart" with that same number. Or a florist with "4-flowers". Notice it has 8 digits instead of the standard 7 - it always used to be that extra digits dialed at the end were ignored; I wonder if that still works.
You might be surprised how many phone numbers have interesting words hidden inside. Go to DialABC to find out. The other day I was just curious if my phone number had an interesting mnemonic. I discovered that my work number can be listed as, "eye-plea" (maybe I'm a lawyer specializing in Ophthalmology). Or "Ex-Dr. Lea" (poor Lea, lost her license to practice medicine).
It's harder if you have 1s or 0s in your number since those don't have letters associated with them.
Anyway, I was just curious, and vaguely remembered that there were sites which gave you suggestions. The first several sites I tried ranged from OK to disappointing, and were mostly just platforms to serve up ads. Then I found DialABC. For the purpose I wanted, it was superior. The visual presentation of the words was much better than a long list of combinations. Plus, the site has other interesting goodies, like DTMF-number conversion, and even an anagram finder (my full name can be re-arranged to "vulgar fondest odes" - I guess I wrote dirty love limericks).
I like DialABC - it provides interesting services without being overly-promotional.
You might be surprised how many phone numbers have interesting words hidden inside. Go to DialABC to find out. The other day I was just curious if my phone number had an interesting mnemonic. I discovered that my work number can be listed as, "eye-plea" (maybe I'm a lawyer specializing in Ophthalmology). Or "Ex-Dr. Lea" (poor Lea, lost her license to practice medicine).
It's harder if you have 1s or 0s in your number since those don't have letters associated with them.
Anyway, I was just curious, and vaguely remembered that there were sites which gave you suggestions. The first several sites I tried ranged from OK to disappointing, and were mostly just platforms to serve up ads. Then I found DialABC. For the purpose I wanted, it was superior. The visual presentation of the words was much better than a long list of combinations. Plus, the site has other interesting goodies, like DTMF-number conversion, and even an anagram finder (my full name can be re-arranged to "vulgar fondest odes" - I guess I wrote dirty love limericks).
I like DialABC - it provides interesting services without being overly-promotional.
Sunday, May 5, 2013
Transfer DNS management to GoDaddy
Some time ago, I transferred my geeky-boy.com domain from an old hosting service to GoDaddy. At that time, I set the NS servers to my (then) new hosting service, suso.org. I did this so that it would be transparent for me if suso decided to move my web page or mail server to a different host. (And indeed, they did move me at one point, and connectivity was seamless and smooth, so it "worked".)
Now I plan to move to a different hosting service, so I wanted to move DNS management from suso to GoDaddy, which has a web-based control panel so that I could self-manage. It was not clear to me how to transfer management from Suso to GoDaddy, but after some experimentation and reading, I figured it out.
The first thing to do is to get a print out of all the domain zone information. I had to send a support request to Suso to get it, and it took a full week. :-(
Log into GoDaddy and go to "My Account". On the "DOMAINS" row click "Launch". Select the domain name.
Under "Nameservers" click "Set Nameservers". It probably says, "I have specific nameservers for my domains" set. Change it to "I want to park my domains". This should set your name servers to NSxx.DOMAINCONTROL.COM where "xx" is a 2-digit number. Click "OK".
You will now have to wait about 5 minutes and then refresh the page. At that point, you should see the Nameservers section with the NSxxDOMAINCONTROL.COM , and under "DNS Manager" it should have a bunch of pre-defined A, CNAME, and MX records defined, all pointing at GoDaddy's servers. These are the "parking" settings, which you don't want.
Under that is the link "launch". Click it. That puts you into the zone editor, which is pretty easy to figure out. I changed the "@" A record to point at Suso (I haven't moved yet), and added the other A records to match what Suso has. I removed all the GoDaddy CNAME records and added the ones from Suso. And I changed the MX records.
Now I just have to decide where to host everything.
Now I plan to move to a different hosting service, so I wanted to move DNS management from suso to GoDaddy, which has a web-based control panel so that I could self-manage. It was not clear to me how to transfer management from Suso to GoDaddy, but after some experimentation and reading, I figured it out.
The first thing to do is to get a print out of all the domain zone information. I had to send a support request to Suso to get it, and it took a full week. :-(
Log into GoDaddy and go to "My Account". On the "DOMAINS" row click "Launch". Select the domain name.
Under "Nameservers" click "Set Nameservers". It probably says, "I have specific nameservers for my domains" set. Change it to "I want to park my domains". This should set your name servers to NSxx.DOMAINCONTROL.COM where "xx" is a 2-digit number. Click "OK".
You will now have to wait about 5 minutes and then refresh the page. At that point, you should see the Nameservers section with the NSxxDOMAINCONTROL.COM , and under "DNS Manager" it should have a bunch of pre-defined A, CNAME, and MX records defined, all pointing at GoDaddy's servers. These are the "parking" settings, which you don't want.
Under that is the link "launch". Click it. That puts you into the zone editor, which is pretty easy to figure out. I changed the "@" A record to point at Suso (I haven't moved yet), and added the other A records to match what Suso has. I removed all the GoDaddy CNAME records and added the ones from Suso. And I changed the MX records.
Now I just have to decide where to host everything.
Thursday, February 7, 2013
random.org
There have been quite a few times that I have wished for a quick and easy way to make random selections. I mean in everyday situations, like if I want a random ordering of people for some task. It's surprisingly hard to just "choose randomly". Flipping a coin is fine when the number of choices is small and a power of two, but too time-consuming with 8 or more choices. Slips of paper in a hat is also a bit unwieldy.
I suppose I could use this, but I guess I like more diversity in my random numbers.
Today I found www.random.org. It is not a pseudo-random number generator; it uses atmospheric noise to generate *true* random numbers.
I suppose I could use this, but I guess I like more diversity in my random numbers.
Today I found www.random.org. It is not a pseudo-random number generator; it uses atmospheric noise to generate *true* random numbers.
- Here's an easy way to shuffle N items: www.random.org/lists/
- If the items are playing cards: www.random.org/playing-cards/
- Want a *really* random password? www.random.org/passwords/ (Note: add a period to the end to get a "special" character in there.)
I know, I know ... overkill, right? Think I'm OCD? You're wrong. I'm probably a bit OCPD.
Tuesday, February 5, 2013
When We Went MAD
I think you have to be of a certain age to really appreciate MAD Magazine. When I was a kid, it was one of the *FEW* outlets of satire, sarcasm, and anti-grownup humor available to wee tikes.
I suspect there are few who grew up prior to The Simpsons who would have such fond memories, but old farts like me might be interested in:
http://www.kickstarter.com/projects/1438570989/when-we-went-mad-a-documentary-of-ecch-ic-proporti
I threw in $25, and I hope they make their goal.
I suspect there are few who grew up prior to The Simpsons who would have such fond memories, but old farts like me might be interested in:
http://www.kickstarter.com/projects/1438570989/when-we-went-mad-a-documentary-of-ecch-ic-proporti
I threw in $25, and I hope they make their goal.
Sunday, January 27, 2013
Cracks in the Edifice of my Religion
I have two religions.
On the one hand, I am proudly Jewish, albeit a secular Jew. This is in spite of the fact that, as most of my friends and many of my acquaintances know, I am an atheist. Many non-Jews consider this to be a contradiction, but it's not - according to one survey, over a quarter of American Jews don't believe in God. (My own Judaism/atheism is complicated, beyond the scope of this post.)
My other religion is Science.
Why do I believe in Science? Simple. Because it works. Both the results and the process of Science have progressed over the millennia, and while it still isn't perfect, it is the best thing that humans have going for them.
So I guess you could say that my discovery of Jonah Lehrer's 2010 article The Truth Wears Off has given me pause. (Margaret actually saw it when it came out and has used it in her class, but happened to leave a copy of it laying around this week. I hadn't seen it before.) I've always known that Science's grasp on truth is always uncertain (that's part of the point of the scientific method), but I guess I didn't know that it is as tenuous as Lehrer makes out.
Am I having a full-fledged crisis of faith? Well ... no. But I do wonder if my lack of deep existential dread might be part of the problem - I don't want the scientific method to be fundamentally flawed, so I choose not to believe so. It just needs some tweaking and a bit more time to converge on highly-probable truths.
And yet, if I only believe this because I want to, how is that different from believing in God?
P.S. - one time I said to an acquaintance that Science is my religion, and he responded, "Scientology?" NO! Scientology is to Science as Astrology is to Astronomy. Please don't confuse them.
On the one hand, I am proudly Jewish, albeit a secular Jew. This is in spite of the fact that, as most of my friends and many of my acquaintances know, I am an atheist. Many non-Jews consider this to be a contradiction, but it's not - according to one survey, over a quarter of American Jews don't believe in God. (My own Judaism/atheism is complicated, beyond the scope of this post.)
My other religion is Science.
Why do I believe in Science? Simple. Because it works. Both the results and the process of Science have progressed over the millennia, and while it still isn't perfect, it is the best thing that humans have going for them.
So I guess you could say that my discovery of Jonah Lehrer's 2010 article The Truth Wears Off has given me pause. (Margaret actually saw it when it came out and has used it in her class, but happened to leave a copy of it laying around this week. I hadn't seen it before.) I've always known that Science's grasp on truth is always uncertain (that's part of the point of the scientific method), but I guess I didn't know that it is as tenuous as Lehrer makes out.
Am I having a full-fledged crisis of faith? Well ... no. But I do wonder if my lack of deep existential dread might be part of the problem - I don't want the scientific method to be fundamentally flawed, so I choose not to believe so. It just needs some tweaking and a bit more time to converge on highly-probable truths.
And yet, if I only believe this because I want to, how is that different from believing in God?
P.S. - one time I said to an acquaintance that Science is my religion, and he responded, "Scientology?" NO! Scientology is to Science as Astrology is to Astronomy. Please don't confuse them.
Friday, January 25, 2013
Debugging Tips
A young pup of an engineer recently wrote to me:
There are other approaches. Some people take a top-down approach to debugging. Look at the code and what it is supposed to do, and try to figure out what is broken. It's all about, "Hmm ... that looks right ... so does that ... that should work ... gee, the code looks right to me. Guess I need to look harder." Yes, I'm making a bit of fun of it, but I have seen it successfully used. I know a guy who can often just look at a screen of code for a minute and point to the bug.
Top-down debugging almost never works for me. Bottom-up debugging asks the question: what is the code *actually* doing? It's all about about collecting evidence and saying, "Whoa, I wonder why it did THAT!" Followed by collecting more evidence. Unfortunately, most of that evidence is hidden deep inside the chips. So the job of the debugging engineer is to expose the evidence of what is going on.
Most people know how to use a source-level debugger to single-step code and examine variables, and this is fine for some bugs. At every step of the way, you can see exactly why it is doing what it is doing. But single-stepping runs out of steam in a hurry, especially when you need to see what's happening inside nested loops that might have thousands of iterations, or when the program is part of a system of multiple cooperating processes - you often can't use break points and single-stepping without breaking the larger system.
Instead of printing huge volumes of debug output, I like to define a function named kick_and_scream. The idea is that you add debug code to your program to test for unexpected conditions, and call kick_and_scream if something is wrong. You might pass in some interesting variables and structures which kick_and_scream will dutifully print the contents of, giving you some insight into the program's state. What it does next depends. Here are some things I've had kick_and_scream do after printing state variables:
I would write a new function: list_check. Pass it num_nodes and head_node and it does this:
So back to adding normal print statements and crawling through thousands of lines of output.
But what if, as I hinted above, the print statements are too disruptive? Like if they change the timing of the system too much?
I've had good luck with an event logger. Call it a poor-man's ultra-low-impact print statement. This is basically a global array treated like a circular queue. Instead of printing a like of debug output, you add debug values to the array. If the array fills, it cycles back to the beginning and overwrites the earliest values. So low impact that it won't have any effect on timing.
The use of the event logger still depends on detecting the problem inside the code and calling kick_and_scream. The kick_and_scream function would then print the contents of the array. It basically shows you the last N events which led up to the failure (where N is the size of the global array).
The disadvantage of this approach is that the output is MUCH harder to interpret than nice descriptive print statements. So I only use this when print statements disrupt the program too much to be useful. Which happens to be fairly frequently in the kinds of software I write.
I've implemented this several times, and I want to create a downloadable package for it. I'll announce it when it's ready.
UPDATE: http://blog.geeky-boy.com/2014/10/event-logger.html
- I was wondering (since I'm taking a coding class and I feel that one
of my weakest points is debugging), do you have any wisdom that you
could pass along? I would appreciate it immensely since it will most
likely save me a considerable amount of time on the MP's we have to
do. If my first coding class taught me anything, the longest part
about those assignments is the debugging process (and I was awful at
debugging my own code).
Bottoms Up!
Maybe I like debgging for the same reasion I like detective shows. It took me a long time to get tired of CSI, and I still like to watch the odd episode. I approach debugging like the CSI guys - I follow the evidence via a technique I call bottom-up debugging.There are other approaches. Some people take a top-down approach to debugging. Look at the code and what it is supposed to do, and try to figure out what is broken. It's all about, "Hmm ... that looks right ... so does that ... that should work ... gee, the code looks right to me. Guess I need to look harder." Yes, I'm making a bit of fun of it, but I have seen it successfully used. I know a guy who can often just look at a screen of code for a minute and point to the bug.
Top-down debugging almost never works for me. Bottom-up debugging asks the question: what is the code *actually* doing? It's all about about collecting evidence and saying, "Whoa, I wonder why it did THAT!" Followed by collecting more evidence. Unfortunately, most of that evidence is hidden deep inside the chips. So the job of the debugging engineer is to expose the evidence of what is going on.
Most people know how to use a source-level debugger to single-step code and examine variables, and this is fine for some bugs. At every step of the way, you can see exactly why it is doing what it is doing. But single-stepping runs out of steam in a hurry, especially when you need to see what's happening inside nested loops that might have thousands of iterations, or when the program is part of a system of multiple cooperating processes - you often can't use break points and single-stepping without breaking the larger system.
Kick and Scream
So what do you do if it's not feasible to single-step? Next in most people's bag of tricks is print statements. Sprinkle liberally throughout your program, printing the values of interesting variables and structures. The hope is that you'll catch the program as it starts to misbehave. But especially with looping programs where it can take a long time for the bug to manifest, the amount of output can be overwhelming. Plus, with cooperating processes, the slowdown introduced by prints can itself disrupt the behavior of the program, long before your elusive bug is caught. Or worse yet, the prints might change the timing of the program enough for the bug to disappear entirely. "Works just fine when I turn on debug output, maybe we should just ship it that way." :-) This is known as the observer effect where the act of measuring something changes the thing under measurement. (It is sometimes called the uncertainty principle, but this is not quite right. The uncertainty principle leads to the observer effect, but it is not the same thing.)Instead of printing huge volumes of debug output, I like to define a function named kick_and_scream. The idea is that you add debug code to your program to test for unexpected conditions, and call kick_and_scream if something is wrong. You might pass in some interesting variables and structures which kick_and_scream will dutifully print the contents of, giving you some insight into the program's state. What it does next depends. Here are some things I've had kick_and_scream do after printing state variables:
- Prompt and read a line from the user. This has the effect of essentially halting execution of the program, giving you a chance to fire up the debugger.
- Dump core - for Unix, you should be able to call "abort()". I assume Windows has something similar (Dr. Watson?). The idea is to get a memory dump of the program which can be examined with a debugger. In C, you can always force an illegal memory access:
*(char *0) = 0;
that often does the trick. - Infinite loop - I've done this for embedded systems whose operating systems are very basic and don't have any kind of core dumping capability. Maybe you have an in-circuit emulator or an external debugger that you can use to interrupt the program and examine state. Having the program stuck in an infinite loop will prevent it from destroying the evidence.
-
cur_node = head_node;
for (i = 0; i < num_nodes; i++) {
if (cur_node.id == query_id) return cur_node;
cur_node = cur_node.next_node;
}
return NULL; /* not found */
Working Back
So, let's say you do the above and you determine that when it loops num_nodes times, the last node it checks has a non-null next_node field. This shouldn't happen - the last node should have a null next_node. You've made some excellent progress - now you know the probable proximate cause of not finding the node - num_nodes is out of sync with the list itself. But the bug isn't actually here. You want to find out where the list got out of sync with num_nodes in the first place.I would write a new function: list_check. Pass it num_nodes and head_node and it does this:
-
cur_node = head_node;
for (i = 0; i < num_nodes; i++) {
if (cur_node.next_node == NULL) kick_and_scream(...);
cur_node = cur_node.next_node;
}
if (cur_node.next_node != NULL) kick_and_scream(...);
Event Logger
The philosophy of kick_and_scream is to not print out reams of debug output, but instead to only print interesting information once an obvious problem is discovered. Sometimes, however, you really do need to see sequences. You might have some kind of state machine which processes input events, and you suspect that the events are arriving in an invalid order. (Ever try to close a file before you open it?) There may not be enough information available just printing current state - you need to see that state evolve as events are being processes.So back to adding normal print statements and crawling through thousands of lines of output.
But what if, as I hinted above, the print statements are too disruptive? Like if they change the timing of the system too much?
I've had good luck with an event logger. Call it a poor-man's ultra-low-impact print statement. This is basically a global array treated like a circular queue. Instead of printing a like of debug output, you add debug values to the array. If the array fills, it cycles back to the beginning and overwrites the earliest values. So low impact that it won't have any effect on timing.
The use of the event logger still depends on detecting the problem inside the code and calling kick_and_scream. The kick_and_scream function would then print the contents of the array. It basically shows you the last N events which led up to the failure (where N is the size of the global array).
The disadvantage of this approach is that the output is MUCH harder to interpret than nice descriptive print statements. So I only use this when print statements disrupt the program too much to be useful. Which happens to be fairly frequently in the kinds of software I write.
I've implemented this several times, and I want to create a downloadable package for it. I'll announce it when it's ready.
UPDATE: http://blog.geeky-boy.com/2014/10/event-logger.html
Maria Bamford
My daughter turned Margaret and me onto Maria Bamford. She is a comedian who has suffered from some mental illness issues, and her sense of humor is definitely not for everybody. Weird, downer, deadpan, awkward, and very very funny for people with a sick sense of humor (like me, and apparently Margaret and my daughter).
If you're up for an experiment, start with her twenty episodes of The Maria Bamford Show. If, after the first one, you don't absolutely hate it, try at least two more.
Then there's Maria Bamford's One Hour Homemade Christmas Special.
I hear she made some commercials for Target, and I should look those up too. Obviously they won't be as off-the-wall as her independent creations, but I bet I'll like them anyway.
And I guess I should spend some time with the fan channel.
If you're up for an experiment, start with her twenty episodes of The Maria Bamford Show. If, after the first one, you don't absolutely hate it, try at least two more.
Then there's Maria Bamford's One Hour Homemade Christmas Special.
I hear she made some commercials for Target, and I should look those up too. Obviously they won't be as off-the-wall as her independent creations, but I bet I'll like them anyway.
And I guess I should spend some time with the fan channel.
Friday, January 18, 2013
Blog tags
Tags are used to group posts. If you want to see all of my postings related to, say, "death", just click on the "death" tag and you'll see the list.
I like tags. It is better than a hierarchical system of organization since a particular item may be associated with multiple points in the hierarchy. E.g. I might have a post tagged as "coding" and "rants", if I have a rant about some aspect of coding.
[Aside - email clients traditionally use a hierarchical folders. But gmail (at least the web interface) gives you true tagging. I like that, but ironically don't use it.]
One complication of tags as an organizational model is that the tags themselves must be organized, especially if the number of tags gets large. THAT strikes me as something which could be organize into a hierarchy. I might have a rants tag and a technical tag. The technical tag might be sub-divided into science and software. Software might be further subdivided into coding and debugging. My rant about coding would show up in both the "rants" tag and the "coding" tag.
Alas, this blogging system does not allow for organizing tags hierarchically ... at least not that I know of. It gives you two views:
The "tag cloud" is interesting. It uses different font sizes for the tags, depending on the relative number of postings given that tag. So rants might be big because I do a lot of ranting, while science might be small because I don't do much blogging about general science. The tag cloud gives an interesting view into my head even without clicking on any of them since they suggest which topics I feel passionate about (or at least chatty about).
That said, I'm thinking it is more of a novelty than a useful organizational model. (It's a novelty that I like, which is why I enabled it on this blog. But it will suffer from the same unwieldiness if I create a lot of tags.) For large numbers of tags, I'm still leaning towards hierarchical.
Since blogger doesn't support hierarchical, I guess I'll just muddle along for now. If my number of tags gets unwieldy, I can look at maybe leveraging the alphabetizing model to represent the hierarchy. For example:
rants
technical
technical-science
technical-software
technical-software-coding
I don't like that much, partly because the important part of the tag name becomes the last part, whereas the eye is drawn to the first part, obscuring the intent. Also, what if I want rants to be last? I guess I could do this instead:
01-technical
02---software
03-----coding
04---science
05-rants
That lets me order them any way I want to. But wow, what a pain if I want to insert a new tag, like say, software design. I'll have to renumber all the tags below it. I guess I could do the old BASIC trick of numbering them by 10s... (Who me? Program in BASIC? How old do you think I am, anyway?)
Another thought: assuming that each tag is simply a fixed URL, I could create a wiki page of the tag links and organize them any way I want to. I could then simply have a pointer to that page on the blog.
Ah well, enough thinking about this. Like I said, I'll just leave it a hodge-podge for now.
I like tags. It is better than a hierarchical system of organization since a particular item may be associated with multiple points in the hierarchy. E.g. I might have a post tagged as "coding" and "rants", if I have a rant about some aspect of coding.
[Aside - email clients traditionally use a hierarchical folders. But gmail (at least the web interface) gives you true tagging. I like that, but ironically don't use it.]
One complication of tags as an organizational model is that the tags themselves must be organized, especially if the number of tags gets large. THAT strikes me as something which could be organize into a hierarchy. I might have a rants tag and a technical tag. The technical tag might be sub-divided into science and software. Software might be further subdivided into coding and debugging. My rant about coding would show up in both the "rants" tag and the "coding" tag.
Alas, this blogging system does not allow for organizing tags hierarchically ... at least not that I know of. It gives you two views:
- Alphabetical
- Tag cloud
The "tag cloud" is interesting. It uses different font sizes for the tags, depending on the relative number of postings given that tag. So rants might be big because I do a lot of ranting, while science might be small because I don't do much blogging about general science. The tag cloud gives an interesting view into my head even without clicking on any of them since they suggest which topics I feel passionate about (or at least chatty about).
That said, I'm thinking it is more of a novelty than a useful organizational model. (It's a novelty that I like, which is why I enabled it on this blog. But it will suffer from the same unwieldiness if I create a lot of tags.) For large numbers of tags, I'm still leaning towards hierarchical.
Since blogger doesn't support hierarchical, I guess I'll just muddle along for now. If my number of tags gets unwieldy, I can look at maybe leveraging the alphabetizing model to represent the hierarchy. For example:
rants
technical
technical-science
technical-software
technical-software-coding
I don't like that much, partly because the important part of the tag name becomes the last part, whereas the eye is drawn to the first part, obscuring the intent. Also, what if I want rants to be last? I guess I could do this instead:
01-technical
02---software
03-----coding
04---science
05-rants
That lets me order them any way I want to. But wow, what a pain if I want to insert a new tag, like say, software design. I'll have to renumber all the tags below it. I guess I could do the old BASIC trick of numbering them by 10s... (Who me? Program in BASIC? How old do you think I am, anyway?)
Another thought: assuming that each tag is simply a fixed URL, I could create a wiki page of the tag links and organize them any way I want to. I could then simply have a pointer to that page on the blog.
Ah well, enough thinking about this. Like I said, I'll just leave it a hodge-podge for now.
Content Publishing
I created a page where I am basically talking to myself about the various ways that content can be published on the Internet, and which way(s) I might want to concentrate on. It is of minimal interest to anybody else.
http://www.geeky-boy.com/w/Sford_Content_Outlets.html
At present, I'm a minimal publisher, splitting content between my wiki and my blog. New Wiki content is sometimes announced in the blog - like this very post. (I also have a twitter and facebook accounts which I don't use due to low signal-to-noise ratios.)
http://www.geeky-boy.com/w/Sford_Content_Outlets.html
At present, I'm a minimal publisher, splitting content between my wiki and my blog. New Wiki content is sometimes announced in the blog - like this very post. (I also have a twitter and facebook accounts which I don't use due to low signal-to-noise ratios.)
Subscribe to:
Posts (Atom)