Site Sponsors:
PHP = Fast & Cheap? 
Okay - I admit it - I am careful. So careful in fact, that what our CLIENTS pay us to do from 9-5 is pretty much the OPPOSITE of what we do on the weekends.

The difference, I suppose, is time. Unlike many, we simply have no time to keep doing things over & over & over again...

So while we work on many a trendy 'tech for-hire, here in the home office using excessive, expensive, toss-out technologies is simply a "no no."

Why? Because - much like upgrading a word processor - we seldom find need to use the hottest new features. The right tool, for the right job?

Indeed, no matter how easy a vendor makes it for us to use their latest opiate, the fact remains that we've simply only had enough time to ''do things over'' about ... uh ... once per decade?

So as we also junked the heavyweight database - even the free stuff - in favor of using flat files, this weekend we decided to show off a little flat-file goodness under PHP.

You can see the results for yourself. While far from complete, the effort for the weekend was a nice face-lift for my oldest web-site (since 1997!) -Known as The Quote For Today, not only does that site run on a rinky-dink shared little server, but it does so far faster & better than it ever did while running under the more expensive stuff...

So here's to faster, cheaper... & better?

(... and our tech was not even 20 years old... Perhaps this means that even MODERN undertakings (let alone ancient space programs) can indeed enjoy all three, with the choice of only two?)

Enjoy the site,

-Rn

[ view entry ] ( 5630 views )   |  permalink  |  related link
Parsing JSON using GSON 
IMHO, Google is fast emerging as the coolest mecca for plus-one innovations. -From Android (+1 on Java / Blackberry) to GWT (+1 on CORBA / XDR), there is simply no better place to watch savvy engineers "embrace and extend" several time-proven ideas.

Such is the case with Google's GSON for Java-Script Object Notation (JSON) (a +1 on json.org): Designed to be a better way to move data in and out of our projects (also known as "serialization"), Google's effort to one-up the ante around the "Fame, Fortune, or Fun" table should get our propellers spinning.



For example, SourceForge.net (also +1'ed by Google eventually hosting their OWN open software developer site) offers an excellent way to query their hosts for the stats on a project.


{
"oses": [["Windows", 29], ["Unknown", 5], ["Linux", 4], ["Macintosh", 2]],
"end_date": "2012-01-20 00:00:00",
"countries": [["United States", 16], ["Italy", 8], ["Ghana", 3], ["Romania", 3], ["United Kingdom", 3], ["Germany", 3], ["Egypt", 1], ["Israel", 1], ["France", 1], ["Hong Kong", 1]],
"downloads": [["2012-01-05 00:00:00", 4], ["2012-01-06 00:00:00", 4], ["2012-01-07 00:00:00", 0], ["2012-01-08 00:00:00", 0], ["2012-01-09 00:00:00", 0], ["2012-01-10 00:00:00", 0], ["2012-01-11 00:00:00", 0], ["2012-01-12 00:00:00", 0], ["2012-01-13 00:00:00", 1], ["2012-01-14 00:00:00", 1], ["2012-01-15 00:00:00", 0], ["2012-01-16 00:00:00", 6], ["2012-01-17 00:00:00", 15], ["2012-01-18 00:00:00", 6], ["2012-01-19 00:00:00", 0], ["2012-01-20 00:00:00", 3]],
"messages": ["Download statistics available since 2012-01-05 (when this project was registered)."],
"period": "daily",
"start_date": "2012-01-05 00:00:00",
"total": 40,
"stats_updated": "2012-01-26 09:01:09",
"summaries": {
"os": {
"top": "Windows",
"percent": 72,
"modifier_text": ""
},
"geo": {
"top": "United States",
"percent": 40,
"modifier_text": ""
},
"time": {
"downloads": 40
}
}
}


Detectable by JSON, we recently decided to use GSON to play with the results:


import com.google.gson.Gson;

public class Test {

public static void main(String... args) throws Exception {
String json =
"{\"oses\": [[\"Windows\", 29], [\"Unknown\", 5], [\"Linux\", 4], [\"Macintosh\", 2]], \"end_date\": \"2012-01-20 00:00:00\", \"countries\": [[\"United States\", 16], [\"Italy\", 8], [\"Ghana\", 3], [\"Romania\", 3], [\"United Kingdom\", 3], [\"Germany\", 3], [\"Egypt\", 1], [\"Israel\", 1], [\"France\", 1], [\"Hong Kong\", 1]], \"downloads\": [[\"2012-01-05 00:00:00\", 4], [\"2012-01-06 00:00:00\", 4], [\"2012-01-07 00:00:00\", 0], [\"2012-01-08 00:00:00\", 0], [\"2012-01-09 00:00:00\", 0], [\"2012-01-10 00:00:00\", 0], [\"2012-01-11 00:00:00\", 0], [\"2012-01-12 00:00:00\", 0], [\"2012-01-13 00:00:00\", 1], [\"2012-01-14 00:00:00\", 1], [\"2012-01-15 00:00:00\", 0], [\"2012-01-16 00:00:00\", 6], [\"2012-01-17 00:00:00\", 15], [\"2012-01-18 00:00:00\", 6], [\"2012-01-19 00:00:00\", 0], [\"2012-01-20 00:00:00\", 3]], \"messages\": [\"Download statistics available since 2012-01-05 (when this project was registered).\"], \"period\": \"daily\", \"start_date\": \"2012-01-05 00:00:00\", \"total\": 40, \"stats_updated\": \"2012-01-26 09:01:09\", \"summaries\": {\"os\": {\"top\": \"Windows\", \"percent\": 72, \"modifier_text\": \"\"}, \"geo\": {\"top\": \"United States\", \"percent\": 40, \"modifier_text\": \"\"}, \"time\": {\"downloads\": 40}}}";

// Wow - This was easy!
SourceForgeData01 data = new Gson().fromJson(json, SourceForgeData01.class);

// The data conversion:
System.out.println(data.toTDF());
}
}


Here are the supporting classes:


import com.google.gson.annotations.SerializedName;

/**
*
* @author profnagy
*/
class SourceForgeData01 {

@SerializedName("stats_updated")
public String statsUpdated = "";
@SerializedName("start_date")
public String startDate = "";
@SerializedName("end_date")
public String endDate = "";
@SerializedName("total")
public String totalDownload = "";
@SerializedName("summaries")
public DataDownloadSummary downloadArray = new DataDownloadSummary();

public String toTDF() {
StringBuilder sb = new StringBuilder();
sb.append(this.totalDownload);
sb.append("\t");
sb.append(this.startDate);
sb.append("\t");
sb.append(this.endDate);
sb.append("\t");
sb.append(this.statsUpdated);

sb.append("\t");
sb.append(this.downloadArray.os.top);
sb.append("\t");
sb.append(this.downloadArray.os.percent);
sb.append("%\t");
sb.append(this.downloadArray.geo.top);
sb.append("\t");
sb.append(this.downloadArray.geo.percent);
sb.append("%");
return sb.toString();
}
}


~ then, given the structure of "summaries" ~


/**
*
* @author profnagy
*/
class DataDownloadSummary {
public TopPercent os = new TopPercent();
public TopPercent geo = new TopPercent();
}


~ and finally ~


import com.google.gson.annotations.SerializedName;

/**
*
* @author profnagy
*/
public class TopPercent {
@SerializedName("top")
public String top = "";
@SerializedName("percent")
public int percent = -1;
}


Here is the result:


run:
40 2012-01-05 00:00:00 2012-01-20 00:00:00 2012-01-26 09:01:09 Windows 72% United States 40%
BUILD SUCCESSFUL (total time: 1 second)


While massively easy to parse tagged values & arrays, we have yet to discover a way to parse those untagged / anonymous record arrays (such as "downloads" in the above) without resorting to pre-processing. Never the less, when it comes time to parse classic JSON tagged values, GSON results are proving to be almost worthy of a "+2".

Enjoy,

-Rn



[ view entry ] ( 2068 views )   |  permalink  |  related link
WPF Styles and Resource Dictionaries 
While XML might seem far too typeless, when using Visual Studio - by virtue of the XAML Compiler - nothing could be farther from the truth. Whilst we either drag-and-drop, or type, our applications together, Visual Studio validates the XML for us:

<Window x:Class="Assembo01.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>

</Grid>
</Window>

While we are free to pick-and-choose between the GUI and XML views, not only can hand-written XAML be quickly validated, but even seasoned XAML Developers can come to rely upon those in-context, pop-up helpers.

<Window x:Class="Assembo01.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid Background="#FFFAE400">
<Button Content="Inspect" Height="23" HorizontalAlignment="Left" Margin="148,131,0,0" Name="Inspect" VerticalAlignment="Top" Width="75" />
<Label Content="Assembly:" Height="28" HorizontalAlignment="Left" Margin="27,25,0,0" Name="label1" VerticalAlignment="Top" />
<TextBlock Height="23" HorizontalAlignment="Right" Margin="0,30,112,0" Name="textBlock1" Text="TextBlock" VerticalAlignment="Top" Width="268" />
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="428,40,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
</Grid>
</Window>

Sadly, when using the VS Property Editor, folks can get carried away. How? When we choose to define too many proprieties per-element, when it comes time to change massive amount of properties, changing each element once again by hand can become a time consuming nightmare. --In WPF as in HTML then, rather than maintaining each element's properties by hand, why not use a library of styles, instead?

Window.Resources


By now everyone probably knows that adding <Window.Resources> can help us migrate things like the above custom-colors & other style elements over to XAML Styles. Conceptually similar to CSS, referring to self-defined styles (such as {StaticResource AssemboText} (below)) allows us to apply a common style across many visual elements:

<Window x:Class="Assembo01.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Assembo - Assembly Inspector" Height="350" Width="525">
<Window.Resources>
<Style x:Key="Assembo" TargetType="Window">
<Setter Property="Background" Value="Yellow"></Setter>
<Setter Property="Foreground" Value="Blue"></Setter>
</Style>
<Style x:Key="AssemboControl" TargetType="Control">
<Setter Property="Background" Value="Yellow"></Setter>
<Setter Property="Foreground" Value="Blue"></Setter>
</Style>
<Style x:Key="AssemboText" TargetType="TextBlock">
<Setter Property="Background" Value="Yellow"></Setter>
<Setter Property="Foreground" Value="Blue"></Setter>
</Style>
</Window.Resources>
<Grid>
<Button Style="{StaticResource AssemboControl}" Content="Inspect" Height="23" HorizontalAlignment="Left" Margin="148,131,0,0" Name="Inspect" VerticalAlignment="Top" Width="75" />
<Label Style="{StaticResource AssemboControl}" Content="Assembly:" Height="28" HorizontalAlignment="Left" Margin="27,25,0,0" Name="label1" VerticalAlignment="Top" />
<TextBlock Style="{StaticResource AssemboText}" Height="23" HorizontalAlignment="Right" Margin="0,30,131,0" Name="textBlock1" Text="TextBlock" VerticalAlignment="Top" Width="268" />
<Button Style="{StaticResource AssemboControl}" Content="..." Height="23" HorizontalAlignment="Left" Margin="422,30,0,0" Name="browser" VerticalAlignment="Top" Width="59" />
</Grid>
</Window>


Resource Dictionaries


While adding styles can be done "inline" (as demonstrated above), many find that moving resources to a Resource Dictionary makes for a far easier-to-maintain experience.

<Window.Resources>
<ResourceDictionary x:Key="AssemboK">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="AssemboDict.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>

Not only can Resource Dictionaries be dynamically swapped about much like traditional national-language resources, but many find that opening <Window.Resources> to insert a <ResourceDictionary> helps eliminate a lot of clutter.

Eliminating clutter helps keep an XML based UI easier to maintain:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="AssemboW" TargetType="Window">
<Setter Property="Background" Value="Blue"></Setter>
<Setter Property="Foreground" Value="Yellow"></Setter>
</Style>
<Style x:Key="AssemboControl" TargetType="Control">
<Setter Property="Background" Value="Yellow"></Setter>
<Setter Property="Foreground" Value="Blue"></Setter>
</Style>
<Style x:Key="AssemboText" TargetType="TextBlock">
<Setter Property="Background" Value="Yellow"></Setter>
<Setter Property="Foreground" Value="Blue"></Setter>
</Style>
</ResourceDictionary>

Perhaps the best thing about using Resource Dictionaries is that our static references will remain the same. Indeed, once cut-and-pasted to a Resource Dictionary, no GUI elements need to be changed:

<Window x:Class="Assembo01.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Assembo - Assembly Inspector" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary x:Key="AssemboK">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="AssemboDict.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Button Style="{StaticResource AssemboControl}" Content="Inspect" Height="23" HorizontalAlignment="Left" Margin="148,131,0,0" Name="Inspect" VerticalAlignment="Top" Width="75" />
<Label Style="{StaticResource AssemboControl}" Content="Assembly:" Height="28" HorizontalAlignment="Left" Margin="27,25,0,0" Name="label1" VerticalAlignment="Top" />
<TextBlock Style="{StaticResource AssemboText}" Height="23" HorizontalAlignment="Right" Margin="0,30,131,0" Name="textBlock1" Text="TextBlock" VerticalAlignment="Top" Width="268" />
<Button Style="{StaticResource AssemboControl}" Content="..." Height="23" HorizontalAlignment="Left" Margin="422,30,0,0" Name="browser" VerticalAlignment="Top" Width="59" />
</Grid>
</Window>

The next time we put together an WPF Application, consider using Styles and Resource Dictionaries sooner, rather than later. -Partitioning our design across several well-named Documents not only makes our XAML easier to maintain, but aside from knowing what is going on inside the bowels of the Visual Studio, as long as we name our documents & styles wisely, there honestly is no down side to keeping our XML clutter-free and better organized.



[ view entry ] ( 2322 views )   |  permalink

<<First <Back | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | Next> Last>>