Thursday, February 05, 2009

Query pattern problem

I have been getting this error with some LINQ expressions:

Could not find an implementation of the query pattern for source type 'System.Text.RegularExpressions.MatchCollection'. 'Where' not found. Consider explicitly specifying the type of the range variable 'v'

You get this error because MatchCollection implements only IEnumerable and not IEnumerable(Of T) All you need to do is change:

from v in ex.Matches(template)

to:

from Match v in ex.Matches(template)

I.e. do what it says and specify the type of the range variable.

CodeSnippet plug-in

Dammit. Those code snippets look so nice in Live Writer… grr. They get all sorts of horrible linebreaks and the formatting does not work at all. Work dammit!

Explorer:

Live Writer:

Grumble.

LINQ expression syntax

I have been recently starting to use LINQ expression syntax a little more. One refactoring that I have been doing is changing things like:

foreach(SomeItem item in items) {
    if(item.SomeProperty == someValue) {
        item.DoSomething();
    }
}

into the slightly nicer:

foreach(var item in (from i in items
                     where i.SomeProperty == someValue
                     select i)) {
    item.DoSomething();
}

… My only hesitation is the nastiness of the syntax (if you try to get it inline with no extra variable definitions – yes I know the extra parentheses are not required, but I find var item in from i in items to be very unreadable, plus I am often adding method syntax to these things at a later stage)… Some syntactic sugar might be nice to get:

foreach(var item from items                                      
                 where item.SomeProperty == someValue                 
                 select item) {
    item.DoSomething();
}

There is probably also a higher order function way to do this for simple cases of just calling one function on each match, but most of the time the code is not as simple as a single method call. Ideally I would love to do something like:

(from i in items where i.SomeProperty == someValue select i).Map(DoSomething);

P.S. Do not like the new Windows Live Writer editor. I just want an editor that makes it easy to create nice neat mark-up! Why is it so difficult to NOT put in paragraphs and other containers that I don’t need? And why can’t I see them in edit mode? And why do I drop out of the edit container and then have the backspace key delete the whole container?

Friday, January 30, 2009

WindowsUpdate

Installing Studio and stuff on my new desktop (laptop is almost officially dead) I was having a problem with Microsoft Update...

The website has encountered a problem and cannot display the page you are trying to view. The options provided below might help you solve the problem.

The error code is 0x8007000B. Looking in the WindowsUpdate.log shows:

WARNING: DownloadFileInternal failed for http://download.windowsupdate.com/v8/windowsupdate/b/selfupdate/WSUS3/x86/Other/wsus3setup.cab: error 0x8007000b

So I tried to download that file in ie and get:

Access to http://download.windowsupdate.com/v8/windowsupdate/b/selfupdate/WSUS3/x86/Other/wsus3setup.cab has been blocked by WebMarshal

Ah ha!

(P.S. I don't remember the blogger editor being this bad... the format of this post is terrible right now.)

[Edit] Formatting maybe fixed...

Thursday, January 29, 2009

Lambda expressions

I just used a lambda expression for the first time. They are neat!

Friday, January 02, 2009

Gunner gunner

I was going to write about some things that I am going to do this year... but I think that kind of thing might be part of the problem... Gonna neva duzzit. So I'm not gonna right nuffink.

I will say though that I have changed something. As in already, it is done. Not going to be done, not only started, but done. I changed the template. They all pretty much suck though so I am going to... no wait. Scratch that. Let's leave it at they suck.

I realise that I have now screwed up the code snippet thingy but too bad. I just wanted a change. What do I need to look for in a template?

  • Quote callouts must look nice
  • Code samples
  • Picture and Video posts must look nice
  • Simple, block oriented
  • Should use my own images not generic ones

Wednesday, August 27, 2008

Why do we not have...

A spell checker that can be run on an entire studio solution, that checks all strings, all mark-up, basically any plain text for spelling errors.

The Code Analysis stuff can now check identifiers which is nice, but why are we still lacking a feature that has been in Word forever.

Wednesday, August 20, 2008

Debugger side effects FTW

Trying to (quickly) get my generated form site working in Firefox...

The first problem was that getElementById was returning null when the client side validation function was firing. A quick look at the source and I see that the Name attribute is set but not the Id on the control that I a looking for. IE "copes" by looking at the Name if the Id is not there, Firefox though "follows the standard". Ok, so why is ASP.Net not generating an Id?

Due to time constraints I tried setting the Id when I create the control, but though it looks fine in the source and the validation works, now I don't get any data in the Text member after postback? Huh? I guess that ASP does not like it when it does not generate the Id, probably have to munge the ViewState to store my Id... No thanks.

So I am just playing in the debugger, trying to see what is populated after adding the control, maybe I can set the Id to be the same as the genereated Name... I add a watch for Control.ID, it's null, then I add a Watch for Control.ClientID, its "ctrl09", now if I just set the contr... wait a second, what?... the watch item for Control.ID just got updated with a value.

Accessing Control.ClientID causes Control.ID to be populated.

I look in the source, sure enough, for the control that I frigged with, the Id is defined. I add this after adding the control to the page:

   1: f.Control.ID = f.Control.ClientID;

And we still let ASP choose the value of the ClientId and hence the Name, but trick it into populating the Id also. (Which I really think that it should anyway...) The assignment is really only for clarity, as this works just as well:

   1: string MicrosoftIsTehSuck = f.Control.ClientID;

Which at least puts a little smile on my face...

Saturday, August 16, 2008

Windows Live Writer

I finally got it set up. A big Fuck(*) You Very Much goes out to whomever wrote the automatic configuration part. Use the damn default web browser to go get your pages, not Internet Explorer! Why would you hard code it to use Explorer? My explorer is configured to only work when I am connected to the VPN and hen only for internal addresses! I had to go change the proxy configuration (after I worked out why it wouldn't work)... Now I just wonder if other parts of Live Writer do this and get upset every time I reboot and reset the proxy configuration? Stupid.

Anyway, looks nice enough.

Where do the drafts go? ... Only local looks like for Blogger, the publish draft is greyed out.

Apparently, by installing a little code snippet (... painless) one can post neat looking code samples:

   1: <controls:PathDuplicator>
   2:     <controls:PathDuplicator.ItemStyle>
   3:         <Style TargetType="controls:Item">
   4:             <Setter Property="Template">
   5:                 <Setter.Value>
   6:                     <ControlTemplate TargetType="controls:Item">
   7:                         <Grid x:Name="RootElement" Height="100" HorizontalAlignment="Left" VerticalAlignment="Top" Width="100" RenderTransformOrigin="0.8,0.8">
   8:                             <Path Margin="18,9.36900043487549,37.2080001831055,27.5090007781982" Data="M50,14 C42.942787,12.875842 37.481071,3.0378544 31,16 C29.399416,19.201166 27,22.378658 27,26 C27,31.253759 25.183334,31 34,31 C35.521332,26.436005 38.284637,24.241812 43,21 C49.555965,16.492775 47.970417,15.455626 55,26 C63.315838,38.473759 64.010223,47.474442 57,65 C55.737644,68.155891 49.410244,76.01281 43,68 C37.249264,60.811581 38.936535,57.9706 36,50 C34.534855,46.023182 28.36919,45.217796 23,51 C17.748837,56.655098 20.123365,57.791729 18,65" Fill="#00FFFFFF" Stretch="Fill" Stroke="#FF000000"  RenderTransformOrigin="0.8,0.8"/>
   9:                         </Grid>
  10:                     </ControlTemplate>
  11:                 </Setter.Value>
  12:             </Setter>
  13:         </Style>
  14:     </controls:PathDuplicator.ItemStyle>
  15: </controls:PathDuplicator>

Hrm. How does one modify the styleses? I guess if I go put them in the configuration of the blog that is easy enough. Would be nice to see the actual styles in the plugin though. Nevermind! Also, the view HTML thingy in the plugin does not show the correct html if you select not to embed the styles, it still shows only the html with the styles embedded. Also also, why not define the styles inline as actual styles rather than setting the style property of each element... just saying.

After stylish modification:

   1: public override void OnApplyTemplate() {
   2:     base.OnApplyTemplate();
   3:  
   4:     RootElement = (Panel)GetTemplateChild("RootElement");
   5:  
   6:     // Just make some transformation adjustments
   7:     for(int i = 0; i < 10; i++) {
   8:         Item item = new Item();
   9:  
  10:         #region Silly Stuff
  11:         item.Style = ItemStyle;
  12:         item.Angle = 10 * i;
  13:         #endregion
  14:  
  15:         RootElement.Children.Add(item);
  16:     }
  17: }

Well, wow. Now if only I could get Studio to do alternate line colouring... Can you do that? :) I guess I would also like to see the plugin support more of the Studio display items. But it looks pretty close to how it looks with my settings.

I guess I just need to find out when it uses each of the styles... and go create the styles for each type of code snippet...

Joy!

(*) Fuck is not in the dictionary... well now it fucking(**) is!

(**) So is that :)

[Edit] Not joy! Unjoy! What is with the 3 line spacing in the code samples?! Grumble... In fact, what is with the massive amounts of extra space all over the place. Grr.

[Edit] Fixed spacing. WLW editing still a bit dodgy, but it is easily fixable in the source edit view. Can't way that I could recommend it to anyone that does not know html – i.e. 90% of people who want to blog and would love a real WYSIMYG editor... Mind you those kind of people probably would not really care about how their markup looks - which incidentally makes it all the more vital to help them produce good markup.

Friday, August 15, 2008

Magic mystery fields

[Just found this draft post that I was waiting to post for some reason... it is from the middle of last year. Almost just a rant but I typed it up so I may as well post it.]

Liaising with customers, particularly ones who are managers of their company - highly experienced in their own field, though not in IT - can sometime suck.

I constantly find myself having to explain in detail why something cannot work that exact way or why something is a problem that needs to be worked through. Their opinion seems often to be that I don't want to do it or that I say it can't be done because I don't know how. Usually it seems to stem from the problem of what is easy for humans, or obvious to us on paper is not something that the computer can do or represents some information that the system does not have.

An example from today: Employees have 4 digit employee numbers, their cards have a single digit issue number that is used after their first replacement. When they lose their card again and get a new one the issue number increments. So employee 1234's first card is 1234, their second is 12341, third is 12342 etc. (Whoever thought this kind of arrangement was a good idea needs their fingers broken.)

There are two problems that I tried to broach today (right now, before they break the system). There will soon be the need for 5 digit employee numbers (we are up to like 8500), there seem to be some people with more than 9 cards (21, 51!). The system (of course, as it stands) cannot tell the difference between employee 10001 and the second card of employee number 1000 (also 10001). The second card of employee 10001 (100011) and the 12th card of employee 1000 etc.

Trying to explain that the system cannot just take off the last 2 numbers when the person has had more than 10 cards and take of the last 1 number otherwise, did get a little frustrating. Basically when there are 2 dynamic length fields in a composite id, without any other information it is not possible to reliably extract them.

Friday, July 11, 2008

AjaxControlLibrary

So it takes a little dicking around to do it, but you can use the DropShadowExtender with the ModalPopupExtender.

I had a little problem getting it to work some time ago, then when I noticed the DropShadow attribute on the popup class I thought that there must have been a problem with using them together so I just used the internal drop shadow. Well, after finding a couple of other issues with the DropShadow attribute, and finding no way to specify opacity or rounded corners, I went back to trying the two extenders together. The solution makes sense in the end I guess. You just need to put the drop shadow on an element inside the one that has the popup, not on the same panel.

An example should be fairly clear:

<asp:Panel ID="pExecuteProgress" runat="server" style="display:none;">
    <asp:Panel ID="pExecuteProgressContent" runat="server" CssClass="ExecuteProgress">
        <div>Processing...</div>
        <div><img alt="..." src="images/status_anim.gif" /></div>
    </asp:Panel>
    <cc1:DropShadowExtender ID="DropShadowExtender1" runat="server" TargetControlID="pExecuteProgressContent" TrackPosition="true" Opacity="0.3" Width="8" />
</asp:Panel>
<cc1:ModalPopupExtender ID="mpeExecuteProgress" runat="server" PopupControlID="pExecuteProgress" TargetControlID="pExecuteProgress" BehaviorID="ExecuteProgress" BackgroundCssClass="ModalBackground">
</cc1:ModalPopupExtender>
A couple of notes about this example:
  • I have specified the same control for the TargetControlID - it has to be non null, but I am showing this popup only via JS
  • The display:none on the outer panel is to prevent the flashing of the control on page load that you can sometimes get

Just for interest sake, here are the two css classes mentioned:

.ExecuteProgress {
  border: 1px solid #000000;
  background-color: #FFFFFF;
  padding: 30px 80px 30px 80px;
  font-family: Arial;
  font-size: large;
  color: #3366FF;
}
 
.ModalBackground {
  background-color: #C0C0C0;
  filter: alpha(opacity=70);
  opacity: 0.7;
}

I gotta find a better way to post code... I just used an online encoder to HTMLEncode the text, then it is just in a <pre> *sigh*

[Edit] Code posting fixed.

Sunday, May 18, 2008

One bad apple?

It's funny, just about every website you go to sign up on that wants your email address gives you those TWO boxes to fill in. Email and Verify Email. I don't who started this, or why everyone thinks they should follow, but I wish it would stop.

I understand where this malady came from: it was some smart web monkey seeing the Password and Validate Password combo and adopting it. But I don't think they quite understood why this mechanism is needed in that case. Just to be explicit - it is only needed because you can't read what you just typed in in the Password box. For the email address, I can re-read that just fine thanks.

Besides, I figure if you can't either type in your correct email address, or read that is not correct and correct it, then you failed my minimum user requirements. There is a certain limit to how far you need to go holding people's hands.

Wednesday, March 19, 2008

TortoiseSVN

The global ignore pattern that I am using at the moment is:

*bin *obj RECYCLER thumbs.db *Debug *Release

Which is probably fine for a single developer. When working in a team you would probably want to block *.suo also.

Wednesday, November 28, 2007

The tale of Mister Splashy Pants

Online polling is broken.

With sites like digg and reddit and many others, the ease with which a group of people can sway the vote is demonstrated time and again. The problem is differentiating “real” voters from “funny” voters. It is just too easy for someone to give a voting link to a large number of people who are not really interested in the outcome of the poll, who will totally unbalance the results.

Perhaps what online polls need is to use some of the mechanics of regular political voting systems. An electoral roll with a defined closing date that is before polling commences. No need to keep voter information long term, just long enough to have the people interested in a certain poll indicate their participation, and ensure that there are no band-wagon jumpers at the last minute. An online news site post saying “Quick, register to vote on the name of the Greenpeace whale - there is sure to be a funny option: we will let you know which option we think is the funniest in a few days!” is not likely to attract the same level of attention.

Wednesday, November 07, 2007

‘S not my job.

“It's not my responsibility to fix that” or “I did not think I had the authority to ask for a certain action” You have to ask yourself a question. Am I happy with my current position in the hierarchy? If you want advancement, more responsibility, one way to get it is to assume it. Take on new roles and new responsibilities and they will become yours. That or you will be put in your place. (It may be time to move on.)

There is nothing more frustrating than someone who continually counters your requests with one of the two phrases at the top there. When I hear it some from someone's mouth what I really hear is “I am quite happy just plodding along in my job and I never want a raise again.” If I hear it come out of my own mouth... (It may be time to move on!)

Don't wait to be given responsibility. Don't wait for the person who should be doing something to do it - make it happen. It makes you look dynamic. Perhaps you will overstep the bounds of your current position, but that may just make someone realise that you don't belong there.

Thursday, September 20, 2007

I smells somethin'

Programmer 1: “What the... That code is horrible. Who did that?”

Programmer 2: “Erm... Yeah that was me. I know it's crap.”

Programmer 1: “Crap? This code gives crap a bad name. This code goes right by crap and out the other...”

Programmer 2: “Yeah, yeah okay, that'll do, I know, but I wrote that shit like 3 years ago.”

Programmer 1: “Uhuh. Umm... This code over here is just as bad... You wrote this shit yesterday!”

Everyone knows that the worst code you have ever seen is the code that you wrote 6 months ago. However you are supposed to learn from your mistakes*.

* That way you get to make new and interesting ones each time.

Wednesday, September 19, 2007

So don't press that button!

It was (probably) Murphy who said (something like) if there are two ways to do something and one of them with have disastrous consequences, the probability that someone will do it that way is 1. Thus, all good programmers ensure that pressing the wrong button at the wrong time will not cause things to blow up. Lumped in here are things like checking input, clicking in the wrong spot, pressing the delete key at the wrong moment. For these things and more we can ignore, correct or confirm inputs. Good. But you can't be pissed off when you click the wrong, but valid from the context, button and that functionality completes successfully.

For instance, there is functionality A and functionality B that both act on the current input. These functionalities are both executed thousands of times per day, there is no way to tell from context (previous operations) which one is more likely, and there is no time to have a confirmation. So when you have operators that click B when they mean A (and not notice - it is not like you can't cancel you B and put in an A) you have a training issue. There is nothing the system can do about it! That is not the worst of it though. What I really love is the service calls and bug requests saying that the reports for the operations on a certain terminal are “all screwed up, there are B's where there should not be.” So I take the 10 minutes that it takes to verify that there were no problems with the processing and what I find amounts to “That place where there was a B is because the operator pressed B.”

“Why is my transaction cancelled?” Because the operator cancelled it.

“Why did the upstairs bell ring?” Because the person pressed the top button.

“Why is there a charge of $0.01 on my credit card?” Uhh, because the cashier ran a transaction for 1 cent on your card?

Tuesday, July 31, 2007

ClickOnce - or: how to instafuck your whole installed base with one click of the mouse!

Fuck me that was fucked.

We are rolling out a new version of a program which is updated via ClickOnce. We currently (luckily) have about 12 of 80 machines installed - the rest are using the old, manually updated software. I am actually pretty glad that we had today's problem today and not in a couple of days time when the whole thing was rolled out - _that_ would have been a major shit fight.

This morning I got a request for changes. Nothing huge. Thought it would be a nice demonstration for the live update feature of the new system. 10 minutes to code. Took my time testing, 1 hour. Published the changes onto the beta site, let the test machines auto-update. Cool. I sign off on the mods, the client give the go-ahead for live. I publish on the live server. Sweet. Now I keep a test machine connected up to the live publication just so I can have a last minute test to make sure all is well. I go and run the client on that machine. The auto-update barfs. Crap. I go to look in the program group for the program. The machine freezes. Crap crap. I reboot and try again. No go. Now I am starting to get a little worried. I connect up to one of the client's live machines which is not being used at the moment and let the auto-update run. Barf. Crap crap crap. Machine freezes. Fuck. I try to uninstall the program, the item does not disappear from the control panel. I try again. Freeze. Reboot. Uninstall. Okay. Now I reinstall the new version, and it works. However the calls have started to come into the call centre... “We logged out and logged in again and it did its auto-update and now the computer is broken”. Fuuuck. So the technicians get to work some overtime uninstalling the broken update then reinstalling it from scratch, and I get to do some overtime to work out why the fuck it did not work.

After a 30 or so re-deployments in different configurations I find out that some kind soul has installed Windows Installer 3.1 on my testbed. I add it as a prerequisite so it gets installed first - now the auto-update works. So that is why my initial deployment test did not fail - there seems to be some kind of problem with the default version of Windows Installer, and I didn't see it because the testbed already was using a later version. I go check in with the technicians and we run a test on a machine that was not yet fucked up - installed Windows Installer 3.1, then let the auto-update run - no problemo. Fuck. I wanna break someone's fingers!

So after an hour of downtime for > 10% of the system I know what we have to do - re-do the install from scratch with Windows Installer 3.1 as a prerequisite. We have to start again because it has to be installed as Administrator. I am not going to be popular with the technicians...

I used to like ClickOnce. But now I am not so sure. It is very difficult to integrate into a responsible deployment strategy. When the whole system is deployed that way, how can you test a new update? I have never seen a case where the re-install (rather than the auto-update) does not work, so you can't just say that if the clean install works the auto-update will work. So imagine that all the machines are deployed from the live site - the auto-update is kind of all or nothing, you can't point a few machines at a different server to make sure the update works. I guess you could copy the live site to a test site, install from there, then update the test site and let an update go through. There is also no rollback. Once you let the update go, it's gone baby.

Just goes to show you - must have test machine that is identical to the live. Well, I'm off to padlock up the test machine... where did I put those thumbscrews?

Saturday, July 07, 2007

Wake up!

For a while now I have had an alarm clock that can wake you up to a CD. I used it a bit to wake up to music, but I had always thought that I could do better than that and create a playlist specifically for waking up. Mostly I had to have the volume up loud enough to ensure that I woke up eventually, meaning that it was too loud at the start, jarring me awake - which I wanted to avoid.

Some things that I have noted about waking up. Waking up to the beep beep alarm is not nice, but it is certain to make you leave the bed. Waking up to white noise it better, but it is possible to sleep through. Waking up to nice music is the best, but again sleeping through is a distinct possibility. When I am not super tired, I will generally wake up at the sound of the CD spinning up, or the light pop sound the amplifier makes when turning on.

So what I have thought might be nice is a kind of ramping up in the volume and wakeability of the noise. I was thinking something like: Low volume environmental sounds, white noise like, waves, wind. Most time I would wake up to this, perhaps drifting in and out of sleep, remembering dreams, getting ready to get up. Low volume relaxing music. This will make me up if I miss the first sounds, I may even get up now if I was fully awoken by the first phase. Medium volume energetic music. This signals the time to rise. Could be possible to sleep until now, if so this will wake me. Loud music that it is basically not possible to sleep through, techno, metal, something like that. The three remaining are the backup plan. I basically don't see getting to this point very often. Medium to loud white noise tones. Loud beeping. David calls in dead.

So what remains now is choice of musics. I am thinking one of the tracks from the glasshouse CD for the environmental sounds. Either one of the early movements from a Bach cannon and fugue or something from hallucinogen for the relaxing. Good wake up music... indy rock, thinking female vocal, rising crescendo... have to think about this one for the medium volume energetic. Loud music backup. So many choices... PWEI, Rage, anything a bit violent and raucous.

Should play with the audio levels on the MP3s that I create for this so that the volume ramps up nicely. May not even have to worry about the final stages, just put another loud sound on with the levels really tweaked in the MP3.

(Might also be interesting to make the playlist, then merge it all into one track so that I can do different ones with different music and use them on shuffle so I don't get sick of the same music every morning...)

Friday, July 06, 2007

Just do it

I feel like productivity people (the GTD crowd, that sleep guy, zenhabits) explaining how to lose bad habits, how to have a morning routine, how to organise your life is much the same as some happy person telling a depressed person to “just feel happy”.

I read somewhere today that when introducing a new habit into your lifestyle, “the first step is getting yourself to do it”. Fuck no buddy - the WHOLE THING is getting myself to do it. Do you not understand that what I have trouble getting myself to do is ‘getting myself to do things’?

Why so glum little girl? “I'm depressed”. Well cheer up, you'll feel much better if you just smile and be happy. Being happy is the first step on the road to not being depressed.

*Barf*