Developed my ME, for ME, with only ME in mind.
Well, not really, but it was my initial thought when starting development of my latest project RADLogger. After reviewing many ham radio logging programs, and honestly not liking most of them for various reasons, it became obvious that I should simply write my own amateur radio logging program. After spending several months thinking and experimenting with different data storage engines, I had the honest thought that just maybe others might want to use this.
However, I couldn't let that drive my development and design. Thinking, "how would others like this," just clouded my thinking. Maintaining the "how would I like this," mind-set removes a lot of ambiguity in my development process. Do I want this button? Do I think this import process is cumbersome? Do I think this copy/paste feature will be helpful? Developing a program just for me makes the process easier.
For those interested in the development progress and feature list of RADLogger, simply browse over to www.ruralruins.com/w/blog/ . For now, that is where my development notes will reside. In the future, perhaps, I will have a dedicated page just for my ham radio interests.
73's all
KC7RAD
Rants and Tips from a Crazy Old Telecommuting Programmer.
Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts
Saturday, September 1, 2018
Tuesday, November 7, 2017
Time to Upgrade a Bit
There, sitting on my bookshelf for more than a decade has been a nearly un-read copy of Victor Shtern's book, Core C++: A Software Engineering Approach. Ever since college I have wanted to dive into C and later, C++. As it occurred, my professional life yielded very little opportunity to learn either.
So... Finally; after all that time gathering dust and being shuffled between at least three cross-country moves, I am diving into the wonderful world of C and C++.
According to my calculations, I should complete the book in about 100 days, if I read 12 pages a day (and perform the prescribed programming exercises). Yes, it's a long book, but at the end is a prize: learning a new language. And, well... another prize... I promised myself a new laptop after finishing the book.
So... I had better get to it.
So... Finally; after all that time gathering dust and being shuffled between at least three cross-country moves, I am diving into the wonderful world of C and C++.
According to my calculations, I should complete the book in about 100 days, if I read 12 pages a day (and perform the prescribed programming exercises). Yes, it's a long book, but at the end is a prize: learning a new language. And, well... another prize... I promised myself a new laptop after finishing the book.
So... I had better get to it.
Wednesday, November 1, 2017
Visual Studio Professional 2013 Crashes on Windows 10... A Solution!!!
So... This morning Microsoft pushed down a large Windows 10 update. My Outlook had been randomly crashing since installing Windows 10 so thought it would be a good idea to install the update.
After only... 30 minutes, the update was finished. I started my normal every-day work programs like Chrome, Putty, SQL Server Management Studio, Excel, Outlook, etc... Then I started my installation of Visual Studio Professional 2013.
Nope. Wouldn't work. Would simply lock up with this window (on the left) after just about 15 seconds.
Event Viewer showed the exception in two separate events:
So... After about 4 hours of poking on the internet and trying different things I found a solution that worked for me. This will only work for people with valid logons to Microsoft MSDN who have access to Visual Studio. (I am not certain how this would work for the free versions.)
And, that's it. My Visual Studio Professional 2013 is running fine once again. Well, with one exception... Now, every time I start it, I am prompted for my MSDN password.
There is mention that once you get VS running, you can select Tools -> Extensions and Updates -> Updates and install Update 5. If you opt to try this upgrade install, be certain you have the time. My upgrade is still downloading after 20 minutes.
Edit 1: Installing Update 5 does seem to complete the fix.
According to this reference, this specific problem started happening today...
After only... 30 minutes, the update was finished. I started my normal every-day work programs like Chrome, Putty, SQL Server Management Studio, Excel, Outlook, etc... Then I started my installation of Visual Studio Professional 2013.
Nope. Wouldn't work. Would simply lock up with this window (on the left) after just about 15 seconds.
Event Viewer showed the exception in two separate events:
First Event:
Application: devenv.exe
Framework Version: v4.0.30319
Description: The process was terminated
due to an unhandled exception.
Exception Info:
System.ArgumentNullException
at
System.IO.MemoryStream..ctor(Byte[], Boolean)
at
System.IO.MemoryStream..ctor(Byte[])
at
Microsoft.VisualStudio.Shell.Connected.ConnectedUser.Utilities.BitmapFromPngOrJpeg(Byte[],
Microsoft.VisualStudio.Shell.Connected.ConnectedUser.Logger)
at
Microsoft.VisualStudio.Shell.Connected.ConnectedUser.AvatarCache+<>c__DisplayClass2.<.ctor>b__0()
at
Microsoft.VisualStudio.Shell.InvokableFunction`1[[System.__Canon, mscorlib,
Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089]].InvokeMethod()
at
Microsoft.VisualStudio.Shell.InvokableBase.Invoke()
Exception Info:
System.ArgumentNullException
at
Microsoft.VisualStudio.Shell.ThreadHelper.InvokeOnUIThread(Microsoft.VisualStudio.Shell.InvokableBase)
at
Microsoft.VisualStudio.Shell.ThreadHelper.Invoke[[System.__Canon, mscorlib,
Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089]](System.Func`1<System.__Canon>)
at
Microsoft.VisualStudio.Shell.Connected.ConnectedUser.AvatarCache..ctor(Microsoft.VisualStudio.Services.Profile.AvatarSize,
Byte[], Boolean, Microsoft.VisualStudio.Shell.Connected.ConnectedUser.Logger)
at
Microsoft.VisualStudio.Shell.Connected.ConnectedUser.AvatarCache..ctor(Microsoft.VisualStudio.Services.Profile.Avatar,
Microsoft.VisualStudio.Shell.Connected.ConnectedUser.Logger)
at Microsoft.VisualStudio.Shell.Connected.ConnectedUser.ProfileCache..ctor(Microsoft.VisualStudio.Services.Profile.Profile,
System.Guid, System.Uri, System.String,
Microsoft.VisualStudio.Shell.Connected.ConnectedUser.Logger)
at
Microsoft.VisualStudio.Shell.Connected.ConnectedUser.Connector+<ConnectAsync>d__1.MoveNext()
at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task)
at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task)
at
Microsoft.VisualStudio.Shell.Connected.ConnectedUser.IdeUserSession+<ConnectAndInitializeSessionAsync>d__a.MoveNext()
at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task)
at
Microsoft.VisualStudio.Shell.Connected.ConnectedUser.BaseUserSession+<ConnectAsyncImpl>d__17.MoveNext()
at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task)
at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task)
at
Microsoft.VisualStudio.Shell.Connected.ConnectedUser.BaseUserSession+<ConnectAsync>d__2.MoveNext()
Second Event:
Faulting application name: devenv.exe,
version: 12.0.21005.1, time stamp: 0x524fcb34
Faulting module name: KERNELBASE.dll,
version: 10.0.16299.15, time stamp: 0x2cd1ce3d
Exception code: 0xe0434352
Fault offset: 0x001008b2
Faulting process id: 0x1958
Faulting application start time:
0x01d35325baa1390f
Faulting application path: C:\Program
Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe
Faulting module path:
C:\WINDOWS\System32\KERNELBASE.dll
Report Id: b0bb84fb-22a5-4efd-a88e-57bb6b1a32ca
Faulting package full name:
Faulting package-relative application ID:
So... After about 4 hours of poking on the internet and trying different things I found a solution that worked for me. This will only work for people with valid logons to Microsoft MSDN who have access to Visual Studio. (I am not certain how this would work for the free versions.)
- Run this in a command box: DEVENV /resetuserdata
- Add the line 127.0.0.1 app.vssps.visualstudio.com to the HOSTS file.
- Start Visual Studio 2013 and you should see a screen like the one below...
- Clicked Sign-Out on that screen.
- Remove the line added to the HOSTS file.
- Restart the computer.
- Go to MSDN website to get your Product Key for Visual Studio Pro 2013 (or whatever version you have installed.).
- Start Visual Studio.
- When the User Information / Product Information screen pops up again, click “Change my product license.”
- Enter your Product Key.
- Close Visual Studio and restart your computer one more time.
There is mention that once you get VS running, you can select Tools -> Extensions and Updates -> Updates and install Update 5. If you opt to try this upgrade install, be certain you have the time. My upgrade is still downloading after 20 minutes.
Edit 1: Installing Update 5 does seem to complete the fix.
YMMV
According to this reference, this specific problem started happening today...
Tuesday, October 17, 2017
Beauty Lies in Simplicity - A Little Forum Software
This has been tumbling around in my brain for a while... An extremely spartan forum script. Something relatively small, very fast, uses minimal bandwidth and presents as a standard HTML page with no CSS or client-side scripting. And, it must be reasonably usable with the Lynx browser. For those of you who don't know, Lynx is a text based browser that has been around since the 1990s.
Why do it? Why build a super-simple forum script? Well, I consider it an experiment. How fast and simple can a forum script be?
The intended audience is one; myself. If others want to use it or help, cool. Those interested, check back here. I will post updates as they happen, using the label BLISf, which, funny enough, it the name of the script. :-)
Why do it? Why build a super-simple forum script? Well, I consider it an experiment. How fast and simple can a forum script be?
The intended audience is one; myself. If others want to use it or help, cool. Those interested, check back here. I will post updates as they happen, using the label BLISf, which, funny enough, it the name of the script. :-)
Tuesday, August 8, 2017
All the Data Bloat
A little foreward... This is not a 'bitch' post, it is merely a set of observations. If anyone takes offense, perhaps they should be reviewing how they code and store data.
96 bytes. That's all I need. This specific information I want for the next three days and nights can be represented in 96 bytes. Could someone please answer this question? Why are these 96 bytes wrapped in 144,383 bytes of HTML, JavaScript and CSS? Additionaly, this doesn't count the over 20,000,000 bytes for images.
Let's factor in transfer and render time. A transfer of 96 bytes, with its necessary TCP/IP communications protocol overhead, is quite fast. Even from Antarctica to here, a 96 byte transfer is VERY quick.
Rendering what this 96 bytes represents is equally quick. Rendering a 20,000,000 byte page in a browser requires decrypting stuff and processing CSS layout information and running JavaScript code and converting images into bitmaps for display and handling any necessary animated graphics. My particular computer at this time, an eight core AMD Vishera FX CPU, 16 GB RAM and 15MBs internet connection requires maybe 5 seconds to retrieve this page and display its graphical representation.
96 bytes? Nearly instantaneous.
What do these 96 bytes represent? It is the current local weather conditions, and the forecast for tonight and the following three days and nights. 12 bytes for each day/night.
Precipitation Percent: one byte
Sky Conditions one byte
Weather Condition: one byte
Temperature: one word
Wind Speed: one byte
Barometer: float (four bytes)
Wind Direction; one byte
Visibility: one byte
Other things might be OK to add; perhaps humidity, barometric trend, watches and warnings, sunrise, sunset, moonrise and moonset. Still, after adding these items, the 96 bytes would become a still slim 152 bytes.
My benchmark page, weighing in at a hefty 20MB is here: New Boston, Illinois Wunderground
Rather than slim and narrow, wide is apparently a 'thing'. Are all the additional abstraction layers and frameworks and graphics and tracking completely necessary???
Please... Think about slimming the data when working on your next project.
Remember, the old maxim 'Less is More' holds especially true in the world of computer programming.
96 bytes. That's all I need. This specific information I want for the next three days and nights can be represented in 96 bytes. Could someone please answer this question? Why are these 96 bytes wrapped in 144,383 bytes of HTML, JavaScript and CSS? Additionaly, this doesn't count the over 20,000,000 bytes for images.
Let's factor in transfer and render time. A transfer of 96 bytes, with its necessary TCP/IP communications protocol overhead, is quite fast. Even from Antarctica to here, a 96 byte transfer is VERY quick.
Rendering what this 96 bytes represents is equally quick. Rendering a 20,000,000 byte page in a browser requires decrypting stuff and processing CSS layout information and running JavaScript code and converting images into bitmaps for display and handling any necessary animated graphics. My particular computer at this time, an eight core AMD Vishera FX CPU, 16 GB RAM and 15MBs internet connection requires maybe 5 seconds to retrieve this page and display its graphical representation.
96 bytes? Nearly instantaneous.
What do these 96 bytes represent? It is the current local weather conditions, and the forecast for tonight and the following three days and nights. 12 bytes for each day/night.
Precipitation Percent: one byte
Sky Conditions one byte
Weather Condition: one byte
Temperature: one word
Wind Speed: one byte
Barometer: float (four bytes)
Wind Direction; one byte
Visibility: one byte
Other things might be OK to add; perhaps humidity, barometric trend, watches and warnings, sunrise, sunset, moonrise and moonset. Still, after adding these items, the 96 bytes would become a still slim 152 bytes.
My benchmark page, weighing in at a hefty 20MB is here: New Boston, Illinois Wunderground
Rather than slim and narrow, wide is apparently a 'thing'. Are all the additional abstraction layers and frameworks and graphics and tracking completely necessary???
Please... Think about slimming the data when working on your next project.
Remember, the old maxim 'Less is More' holds especially true in the world of computer programming.
Friday, July 21, 2017
Too Much Codez!!! WHY?!?!?
Why must some programmers place as much code into a single file as they can? Seriously? Is this some sort of challenge? Is there some advantage unknown to me by shoving all of a program's code into a single file?
Really, I am not a huge fan of the MVC pattern. It places, sometimes, arbitrary guidelines regarding what should be placed in the Model, the View and the Controller. However, it is better that the SEIOF pattern! (Shovel Everything Into One File)
In my opinion, a logical separation of interests is best and basic. One file for the GUI, one or more files for the application or business logic and one or more containing global types, classes, utility code, etc...
Placing all that into one large bucket can be confusing. Please... If you are a programmer, please, please separate your code a little bit. Help save the next programmer's sanity.
Oh... And those long methods/functions/procedures... While in college I was taught that a method, function, procedure, subroutine, what-have-you, should be less than a page of printed code. While that isn't always possible, it is still a guideline that I try to observe, and firmly believe other programmers should as well.
Really, I am not a huge fan of the MVC pattern. It places, sometimes, arbitrary guidelines regarding what should be placed in the Model, the View and the Controller. However, it is better that the SEIOF pattern! (Shovel Everything Into One File)
In my opinion, a logical separation of interests is best and basic. One file for the GUI, one or more files for the application or business logic and one or more containing global types, classes, utility code, etc...
Placing all that into one large bucket can be confusing. Please... If you are a programmer, please, please separate your code a little bit. Help save the next programmer's sanity.
Oh... And those long methods/functions/procedures... While in college I was taught that a method, function, procedure, subroutine, what-have-you, should be less than a page of printed code. While that isn't always possible, it is still a guideline that I try to observe, and firmly believe other programmers should as well.
Happy Friday!!!
Tuesday, July 18, 2017
This is one HOT little post!
Sooo... What exactly are you expecting???
Dirty minded people...
It's HOT here... 88F with a humidity that would make any jungle animal quite comfortable.
Anyway... My mind turned to this blog again. You know, I really SHOULD post more here. I mean, with my newfound projects and all.
Projects, you ask? Yes, I have a few new ones...
And... There is plenty to bitch, moan and complain about... So... Be back soon.
Dirty minded people...
It's HOT here... 88F with a humidity that would make any jungle animal quite comfortable.
Anyway... My mind turned to this blog again. You know, I really SHOULD post more here. I mean, with my newfound projects and all.
Projects, you ask? Yes, I have a few new ones...
- Learn C. I mean, more than the typical advanced, scrolling, multicolored "Hello World" sort of level. I mean, really learn it. I really thought long and hard about whether I wanted to learn X86 Assembly or C. My brain is still on the fence just a bit, but when I sat down, wrote a "Hello World" program in each, the C version compiled and ran the first time. My Assembly version required some research to understand some of the assembler switches on NASM. Sure, I got my assembly program to, er... assemble but was a pain.
- I found my favorite college textbook, "An Introduction to Data Structures With Applications" by Tremblay and Sorenson. There may be better text books out there that cover this subject, but this is the one I have... And from my days at WIU, it is my favorite. What am I going to do? Well, when I used this book, all of our projects were written in USCD Pascal. What I would like to do is use several languages to write all the projects in the book. I am thinking of using C, Free Pascal, Modula III and Lua. Maybe a few others like Assembler, C++, Python, Java or Rust. Not certain, but it sounds interesting.
- Maybe... maybe find an open source project to contribute my time.
- Sailing... boating... sailing... OMG, I am a sailor! Yes, my significant other gave me sailing lessons for my birthday. Finished class about a week ago and bought a little sailboat built in the early 1970s by a company in Missouri called Advance. She is 16 feet long, and also known as the "Sweet 16". Great little boat, but is just for me. Our 18 foot cruiser is currently in the shop for repairs and HOPEFULLY will be home before there is ice on the lake.
- Project StarStare, my little project to automatically detect meteor streaks in night sky photos is on a temporary hiatus but my be revived this winter.
- RuralRuins will see some new photos, I promise.
And... There is plenty to bitch, moan and complain about... So... Be back soon.
Thursday, March 23, 2017
Implementing a Simple Weather ScreenSaver in Linux
Starting with that first real-life tornado experience as a seven year old, I have been intrigued with the weather. Going back to my college days I would watch the Weather Channel for hours-on-end when not doing school work. After my freshman year (1985 or 86 or 87; don't remember completely), I passed my ham radio Technician test and was able to participate as a weather spotter.
Wanting to watch the weather on my computer while at work, many years ago I wrote a little program that would rotate the Windows background image through several current weather maps downloaded from NOAA and NWS websites. Honestly, it worked OK, but not stellar.
Living Las Vegas gave me very little drive to be informed with the weather; it was simply depressing. Hot... Hot... OMG Hot... WTF Hot... oh... one nice day. meh... FUUU HOT! I did NOT like the weather there.
Now, living back in the mid-west, I have been gaining interest in watching the weather again. Since watching any cable weather outlet while working is quite distracting, a weather screen saver is the next best thing. In this post I will detail how to setup a desktop Linux distribution (Debian "Jessie" to be exact) to download maps and radar images from the NWS and have the screen saver cycle through the images. Personally, this runs on my spare Linux box next to my work computer.
Wanting to watch the weather on my computer while at work, many years ago I wrote a little program that would rotate the Windows background image through several current weather maps downloaded from NOAA and NWS websites. Honestly, it worked OK, but not stellar.
Living Las Vegas gave me very little drive to be informed with the weather; it was simply depressing. Hot... Hot... OMG Hot... WTF Hot... oh... one nice day. meh... FUUU HOT! I did NOT like the weather there.
Now, living back in the mid-west, I have been gaining interest in watching the weather again. Since watching any cable weather outlet while working is quite distracting, a weather screen saver is the next best thing. In this post I will detail how to setup a desktop Linux distribution (Debian "Jessie" to be exact) to download maps and radar images from the NWS and have the screen saver cycle through the images. Personally, this runs on my spare Linux box next to my work computer.
Friday, February 3, 2017
What to do with all that speed???
So, computers based on quantum physics are already being planned, designed and in some cases even being created. The electronics used in quantum computing do not rely on relatively slow semiconductors; they use near instantaneous quantum technology. No, I don't know the details, but I do know that once some developers get access, there will be abstractions upon abstractions upon abstractions built, to the point where a quantum computer will perform about as well as a 80386 running OS/2.
Monday, November 14, 2016
A Base-64 Decoder That Works!
Let's face it... debugging ASP.NET production websites can be challenging. HTML sessions are 'stateless', meaning from one post to the next, the server has no idea what post came first. For example, let's say there is a website that prompts the user for their name on one page, and on the subsequent page the user is prompted for their address. Well, the server has no intrinsic way to join the data together from those two pages to save it all in a table somewhere.
Web scripting language use various methods to store this state information. Some use cookies to store the data from one page to another. Some use a unique key, placed into a cookie, or in the URL as a parameter to retrieve the data from an internal 'session store' on the server. ASP.NET can save the session state several ways. One way to save part of the session state is in something called a ViewState. This is basically the state of a page; just part of the entire session state.
Well, this ViewState is stored right in the web page as a 64 bit encoded string. It's not encoded but definitely looks that way. It's unreadable without a decoder. Anyway... If something is stored in the ViewState, programmers can have a bitch of a time trying to pull it apart and see the data. But... This information can be invaluable to debugging a production problem. There are varied ViewState tools on the web for decoding this gobeldygook into something that is somewhat coherent. I use Base64 decoder and encoder at motobit. It's simple and works.
Web scripting language use various methods to store this state information. Some use cookies to store the data from one page to another. Some use a unique key, placed into a cookie, or in the URL as a parameter to retrieve the data from an internal 'session store' on the server. ASP.NET can save the session state several ways. One way to save part of the session state is in something called a ViewState. This is basically the state of a page; just part of the entire session state.
Well, this ViewState is stored right in the web page as a 64 bit encoded string. It's not encoded but definitely looks that way. It's unreadable without a decoder. Anyway... If something is stored in the ViewState, programmers can have a bitch of a time trying to pull it apart and see the data. But... This information can be invaluable to debugging a production problem. There are varied ViewState tools on the web for decoding this gobeldygook into something that is somewhat coherent. I use Base64 decoder and encoder at motobit. It's simple and works.
Sunday, November 6, 2016
Simple Is Still Simple
Yes, contrary to the conventional state of technology and computer programming, simple is still simple. Well, at least it should be.
Quite frequently I read different articles about programming in an attempt to maintain professional relevance. Some are well written articles on good programming techniques. Some are poorly written but the core material is still good. Some are well written pieces about some fluff fad and then there are occasionally the poorly written article about some programming technique or library or concept that has 'bad idea' written all over it.
Quite frequently I read different articles about programming in an attempt to maintain professional relevance. Some are well written articles on good programming techniques. Some are poorly written but the core material is still good. Some are well written pieces about some fluff fad and then there are occasionally the poorly written article about some programming technique or library or concept that has 'bad idea' written all over it.
Thursday, September 22, 2016
Getting a 500 Error When Trying to Access a REST API from C#?
This just might be the solution.
Here's the deal... I need to write a simple C# client to access data from a REST API served up by an Apache Tomcat server. Not a big deal at all... should be pretty simple...
Should be...
For some unknown reason, my attempts generated nothing but '500' errors from the server. Myself and our resident network wizard captured my traffic and we compared the headers of a successful GET using CURL and the non-successful attempt using my simple C# program.
After trying a few things with no success, I noticed the CURL capture showed an 'Accept: */*' header. My C# program did not. So, I added this...
request.Accept = "*/*";
SHAZAM!!! No more 500 errors.
No search results from Google helped. None mentioned this as being a possibility. But, heck... it worked.
By the way, this Apache server is what I like to call LegalWalled. Yes, it's our server but if we touch it, or even log onto it using SSH without the guidance and approval of the vendor's support group, we could violate our support contract... so opportunity to dig into why that specific error was generated.
Here's the deal... I need to write a simple C# client to access data from a REST API served up by an Apache Tomcat server. Not a big deal at all... should be pretty simple...
Should be...
For some unknown reason, my attempts generated nothing but '500' errors from the server. Myself and our resident network wizard captured my traffic and we compared the headers of a successful GET using CURL and the non-successful attempt using my simple C# program.
After trying a few things with no success, I noticed the CURL capture showed an 'Accept: */*' header. My C# program did not. So, I added this...
request.Accept = "*/*";
SHAZAM!!! No more 500 errors.
No search results from Google helped. None mentioned this as being a possibility. But, heck... it worked.
By the way, this Apache server is what I like to call LegalWalled. Yes, it's our server but if we touch it, or even log onto it using SSH without the guidance and approval of the vendor's support group, we could violate our support contract... so opportunity to dig into why that specific error was generated.
Wednesday, August 17, 2016
Webcollage bug/irritation repair
So, I am enjoying my little Linux build with that little AMD APU detailed in my last post... Something is missing... YES! A good screensaver.
Oh... Yes it has been a while since my last post, so what? I've been boating and working on the house and generally enjoying the outdoors while the weather is agreeable. So... pfft...
Anyway, I installed the XScreenSaver package with several additional screensaver packages. One looked intriguing... webcollage by Jamie Zawinski. Webcollage uses dictionary files (just lists of words) to seed simple searches on several internet search engines. When the screen saver is activated, a random image (or part of an image) from a random webpage from the results of searching a random word is placed on a the screen like a collage, one image over the other.
Needless to say there is a lot of online bitching about this because quite simply, it can display porn and other NSFW images. OK, so some people don't like it. Personally, I find it intriguing. But... occasionally the following text would show up on the screen... sometimes several times before a screen redraw covered the text:
Use of uninitialized value $vals in index at /usr/share/perl5/HTTP/Headers.pm line 264
Use of uninitialized value $vals in concatenation(.) or string at /usr/share/perl5/HTTP/Headers.pm line 267
After trying a few repairs to the webcollage Perl source, I just went into Headers.pm and fixed it there. Here's the repair:
sub as_string
{
my($self, $endl) = @_;
$endl = "\n" unless defined $endl;
my @result = ();
for my $key (@{ $self->_sorted_field_names }) {
next if index($key, '_') == 0;
my $vals = $self->{$key};
if ( ref($vals) eq 'ARRAY' ) {
for my $val (@$vals) {
my $field = $standard_case{$key} || $self->{'::std_case'}{$key} || $key;
$field =~ s/^://;
if ( index($val, "\n") >= 0 ) {
$val = _process_newline($val, $endl);
}
push @result, $field . ': ' . $val;
}
}
else {
if ( defined $vals ) {
my $field = $standard_case{$key} || $self->{'::std_case'}{$key} || $key;
$field =~ s/^://;
if ( index($vals, "\n") >= 0 ) {
$vals = _process_newline($vals, $endl);
}
push @result, $field . ': ' . $vals;
}
}
}
join($endl, @result, '');
}
My changes are in red. Not sure if the bug is in webcollage or if it is in Headers.pm but here ya go. This is the fix. Damn, I love open source!
**Disclaimer: I am NOT a Perl programmer, I only know enough to successfully poke around Perl source and figure things out.
**Suggestion: Anyone running webcollage might want to consider two things: 1) it uses internet resources to perform searches and retrieve images; 2) some of the images shown on the screen could really get a person in trouble at most companies, not to mention what might happen should certain significant others see certain images.
Oh... Yes it has been a while since my last post, so what? I've been boating and working on the house and generally enjoying the outdoors while the weather is agreeable. So... pfft...
Anyway, I installed the XScreenSaver package with several additional screensaver packages. One looked intriguing... webcollage by Jamie Zawinski. Webcollage uses dictionary files (just lists of words) to seed simple searches on several internet search engines. When the screen saver is activated, a random image (or part of an image) from a random webpage from the results of searching a random word is placed on a the screen like a collage, one image over the other.
Needless to say there is a lot of online bitching about this because quite simply, it can display porn and other NSFW images. OK, so some people don't like it. Personally, I find it intriguing. But... occasionally the following text would show up on the screen... sometimes several times before a screen redraw covered the text:
Use of uninitialized value $vals in index at /usr/share/perl5/HTTP/Headers.pm line 264
Use of uninitialized value $vals in concatenation(.) or string at /usr/share/perl5/HTTP/Headers.pm line 267
After trying a few repairs to the webcollage Perl source, I just went into Headers.pm and fixed it there. Here's the repair:
sub as_string
{
my($self, $endl) = @_;
$endl = "\n" unless defined $endl;
my @result = ();
for my $key (@{ $self->_sorted_field_names }) {
next if index($key, '_') == 0;
my $vals = $self->{$key};
if ( ref($vals) eq 'ARRAY' ) {
for my $val (@$vals) {
my $field = $standard_case{$key} || $self->{'::std_case'}{$key} || $key;
$field =~ s/^://;
if ( index($val, "\n") >= 0 ) {
$val = _process_newline($val, $endl);
}
push @result, $field . ': ' . $val;
}
}
else {
if ( defined $vals ) {
my $field = $standard_case{$key} || $self->{'::std_case'}{$key} || $key;
$field =~ s/^://;
if ( index($vals, "\n") >= 0 ) {
$vals = _process_newline($vals, $endl);
}
push @result, $field . ': ' . $vals;
}
}
}
join($endl, @result, '');
}
**Disclaimer: I am NOT a Perl programmer, I only know enough to successfully poke around Perl source and figure things out.
**Suggestion: Anyone running webcollage might want to consider two things: 1) it uses internet resources to perform searches and retrieve images; 2) some of the images shown on the screen could really get a person in trouble at most companies, not to mention what might happen should certain significant others see certain images.
Tuesday, March 29, 2016
OMG .NET, You Are Crazy!!!
OK, so I am doing something simple... adding a ControlParameter to a SQLDataSource. I just want to add it as an optional filter. The ControlParameter points to a TextBox. Like this...
<asp:ControlParameter ControlID="txtFiltCC" Name="TCity" PropertyName="Text" Type="String" DefaultValue=""/>
Not only does the result return nothing, according to the Microsoft SQL Server Profiler, the query is never even sent to the server!!!
What the HELL!?!?!?!?
I change the SelectCommand to not use the @TCity paramater and still... no query sent. The GridView bound to the SQLDataSource reports that no records were retrieved. Hmmm... makes sense since according to SQL Server Profiler, no query was sent.
Then I find the ConvertEmptyStringToNull property on the ControlParameter. It's default is 'True'. Hell, I don't want it to be null, so I change it to False. Friggin SHAZAM! The SQL query is sent and I get a result set. Why the HELL would the ConvertEmptyStringToNull cause a query to not be sent, especially if the parameter isn't even used in the query???? This works fine...
<asp:ControlParameter ControlID="txtFiltCC" Name="TCity" PropertyName="Text" Type="String" ConvertEmptyStringToNull="False" DefaultValue=""/>
Really, Microsoft... This is a crazy little piece in ASP.NET
So... For anyone scratching their head about a GridView not being populated from a SQLDataSource that is using a ControlParameter pointing to a TextBox, this just may be the solution.
<asp:ControlParameter ControlID="txtFiltCC" Name="TCity" PropertyName="Text" Type="String" DefaultValue=""/>
Not only does the result return nothing, according to the Microsoft SQL Server Profiler, the query is never even sent to the server!!!
What the HELL!?!?!?!?
I change the SelectCommand to not use the @TCity paramater and still... no query sent. The GridView bound to the SQLDataSource reports that no records were retrieved. Hmmm... makes sense since according to SQL Server Profiler, no query was sent.
Then I find the ConvertEmptyStringToNull property on the ControlParameter. It's default is 'True'. Hell, I don't want it to be null, so I change it to False. Friggin SHAZAM! The SQL query is sent and I get a result set. Why the HELL would the ConvertEmptyStringToNull cause a query to not be sent, especially if the parameter isn't even used in the query???? This works fine...
<asp:ControlParameter ControlID="txtFiltCC" Name="TCity" PropertyName="Text" Type="String" ConvertEmptyStringToNull="False" DefaultValue=""/>
Really, Microsoft... This is a crazy little piece in ASP.NET
So... For anyone scratching their head about a GridView not being populated from a SQLDataSource that is using a ControlParameter pointing to a TextBox, this just may be the solution.
Wednesday, March 2, 2016
Oracle VM VirtualBox - Just a Misleading Error Message
Three weeks of fighting a "cold from hell" gave me time to think about my little project to automate a search for meteor photos. Sure, I have a PINE64 on order. Sure, it may be delivered later in March. Sure, there may be a flavor of Linux available for it sometime soon. Sure, I may be able to build ImageMagick and other tools I need for the Pine64. Sure, the performance may be acceptable for my goal. Crap, no planned PXE/net-boot planned.
What if... Let's see... a complete Pine64 compute node with 1GB Ram and the OS on an 8GB flash drive will cost roughly $35 accepting a lot of "maybe" assumptions. Let's remove the assumptions and calculate the cost of a good old AMD or Intel processing node. Looks like a 64 bit AMD based system with 4GB RAM, with PXE boot will run about $85.
So... I decide to emulate a 32 bit Debian text-only install on an Orable VM Virtual box using 4GB Ram to sort-of emulate the AMD solution. Which gives me an idea for a new word...
umulate - An emulation that is not exact; allowing certain differences for the sake of brevity or simplicity. "I am going to umulate this Debian install; the real machine will not have a hard drive, but will boot from a flash drive." But... I digress...
BUT SMACK... An error pops up from Oracle Virtualbox when I try starting the virtual machine...
Failed to open a session for the virtual machine DebianPNode.
Under "Details" it read...
VT-x is disabled in the BIOS for all CPU modes (VERR_VMX_MSR_ALL_VMX_DISABLED)
Well, after some research and comparing this virtual machine with the operational virtual version of Debian, I arrived at a repair that seemingly has nothing to do with the error. I changed the Base Memory for this Virtual machine to 3072 GB and SHAZAM. No more error. Keep in mind, my machine has 8 GB and runs a pretty lean install of 64 bit Windows 7. Why this misleading message popped up, I have no idea... but reducing the Virtual machine's Base RAM fixed the problem.
What if... Let's see... a complete Pine64 compute node with 1GB Ram and the OS on an 8GB flash drive will cost roughly $35 accepting a lot of "maybe" assumptions. Let's remove the assumptions and calculate the cost of a good old AMD or Intel processing node. Looks like a 64 bit AMD based system with 4GB RAM, with PXE boot will run about $85.
So... I decide to emulate a 32 bit Debian text-only install on an Orable VM Virtual box using 4GB Ram to sort-of emulate the AMD solution. Which gives me an idea for a new word...
umulate - An emulation that is not exact; allowing certain differences for the sake of brevity or simplicity. "I am going to umulate this Debian install; the real machine will not have a hard drive, but will boot from a flash drive." But... I digress...
BUT SMACK... An error pops up from Oracle Virtualbox when I try starting the virtual machine...
Failed to open a session for the virtual machine DebianPNode.
Under "Details" it read...
VT-x is disabled in the BIOS for all CPU modes (VERR_VMX_MSR_ALL_VMX_DISABLED)
Well, after some research and comparing this virtual machine with the operational virtual version of Debian, I arrived at a repair that seemingly has nothing to do with the error. I changed the Base Memory for this Virtual machine to 3072 GB and SHAZAM. No more error. Keep in mind, my machine has 8 GB and runs a pretty lean install of 64 bit Windows 7. Why this misleading message popped up, I have no idea... but reducing the Virtual machine's Base RAM fixed the problem.
Friday, February 19, 2016
Teaching an Old Dog New Tricks.
Regardless the age of an old programming dog, new tricks are pretty important to learn.
My initial success with night sky photography with my Canon EOS Rebel T3 tumbled in my mind over the last few days. Recorded remnants of a thought from a few years ago popped up when searching an old personal hard drive... An automated search for meteor photos.
Well, I was nearly there. After spending a few nights with ImageMagick and some meteor photos, I built a basic recipe to find meteor strikes in night sky photos.
Hey, I thought... I have a PINE64 on order. Wouldn't that be cool to make one of these tiny ARM based computers comb through photos for meteors? Ohhh... With a little thought this could be easily scalable. What about controlling my camera with one of these PINE64 computers? Maybe a loosely coupled cluster of these $15 computers to search these photos in different ways?
I needed a control language for this; something interpreted and not terribly complex. It only needs to be able to run shell commands, copy files and talk to MySQL. Lua had my vote until I tried MySQL. After two hours of trying to make it work on my Windows 7 computer, the necessity for a different language became apparent. Sorry Lua.
A buddy of mine at work likes Python. My daughter learned a little Python at college last year. Python is a language specifically being ported to the Pine64. The memory footprint of Python is larger than that of Lua but should work fine in the constrained environment of the Pine64. MySQL Connector was easy to install and setup. After a running a few little trial scripts, I was convinced Python would be my control language for this little project.
So, over the last week or so, this old dog has learned a few new tricks; and he is enjoying it!
My initial success with night sky photography with my Canon EOS Rebel T3 tumbled in my mind over the last few days. Recorded remnants of a thought from a few years ago popped up when searching an old personal hard drive... An automated search for meteor photos.
Well, I was nearly there. After spending a few nights with ImageMagick and some meteor photos, I built a basic recipe to find meteor strikes in night sky photos.
Hey, I thought... I have a PINE64 on order. Wouldn't that be cool to make one of these tiny ARM based computers comb through photos for meteors? Ohhh... With a little thought this could be easily scalable. What about controlling my camera with one of these PINE64 computers? Maybe a loosely coupled cluster of these $15 computers to search these photos in different ways?
I needed a control language for this; something interpreted and not terribly complex. It only needs to be able to run shell commands, copy files and talk to MySQL. Lua had my vote until I tried MySQL. After two hours of trying to make it work on my Windows 7 computer, the necessity for a different language became apparent. Sorry Lua.
A buddy of mine at work likes Python. My daughter learned a little Python at college last year. Python is a language specifically being ported to the Pine64. The memory footprint of Python is larger than that of Lua but should work fine in the constrained environment of the Pine64. MySQL Connector was easy to install and setup. After a running a few little trial scripts, I was convinced Python would be my control language for this little project.
So, over the last week or so, this old dog has learned a few new tricks; and he is enjoying it!
Friday, November 6, 2015
C# Background Workers Using Shared Memory
It doesn't happen often in my particular coding shop, but once in a rare while the requirement for different threads in a program to use a shared memory variable rears it's head. It really isn't difficult to handle this requirement in C#; actually, it is surprisingly easy if you are careful to avoid deadlock situations,
The key to this solution is a simple static class:
using System;
using System.Collections.Generic;
using System.Text;
namespace ThreadCom
{
static class StaticShare
{
public static object MsgLock = new object(); // Functions as a lock when accessing Messages.
public static string Messages = ""; // This is what is shared and used in all threads of this sample program.
}
}
Basically, this snippet of C# code creates a static class with two public properties: MsgLock and Messages. MsgLock is used to control access to Messages; a string that contains the data shared among the different threads. Remember, performance is important; keep the shared static variable terse and small.
Here is how a thread (specifically a BackgroundWorker) might use the StaticShare class to lock, access and change the shared data without causing noticeable contention or throwing exceptions:
lock (StaticShare.MsgLock)
{
ReportProgress(0, "From " + BWName + " -> " + StaticShare.Messages);
StaticShare.Messages = BWName + " current time: " + DateTime.Now.ToString();
}
The first line locks MsgLock, or causes the thread to wait until another thread's lock is released. The ReportProgress() line is a method belonging to a BackgroundWorker, that line, in this case is accessing our shared variable Messages. The last line in the Lock() block assigns something to the shared variable.
One big caveat here... Make the code within the lock() block short, concise, to the point and fast. If the code there is time-consuming or performs poorly, the lock() could cause other threads to be blocked.
Remember... thread blocking is not cool!
You can download the entire c# project from my Google Drive here. Standard code disclaimer: This code is for education, information and perhaps a few laughs. It may not be perfect but does demonstrate a valid implementation of using shared storage with a multi-threaded C# application.
-whew-
The key to this solution is a simple static class:
using System;
using System.Collections.Generic;
using System.Text;
namespace ThreadCom
{
static class StaticShare
{
public static object MsgLock = new object(); // Functions as a lock when accessing Messages.
public static string Messages = ""; // This is what is shared and used in all threads of this sample program.
}
}
Basically, this snippet of C# code creates a static class with two public properties: MsgLock and Messages. MsgLock is used to control access to Messages; a string that contains the data shared among the different threads. Remember, performance is important; keep the shared static variable terse and small.
Here is how a thread (specifically a BackgroundWorker) might use the StaticShare class to lock, access and change the shared data without causing noticeable contention or throwing exceptions:
lock (StaticShare.MsgLock)
{
ReportProgress(0, "From " + BWName + " -> " + StaticShare.Messages);
StaticShare.Messages = BWName + " current time: " + DateTime.Now.ToString();
}
One big caveat here... Make the code within the lock() block short, concise, to the point and fast. If the code there is time-consuming or performs poorly, the lock() could cause other threads to be blocked.
Remember... thread blocking is not cool!
You can download the entire c# project from my Google Drive here. Standard code disclaimer: This code is for education, information and perhaps a few laughs. It may not be perfect but does demonstrate a valid implementation of using shared storage with a multi-threaded C# application.
-whew-
Monday, July 13, 2015
C# Battle - Dynamic Array -versus- Generic Collection
In a previous post I insinuated that using a dynamic array in C#, rather than a dynamic structure might show a certain lack of basic programming skills. Well, after getting my daughter off to work early Saturday morning, a storm rolled in, throwing out my plans to perform a little yard maintenance. So... what to do? How about a little computer play while drinking my morning coffee.
After all, drinking coffee while practicing my guitar has far too many times caused scares due to the possibility of spilled coffee!
So, I set out to prove that Dynamic Arrays are worse performers than Collections in C#. Well... For my tests, my presumptions were proven incorrect. My little test showed that when loading image bitmaps from PNG files into a Dynamic Array, there is only a marginal difference loading into a C# Collection.
Machine Baseline...
CPU: Intel Core i3-3240 @ 3.4 GHz
RAM: 8GB
Windows Version: 7 Ultimate 64 bit.
Hard Drive: ADATA SP920 512MB SSD drive
Number of images to load: 9727
Image size: All are 640 x 480
Read on for the code and specific results...
After all, drinking coffee while practicing my guitar has far too many times caused scares due to the possibility of spilled coffee!
So, I set out to prove that Dynamic Arrays are worse performers than Collections in C#. Well... For my tests, my presumptions were proven incorrect. My little test showed that when loading image bitmaps from PNG files into a Dynamic Array, there is only a marginal difference loading into a C# Collection.
Machine Baseline...
CPU: Intel Core i3-3240 @ 3.4 GHz
RAM: 8GB
Windows Version: 7 Ultimate 64 bit.
Hard Drive: ADATA SP920 512MB SSD drive
Number of images to load: 9727
Image size: All are 640 x 480
Read on for the code and specific results...
Saturday, July 11, 2015
Basic Skills, Please People!
Please!!!
Programmers really should know the basics of a language and platform before coding something that is used in a production environment. Knowing the cool tricks of a language is nice but not knowing how the basics work is just irritating.
Take for instance a little optimization I just finished... A SQL query was returning about 800,000 rows where about 799,700 were duplicates. Adding a distinct to the SQL made the page load about 80% faster. Why did the programmer not use that distinct keyword??? Maybe because they didn't know the basics. Maybe because the programmer was sloppy. Maybe the programmer didn't completely understand what was requested. Don't know.
Then, while looking at the rest of the code I saw several string arrays defined; arrays that, after populated, contained hundreds of items. To build these arrays, Array.Resize was used to add items. Now THAT just might be inefficient. Array.Resize copies the entire array and adds another element. The programmer probably should have used a List<> or some other dynamic structure.
Hmmm... now I am curious...
Programmers really should know the basics of a language and platform before coding something that is used in a production environment. Knowing the cool tricks of a language is nice but not knowing how the basics work is just irritating.
Take for instance a little optimization I just finished... A SQL query was returning about 800,000 rows where about 799,700 were duplicates. Adding a distinct to the SQL made the page load about 80% faster. Why did the programmer not use that distinct keyword??? Maybe because they didn't know the basics. Maybe because the programmer was sloppy. Maybe the programmer didn't completely understand what was requested. Don't know.
Then, while looking at the rest of the code I saw several string arrays defined; arrays that, after populated, contained hundreds of items. To build these arrays, Array.Resize was used to add items. Now THAT just might be inefficient. Array.Resize copies the entire array and adds another element. The programmer probably should have used a List<> or some other dynamic structure.
Hmmm... now I am curious...
Wednesday, July 8, 2015
8 Reasons for a New Operating System
Many years ago you could find me sitting in front of my computer wearing one of my well-worn Linux t-shirts or baseball caps, just programming my brains out, secretly wishing the universe of computers ran on one flavor of Linux or another. Today, well, I am happy to simply have my Windows 7 machines humming along in front of me for at least a week without pause or crash. Anyway... over time I believe Linux has migrated from an OS that performed well & was fairly simple to install and operate, intended to make any computer geek giggle with delight, to something somewhat sloggy and overly complex that now give those same computer geeks headaches and the occasional nightmare.
Anyway, not that I have the technical ability in my current state, I would love to write a new operating system. Why? Here are eight reasons:
Anyway, not that I have the technical ability in my current state, I would love to write a new operating system. Why? Here are eight reasons:
- Performance gains from increased hardware capabilities have been severely strangled by poorly performing code and the belief that the faster hardware will compensate for less than stellar code. A new operating system should centrally focus on core performance at the expense of general purpose functionality.
- Malware... Viruses... Keystroke Loggers... Spyware... One of the key reasons this crap is proliferating is because we have the same-old operating systems and code and utilities. A new operating system should have some basic security in mind when designing basic low-level functionality. And, simply by nature, a new OS would be impervious to these nasties for a while.
- Current OSs are COMPLEX!!! They try to be the do-all, know-all solution to everything. Someone (or something) that tries to do everything will never do anything specific very well. A new operating system should focus more on doing computery things, rather than everything under the sun.
- Developer environments and tools for Windows and Linux are fragmenting so badly, researching solutions and problems, depending on the situation, can be a near-futile exercise. A new operating system could provide a new & clean slate.
- The windowing OS paradigm is dying. Yes, I said it. Don't get me wrong, the windowing paradigm will be around far longer than I. However, it is my firm belief that virtual reality, tactile and audio human/computer interfacing will be the future. A new operating system should have a low level text base interface for baseline operations, maintenance and debugging, and perhaps a windowing interface for coding, but should focus at these newer human/computer interfaces. And, just as a note, all functions capable of being performed by the computer, should be allowed through the text interface.
- The Keep It Simple and Stupid concept has been, for the most part, thrown out by most modern operating systems and development tools. A new operating system should embrace the KISS concept.
- Ever notice the slow access to directories with thousands of files? OK, there may be solutions but it just peeves me off when I have 10,000 or 20,000 files in a directory and handling this many files is so slow (in both Windows and Linux) I can take an afternoon of coffee & smoke breaks. A new operating system should minimally have the ability to support fast handling of large number of files.
- Provide a more rich computer eco-system. Sometime I think Apple and Windows and Linux devs are getting lazy, just hunting for and polishing the low-hanging fruit. A new operating system that performs well, has a vibrant development environment will place pressure on existing ecosystems and provide evolutionary pressure.
What are you waiting for???
Subscribe to:
Posts (Atom)