Saturday, October 30, 2004

More piratical pics!

Just a quicky...

One of my pirate mates, Mark, has put together a few more pics and video from my party. It's here. Check it out. His video's better than mine!

Friday, October 29, 2004

Good to be pushed sometimes...

I sent the link to my birthday pics to a few friends of mine last night, and immediately JML got back to me via IM.

JML's a top guy. A real diamond. He's the IT manager where I used to work, and one of the only people from there whoI stil see regularly. Mrs Mawoo tells me he's the only person on the planet who I can talk to on the phone, as well.

So anyway, JML gets back to me immediately and says 'Can I offer some constructive criticism? Your pictures look shit. What interpolation did you use on them?' So I said I used the default compression, and promptly went out and tried to find out how I can apply a different algorithm to the images being shrunk (Curse you JML! I was about to go and watch some CSI!).

Good job I did, though, because I learnt a really cool, and quite fundamental thing.

System.Drawing.Graphics.FromImage() Doesn't give you a new blank canvas
Rather, it takes your blank canvas (or your canvas with an image on it) and allows you to use GDI+ to play about with it. Everything you do, though, every string you draw, every change you make, is made to the original image, not to a new one. To give an example:

Dim pic as Image
pic = pic.FromFile("C:\Monkey.jpg")
Dim little As New Bitmap(CInt(pic.Width / 4), CInt(pic.Height / 4))
Dim g As Graphics = Graphics.FromImage(little)
With g
.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
End With
g.DrawImage(pic, 0, 0, little.Width, little.Height)
little.Save("C:\SmallMonkey.jpg")


Now, yesterday, I would have said 'What? What are you doing saving a blank bitmap?'. That what it looked like to me. If you read through the code, it looks like the sequence of events is this:

  1. Open the original Image File
  2. Create a new blank Bitmap object 1/4 the size of the original
  3. Create a new Graphics Object, copying into it the blank cnvas you've just created
  4. Draw the image etc. on the new Graphics image, leaving the original blank bitmap (little) untouched
  5. Save the blank bitmap (little)
That's what it looked like to me, anyway.

I used to imaging the Graphics object as a posh bitmap, a bitmap tat you could do some whizzy things to, like write text on it and things like that. I now understand much differently. Rather than imagine the Graphics object as a blank canvas, I rather imagine it kind of like the team of robot arms that run around cars, welding bits together. You know the ones. When the car stops on the conveyor belt, and then a squad of robot arms comes out and welds, glues and paints everything before the car moves off again. That's how I visualize it now. Robot arms. With the car (or Bitmap, in this case) in the middle. Neato. And it answered a lot of questions.

This bit on MSDN helped me out a bit too.

It left me in a really good mood. For some sick reason, I actually get quite a buzz when I find out something new. I'm still really lazy, though. I wouldn't have played about with the Graphics object and found out what a cool thing it is without JML telling me 'Dude, your pictures are shit! Sort them out.' Thanks!

Just needed to share.

Thursday, October 28, 2004

Happy Birthday to me!!

Well it was my birthday last week, and after having a bit of a mare trying to get my pictures shrunk to web-size, I've finally got them online here.

You might find the layout of the page a little familiar. I really am lazy when it comes to layout.

Just one quick note, the video of the final (Mrs Mawoo versus my mate Rod) was made using my SPV E200 Smartphone. It's not the greates quality, but hey, it's a phone. What did you expect? Spielberg?

Just wanted to share. Feel free to tell me I look great in a hat and eyepatch.

Doh!

Don't you hate it when you do something so stoopid it makes you want to cry? That happened to me just this morning. Bugger.

Over the past couple of days I've been writing just a very quick easy app to batch resize a folderful of images. I wanted to get a bunch of pictures from a party (it was my birthday Saturday. Woo and Yay) and resize them to put online somewhere. SImple, I know. Yes, I could have donme them by hand. Yes, I could have downloaded one of a million free utilities to do the same thing, but hey, where's the fun in that?

Originally the plan was to do it this way:

  1. Load the image
  2. Create a new image (in GDI+) from the original image's GetThumbNailImage method
  3. Save that image
Simple huh? It's something I've done a few times for creating thumbnail images on the fly.

Turns out (and I didn't know this before) that if the image file already has a thumbnail associated to it, it just takes that image and resizes, rather than taking the original and resizing it. As a result, half of the images that were produced were horrible pixellated crap. Not good. So I spent a few hours trying some other stuff, looking for resize methods in all of the GDI+ objects, and a whole bunch of other stuff. I even toyed with writing my own resizing algorithm to do the job I wanted. I didn't go down that route, though.

No. The route I went down was very very very easy. I'm even ashamed to admit that I had spent so much time thinking about it and playing with so many different things to arrive at this point. No.

Turns out the Bitmap object has a very nice constructor (yes, a CONSTRUCTOR! Note emphasis. I really was being that dumb!) that does it all for you. It goes like this:

Dim x as new Bitmap(Original as Image, Width as Integer, Height as Integer)

Dammit! It really hurt to delete the whole bunch of code I'd written only to replace it with one line.

And the even worse part? I haven't even got round to putting together a nice HTML page to put them on yet, so wrapped up have I been with trying to sort out this resizing thing, so my birthday party's still not online yet. When I do it, though, I'll put up a link.

Just wanted to share my stupidity. I'm hoping I'm not the only person who's had experiences like this!

Friday, October 22, 2004

Strange...

I've been playing a bit with non-rectangular Windows forms (using a background image and transparency key), and have discovered some strange things.

The TransparencyKey property doesn't work
Well, this is a known issue. The TransparencyKey property doesn't work on systems where you've got your screen colour depth set to more than 24 bit. Bit of an oversight in my book, but there you go.

Quick google search cured that, though. The problem can be solved by putting the following lines of code in your form.initialize method:
Dim Img As Bitmap = Me.BackgroundImage
Img.MakeTransparent(Img.GetPixel(1, 1))
Me.BackgroundImage = Img
Me.TransparencyKey = Img.GetPixel(1, 1)


That works, but seems to have a bit of a strange side-effect.

If I add a control to the form, a ListBox, say, and set its BackColor to Black, that control becomes transparent too. Like properly transparent. I mean it looks like there's a hole in the form. Any other colour's fine, it's just black makes a hole in the form.

It only seems to happen on the form with the transparency key stuff going on. On standard forms, it doesn't happen. Black controls look just as you'd expect. Black.

It's kind of disconcerting, seeing a selected item (blue bar and everything) floating seemingly in space (well, floating with a bunch of code behind it.

If anyone can figure out why this is happening, let me know. I'm really quite interested.

Anyway, that's what I learnt this evening.

PS - Feel free not to tell me the answer if you do know. I just needed to remind myself of an interesting thing I need to read up about.

Aha!!!!

Before I start, you're going to have to bear something in mind. I live in the UK. Which means that I'm at least 12 months behind the rest of the world when it comes to technology.

I had one of those proper 'Aha!' moments last night over the .NET framework 2.0. I went to an MSDN talk last night, ostensibly about Visual Studio Express. I'm not really that interested in the express versions per se, but I wanted to have a bit of a look at what the implications were for Visual Studio Standard Edition. What would the effect be of adding an extra layer of products at the bottom of the product line (bottom in terms of features and functionality, I hasten to add, not bottom in terms of the people using them!) have on the previous bottom of the ladder product.

And it looks good (providing the price for Standard stays about the same). Smart device development looks like it's supported in VS Standard, which is something I really kinda like. And it looks to be all round goodness in a box.

That wasn't what got me excited, though.

What got me excited was ASP.NET 2.0. Although I'm going to have to have a deeper look into how they really work, some of the data access features of ASP.NET look to really rock. Being able to put data sources with (and this is the important bit) parameters bound to other controls on the page right in the code on the ASPX page looks really cool. I'm sure there are security issues there, which is why I'm going to have to have to have a deeper look into how it works, but on the face of it, for quickly banging together web forms apps it looks like a really good thing.

Snaplines in Windows forms got me really fired up as well. Although I've seen quicky demos on channel 9 and the like, I never really appreciated just how funky a feature this really was. It's fantastic. Being able to snap controls so they line up with any of a dozen reference points (The top of the control, baseline of the text, middle of the control etc.) is really quite good. I might be biased because I've been knocking some forms together in Access, where that kind of thing is really quite hard. And even harder to do quickly without losing your train of thought.

The code editing formatting options are also really good. The demo showed a load of the options available in c#, like where opening curly brackets start and end (on a new line, inline etc), and stuff like that. In ASP.NET as well, the days of VS reformatting your code every time you switch from design to code view and back are gone You want to have a block of text hard-up against the margin, you can have a block of text hard-up against the margin. It's all preserved for you. Nice.

Data Access thingys in windows forms are quite cool as well. In the quicky demo the guy showed us, he did essentially what the Data Forms Wizard does in VS 2003, but all with just pure drag and drop. Just pull a datagrid onto a form (if I remember rightly) set its data source and run the app. It automagically generates the code to populate the grid, and even gives you a navigation menustrip to boot. The whole thing took under a minute. Sweet.

And the best thing, the thing that'll have me running out to the shop to buy VS the day it comes out, the thing that'll stick in my mind, the thing that when people ask me 'So what's so cool about VS Express?' I'll tell them about... They gave us beer and Pizza! God I'm a cheap whore.

Just wanted to share.

P.S. Sadly not many links to documentation. There's not a great deal online yet.

Tuesday, October 19, 2004

Another stoopid test...

You are .dll You are dynamic. You are constantly in danger of bringing down the house, because you don't play well with others.
Apparently I'm a .DLL.


The next couple of weeks or so mihgt be a bit light on .NET stuff. And generally light overall. I might be working on an Access project for a little while.

Yeah yeah, I know. It's Access. Which is bad on more levels than I care to imagine, but such is life.

Just wanted to share.

Friday, October 15, 2004

Blogging on Demand #3

Okay, this isn't a technical search that brought someone to my blog, but I thought it's be quite an interesting thing to write about since it's something I have (I think) a fair degree of experience in. And often colleagues at work ask me about it.

Mostly, they ask 'Why?'

Learning VB.net (via Yahoo)

Well, it's nice and vague, and I guess it is the title of my blog, so why not write a bit about my experiences learning VB.

Know that you know nothing
This I learnt after about 2 minutes playing with Viual Studio. I came from programming VBA and (gasp!) Access, thinking, 'Hey, know how this stuff works. I can write code that talks across applications, I know what a Select Case does.' I learnt very very soon that I didn't know diddly. I could talk for hours about the differences between VBA and .NET, but I'm not going to. You could try looking here for some inspiration. The 2 things that struck me first were

  1. The .NET framework is huge. To paraphrase Douglas Adams "The .NET framework is big. Really big. You might think the MS Word object model is a bit overwhelming, but that's just peanuts compared to the .NET framework."
  2. working with objects in VB.NET is completely different to working with objects in VBA. Nicer, I'll grant you, but nonetheless very different.
Unless you're really forced very hard to produce something concrete, it's very difficult to pick it up and start typing away.

In fact, I'll go as far as to say that I was so clueless about VB.NET when I first picked it up that even the help docs were next to useless for me. I mean, MustInherit? What's that all about?

Quickly, though, you'll notice something quite nice, though.

The world wants to help you (for free!)
It's true. There are a million and one places to find out about .NET. ASP.NET, WindowsForms.NET, Microsoft, everyone. If you need to find something out, it's all there. The .NET community rules. Honestly.

I sometimes post entries about webcasts and other various resources online. I love 'em. The web is a beautiful, beautiful thing for learning. But...

You can't beat a good bit of study
Unfortunately here's the pisser. Although there is more free interactive, lecture-based AV stuff out there than I have time to watch, there's nothing like sitting down for a few hours and reading. Studying is something that just unfortunately won't go away. No matter how far we advance in presentation techgnology, styles and material, if you really want to learn about something, you've got to graft for it. I tried learning a bunch of stuff through fluffy online tutorials and stuff, but when it came down to it, I learnt far more and got a much deeper understanding of the subject though just solid reading. In a way I'm lucky. I get the tube for an hour in the morning and an hour in the evening. There's 2 hours every day to just read and read and read.

An oh my, there are some books out there.

I'mk not going to start reviewing books, I can't be bothered, and hey, it's my blog. I found the Unleashed series and the teach yourself ... in 21 Days from Sams really good introducions to .NET. Personally I tend to stay away from the 24 hours books, butthat's just me.

The Dummies series is quite cool right at the very very beginning. In fact, it was this book that first made me think 'What, you can get a computer to do ANYTHING YOU WANT? Cool.'

Write stuff
I generally dont like doing the tutorials in books. I tried it, but here's the scenario I usually find:

Picture the scene. I'm sitting at home in front of my computer, book on my lap doing a tutorial. I type what it says in th book, nodding sagely at every line, saying to myself, yep. yep. Uhuh. Understand that.

Run it. Get an exception, AND THEN (here's the important bit) what do I do? Cancel the Unhandled Exception Dialog box and scour my code checking it against the book looking for the typo. Useful? I think not.

Instead, I just read the stuff think of a similar, but not identical problem, and try to solve that. Or, think of a task loosely based on the book example, but incorporate into it something I already know. I always find that where I thought I know loads, I actually know diddly when I come to integrate something that isn't in the book into the code I'm writing. Might just be me, though.

Or, do something kind of unrealted, but using just one bit of the stuff in the book. My favourite aplication I wrote, the one I'm most proud of, and the one I tell my friends (well, if we're being honest here, friend...) about is ASP2WMP which I wrote to explore remoting a bit. I got tired with populating a datagrid with the Northwind Products table. So I did something completely unrelated, but using just one apect of what I'd read that day. In fact, ASP2WMP was developed in several stages as I learnt about more stuff from the book I was reading at the time.

Answer questions
When I was getting my head round ASP.NET, I started answering questions in the ASP.NET forums. Sometimes I'd play it safe and stick to what I was absolutely sure of, but sometimes I'd try and solve a problem I wasn't too sure of and then come out with an answer. They weren't always particularly bad answers, either.

I don't know about anyone else, but I am very very lazy. That's why I started programming. I figured 'I really can't be arsed with all this work. Why can't I get a computer to do it instead?'. Well, being lazy, I really can't be arsed making problems for myself. The downside? No problems, no solutions. So I tried solving some other people's problems instead. I find that once I explain something to someone, it makes it much easier or me to crystallise that knowledge in my head too.

I think that's about all I've got to say about how I'm learning VB.NET. This is all just based on my own experience, mind you.

Oh yes, just one quick note, there's nothing annoys forum types (not me, but I occasionally see some pretty terse replies) than people eho just can't be arsed looking. So before you start asking other people questions, make sure you've checked:
  • The Help Files
  • The MSDN Library
  • Google
  • The forum itself, to make sure nobody else has come up against the same thing before
Just wanted to share. Sorry it's such a huge beast of a post. If you've got this far, then my heartiest congratulations to you. And thanks.

Wednesday, October 13, 2004

Sharing the Love

"This fella has a nice web log with some good information and seems to be right up our alley"
Some people say the sweetest things. Right back atcha dude!

Just felt the need to share.

Ever wondered which to choose?

Krzysztof Cwalina has written this very good blog entry about the questions and issues you should be addressing when you're choosing whether to implement factory methods or constructors. I know in some situations, you don't have a choice, certainly when you get into the remoting and COM+ arena, you have to use factory methods since there can be issues with overloaded constructors, but otherwise how do you decide?

Found via Mike Gunderloy.

Just wanted to share.

Monday, October 11, 2004

Blogging on Demand #2

Every now and again I go through my referral logs to see if there's anything interesting bringing people to my site, and if so, I've started writing a little bit about them.

I've previously written about the arraylist.Copy method after someone landed on my site looking for it in Yahoo.

This week someone landed here looking for "sessionid tutorial example vb.net" from Yahoo.


Session.SessionID returns a String, which is the web server's internal identifier of the current session for that particular user. It is this number that gets passed around in cookies and whatnot that allows ASP.NET applications to manage session state.

Although 99% of the time, normal people will never get to see their sessionID getting passed about (it's all done in the background) there are a couple of situations where the session ID is passed in the request's URL. The most common ones are:

Mobile web forms
Although mobile web apps are getting more widely used out in the real world (I've even written one or two myself), some things, like cookie handling, haven't been adopted in any kind of standard way. Some browsers on some devices have cookie handlig, but not all. As a result, the only way to tie the requests from the browser to the session state being managed on the web server is through the URL. If you ever navigate to a mobile webapp from Internet explorer, you'll notice that the URL in the address bar changes to something like "http://localhost/MyMobileApp/(biiig long number here)/Form1.aspx". The big long number being passed abut is the session ID.

Cookieless Sessions
In the same way that mobile web apps pass the session ID in the request URL, normal web browsers do that as well if you configure your app to use cookieless sessions. Kinda makes sense, really. If your user can't receive cookies, then you need some mechanism to associate the user with the session object.

There are one or two security issues, as well as aesthetic issues when it comes to passing session ID's in the URL. As far as security goes, putting the session ID in the URL makes it easier to copy/paste that URL into their browser and hijack someone's session. Not good, particularly if you have a website with restricted/controlled access areas.

Aesthetically, as well, it looks ugly. Big long URLs are bad enough, but put a session ID in there, in brackets, and that's just getting silly. If you've built your app properly, then if someone comes back with an invalid session ID, then nothing'll happen. Your app will gracefully handle the situation, and your user can continue as normal. I only mention this because of one of the other problems with cookieless sessions - if your app doesn't handle an invalid session ID properly, then you're going to have a number of users upset with you because they can't bookmark your site.

Well, that's about all you can say about SessionID. It's a member of the System.Web.SessionState.HttpSessionState class, and is used by the server to differentiate bewteen user sessions.

That is all.

Sexy Sexy

My mouse packed up a littl ewhile ago, and my emergency mouse gave up the ghost last week. As a result I've spent the past week not being able to click/drag anything. It's been an experience, I can tell you!

Anyway, I've just been down to PC world and picked myself up one of these little beauties!.

It's terribly sexy and a very beautiful thing.

Just needed to share.

Saturday, October 09, 2004

Census madness

Nobody really likes giving all their personal information out. Lengthy registration processes, identity rape and the like really wind people up. Especially me.

We know it's not a particularly new idea, ever since the Doomsday book, the powers that be have kept records about everyone in the land. And now there's the census to content with. Which is fine, if you're into that kind of thing. Not everybody is, though. At the last census a couple of years ago, there was a bit of a mission to get Jedi acknowledged as a religion. Turns out Brighton has the most in the UK (2%).

What I found out today was that it's not a new idea at all. They did it in 1901 as well. Either that, or someone's been cursed from birth being called William Poop.

Well I thought it was interesting, anyway.

Wah!

Just when you think your blog's going down the pan, with nothing on it at all worth reading, the great lord himself links to your blog. (And before you start asking, yes. I am trying to curry favour so I'm more likely to win free stuff.

Just thought I'd mention it.

And hey. Leave comments. I don't care how irrelevant they are, or what. Leave commentary. Even if it's just to call me a jerk, I wanna know. Do it. YES, do it! Now!

PS - if this post looks a bit crazy, it's for one/many/all of these reasons:

  1. It's nearly 5 am and I've been up all night listening to DotNetRocks...
  2. Whilst drinking scotch...
  3. After quite a good evening (sorry, nothing to do with code, computers, or anything like that. I'm just in a good mood.)
Just wanted to share.

Friday, October 08, 2004

Well, at least I'm not going to Hell yet...

Looks like, at the time of writing, my blog is only a mere third Evil.

This site is certified 33% EVIL by the Gematriculator

It's more evil than Rory's blog (28%), but less evil than MSDN (58%). So that's OK.

That is all...

EDIT: After I added this entry to my blog, my evil rating dropped to just 23%. I'm keeping the 33% rating, though.

Edit to the Edit: Although my blog Evil rating has gone down, it turns out, in a rather cool way, that my name is 99% evil. I'm impressed.

Thursday, October 07, 2004

What I learnt this week...

I spend quite a lot of my time learning how to do stuff. This is why many of the little ptojects I start working on amount to nothing. In that way, I guess I'm kinda like a mathematician, the guys who go "Well, we'll solve the problem to this point, but then, of course we already know how to do it from here, so there's no point doing it again."

Sometimes it's kinda cool that way. I do at least keep myself interested and avoid doing a whole load of drudgery (and by drudgery, I mean 'stuff I already know how to do')..

Anyway. I learn how to do stuff. And this is what I've learnt how to do this week:
Using SQL Server SCHEMA_INFORMATION

The SCHEMA_INFORMATION views give you a way of writing stored procedures that can pull out some of the metadata about your database. You can pull out data about tables, columns, contraints and all sorts of other stuff about how your database is structured.

I thought it was kind of useful. Particularly for the code generation widget I'm writing at the moment.

Quick note to self:
Regarding the code that's actually generated, I'm making it generate abstract classes, rather than getting it to generate normal classes for 2 reasons:

  1. I can extend them nicely once they're done
  2. I can make a DB design change and regenerate the code. It'll sling out a whole load of compiler errors, depending on what's actually been changed, but (and here's the inportant part) it won't overwrite what I've already done to it
  3. It'll force me to think more about inheritance when I'm actually using the code generated from it. So far I've coding without really using inheritance that much. Bad me! I need to make myself get my head well and truly round it


That is all. Just wanted to share.

That's what I was after...

Just found UI Patterns and Techniques (via Duncan Mackenzie)

I've been looking for a site like this for a while now. UI design is something that I've been kind of thinking abot for a little while. There's a very good site here that's got just bucketloads of UI design disasters and successes. Unfortunately, it's starting to get a bit old (It hasn't been updated or a number of years...), and although a lot of the advice on there is still very valid, there are some aspects where the technology and users have moved on and adopted (rightly or wrongly) some of the design widgets on there.

Patterns and Techniques is more up to date, featuring a lot of the design-schema (if that's a real world) adopted from the web. Although I'm not a big fan of web-style windows apps, I know many people do find them quite familiar and intuitive to use, so I guess they're here to stay.

Just wanted to share.

Aren't I nice?

I'm entering Rory's stupid contest, and I'm lowering my chances of winning by telling you about it, too - neopoleon.com
I mean nice about lowering my chances of winning. I know I'm not nice in real life...

Wednesday, October 06, 2004

Youch!!

The muse came and bit me really hard the other day.

I think I must have been thinking of 6 things at once, when all of a sudden all these things got jumbled together and started joining up. I was thinking of something like this:

  1. Bill Vaughn's presentation at DevDays about data access in Smart Client applications
  2. Rory Blyth's general bias against Datasets (I'd link to something specific, but I can't remember exactly where I heard it
  3. This Episode of DotNetRocks with Scott Hanselman talking about code generation
  4. A conversation I was having with a friend of mine about how it's quite dull and boring essentially building a data model in SQL Server, and then translating that into a set of .NET classes to use in an app
You can probably see where this is going...

I've decided to see if I can write a little app that automatically generates classes from a SQL Server database. As I see it, it'll go through the DB, convert all the tables to classes. Sounds simple. And it will be. It won't be a giant multi-functioned fully fuctional code-generation app with accompanying syntax and stuff. It'll just be something I use to create classes after I've built a DB. I always prefer building a DB to model my data to doing it just in code. It's probably just me and the way I think. I've been working with databases longer than I've been writing .NET, so I just find it easier to conceptualise it this way.

The key things my little script will do are:
  • Generate interfaces for each object
  • Create abstract classes that implement each interface
  • Generate either dynamic SQL or a stored procedure on the server to handle data access
So that's that.

As I go along, I'll expand a bit more. But it's quite fun at the moment.

Sunday, October 03, 2004

What's wrong with this picture?

I've just been looking up some event info on MSDN, and I came across this page.

Now here's a little exercise:

  1. Read the first 5 menu options, or the first 5 links along the bottom. Just the first five, mind you!
  2. Based on those first five values, take your best guess at how they're ordered.
  3. Find United Kingdom.
Now normally I see this list organised alphabetically. I know that the UK's 2 rows below the USA (I think, it might be 3), after United Arab Emirates.

What crazy ordering scheme lead the web developer here to put United Kingdom between France and Greece?

Well, you don't really have to answer that. I think I've got it figured. The name of the region (France, United Kingdom etc.) is taken from the culture defined by the system. That's fine. That's why there are so many. I can handle that.

Where it falls down, however, is whoever put the page together ordered the list items by the specific culture key (e.g. the 'us' in 'EN-us'). The specific culture key for the UK is 'gb' (That's why the URL in the link above ends in 'culture=en-us') which is why the UK sits between France ('fr') and Greece ('gr', I think).

Would it have been that much hassle to order the list by the output text, rather than the culture name? Oh well. It does give me another thing to remember next time I'm building something with data:

Make sure your lists 'n' stuff are ordered using some sort of sensible, obvious scheme.

Just wanted to share.