Month: April 2014

Salary Negotiation for Sissies.

First off, may I say, I really SUCK something awful at negotiating salary. And why wouldn’t I? I do it maybe once a year, if that; I’m negotiating directly for myself (no middleman), and it’s outside my core skill as an engineer. I want to move past this as fast as possible and get back to doing what I love: everything BUT talking about money. Well, guess what? That’s the story of every other programmer I’ve ever met.

I’ll do you a solid and not drone on endlessly what you can read in more detail (and much better written) elsewhere. But, it does come down to these points:

  • Never give a number.
  • Salary negotiation is the most important financial decision you make. More even than owning a home.
  • Your actual (fully loaded) cost to an employer is several times your base salary. They will not get a bonus by nickel and diming you, and they will not be offended if you ask. You will not be blackballed. $5,000 is, in the scheme of things, chump change.
  • They’ve sunk thousands invested in just talking with you, so – assuming you have agreement-in-principle after several rounds of interviews – they want you. Negotiating will never make worthwhile offers worse.
  • Once again, never be the first to give a number.
  • Use words like “We” and “You” (which is better, since people care a lot more about their problem than yours.)

Ahead of time you should know the following:

  • What the marketplace will support.
  • What you are worth, what value you provide – with specific examples.
  • Know your three numbers – the money you want, a good “settle” number, and the drop dead bottom line. NEVER tell them that third number!

Do NOT say – “What’s the salary range?” You should already know this from your market research. Dice and LinkedIn exist, use them! In your tone, don’t be adversarial – and give longer answers than in interviews. Iterate that you’re excited about the job. The tone is, I want to be here, I’m going to add a tremendous amount of value, here’s what I’m worth – let’s find a fair # that works for both of us.

Talking Points

So here’s some scripts to talk from:

“What’s your current salary?”

  • Do NOT say: A specific number. You can’t lie here. But you are backed into a corner… and this isn’t the time to So you evade:
  • I’m willing to entertain any reasonable offer.
  • I’m confident I’m within your range.

“I really need a number to move the process forward.”

  • Do NOT say: First and foremost, NEVER give a number. They’re trying to get you to compromise your negotiating position.
  • Say: “I’m more concerned about discovering whether we’re a mutual fit. If we’re a great fit, then I can be flexible on the numbers with you and you can be flexible with me. If we’re not a great fit, then numbers are ultimately irrelevant, because your companies only hires A players and I only work at roles where I would be an A player.”
  • Honorable mention: It’s so important to me that this is a good mutual fit. Let’s talk about why I’m a great fit for this position; I know you’re concerned about ____. In addition to my previous successes, I have some great ideas on what I’d do on this… Would you like me to drill into those or is there another job area you’re more concerned about.”
  • Well, you know, I would hate to have to walk away from the negotiation over this. Working with your company looked like it would have been such a wonderful opportunity. The market is tight right now. Hmm. Well, salary is one part of the total compensation package. In terms of total compensation, we’re probably looking at something like $200K, correct? (30-50% + FT salary)
    • OTHER AREAS: Training. Vacation days. Project assignments. Travel.
  • “Hmmm. This is an important decision where we both have to walk away happy. That means me taking a specific number to my wife for consideration.

“We were thinking about $60,000 and maybe throwing in a can of pork and beans.”

  • “60,000 is interesting but not quite where we need to be to get this done. Do you have any flexibility on that number? … That isn’t quite what I had in mind, but the right package offer could make that attractive. How much vacation comes with the package?… If you could do X days a year (or a bonus of $___, etc), I could compromise on $*****.”
  • “First off, I just want to say, I’m very excited about this opportunity. I really want to work for XCORP. The experience I bring to the table in previous roles directly translates to this and I believe warrants a much higher salary. In terms of my own research on the marketplace, the range is more like $XXXX to XXXX. Given my experience and my ability to deliver value, I believe I deserve to be at the higher end of the scale.
  • At the end of the day, I would look at this as an investment. At the end of the day, I think I’ll be able to deliver more than that $XXX difference.

OK, I talked with my manager, and he’s offering $67,000. Plus two cans of pork and beans. Would that be acceptable?

  • “You know, one of the things we didn’t talk about was all the things around salary. Stock options, bonuses, vacation days. What can you come to the table with here.”
  • “I think that goes a long way towards closing the gap. I really appreciate your flexibility there, because I am committed to this role, and options are a great way to demonstrate you’re committed. What would the review cycle be for my performance as far as evaluating my candidacy for a promotion and a raise? My understanding is that it tends to be a year, ”

 

Other links:

 

Don’t call yourself a programmer.

This post is terrific. To sum it up –

  • Don’t call yourself a programmer, which is a codeword for peon. You’re an engineer.
  • Engineers are hired to create business value, not to program.
  • If you’re not working for a revenue center – i.e. if you can’t tie your work directly into reducing costs or adding revenue – get a job where you can.
  • Coworkers and bosses are not your friends.
  • Sending in a resume to an ad / Dice position is for losers. Most hiring is done behind the scenes, for positions that never hit publicly. So network.
  • You’re not defined by your chosen software stack. Look for opportunities to branch out and try new things. Pilot projects rock.
  • Modesty doesn’t sell. Neither to buzzwords. If you can’t explain what you do to an eight year old, try it again – and make sure you can communicate how you create value.
  • … and at the end of the day, your life happiness will not be dominated by your career.

That last point, I buy into mentally but not yet emotionally. I do tend to invest quite heavily in the success of project X or company Y. Isn’t life simpler when we’re more heavily invested in our OWN success?

WebDeploy again and IIS setup issues

 

Went thru setting up a new server with Web Deploy. once again (and it feels like I’ve posted on this a dozen times, but it’s probably only about 10) I walked thru the following:

  1. Remote desktop onto the box.
  2. Setup Google Chrome so I could get around IE’s insane “trusted sites” security-through-obstruction policies.
  3. Installed Microsoft Web Platform Installer 4.6.
  4. Used this tool to install Web Deploy 3.5.
  5. Used WPI to set up IIS Recommended Configuration

At this point I was able to go into Visual Studio and deploy a website out to the Default Web Site\{MySiteName} folder that I created. Yay! IIS_IUSRS had sufficient privileges, etc.

Still though I was getting this error message:

Which was odd.The “ASP.NET is not installed” note is a dead giveaway. My first thought was that we were missing some security settings or a key component. But no, everything looked jake:

 

I tried an admin command prompt and reregistering aspnet_regiis as follows:

c:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i

 

… but had forgotten that in Windows Server 2012 this is done with the “Turn Windows Features On and Off” app. So, I ran that – and lo and behold, a few key things that ASP.NET 4.5 needs weren’t set up initially:

 

I guess this is what happens when someone else “sets up” a server partially (sigh). Easy to fix though. After the setup of these missing roles, voila – suddenly I could (without a restart even!) browse to my site locally, and remotely. Easy!

Experiments with tiling and FontAwesome, and image hotspots

Just a few notes to dash off today before I’m back to the grind.

Metro and FontAwesome

I wanted a Metro tile look without having the high overhead with the Telerik set of controls, and a Windows 8 or WPF application was off limits per my client. And, I only had a few days to put together a demo. What to do?

Well, the good news is there’s a host of CSS options for you out there. This site has a comprehensive set of stylings that work OOTB. The one I chose was metro-bootstrap from this site – http://talkslab.github.io/metro-bootstrap/ – and a full description of sample components a la Bootstrap are here: http://talkslab.github.io/metro-bootstrap/components.html. So putting together an icon was fairly easy. (On FontAwesome, here’s an icon cheatsheet – excellent! http://fontawesome.io/cheatsheet/) And in a jiffy, I had a clickable interface that displayed tiles without having to jump through a lot of hoops – so I could focus on the data and not the look and feel. Yay!

Hotspots

Feels weird to say this but I’ve never put hotspots on an image before. Yet the operators at this facility think in terms of physical machines – so it makes sense for the UI to key off of a factory layout. The idea is, when you hover over a particular area or click it, a list of the part numbers in progress at that station will display. To do this, I installed Expression Web and took my snapshot and dropped a set of rectangular hotspots on the image:

Once this was done I took the raw HTML and translated the coords to a set of Left/Top/Right/Bottom elements the way the asp:ImageMap control prefers, see below:

 

And, voila – a clickable image map. HTML5 goes even further with its <map> element – you can do some pretty neat things without having to resort to a ImageMap or a similar control, and keep it native. Enjoy!

Other Links

 

 

 

 

KnockoutJS and WebAPI tricks are for POCO, kids.

Below are notes – mostly for me – on trying to get a KnockoutJS/MVVM/EF6 going with an existing database. I’m not going to presume that what I attempted is impossible, but for now I’m stepping back from MVVM and going to MVC/EF6. Here’s why.

I’ll cut things short and give it to you straight. You’ll find most of the webAPI samples you see out there are code-first. I think there’s a reason for that. For MVC applications, maybe a straight up EF6 model, database-first, is the way to go – with Linq to SQL. There it is, for now.

Walkthrough

Here’s the general pattern I as going for: (Thanks Mike Wasson, you rock!)

 

In more detail – we’d like a wire format like the following. This works, just great, if you follow Mike’s article below explicitly, and use POCO code-first approach. It bogs down, as we’ll see, with db-first.

 

In review: Knockout.js is a Javascript library that makes it easy to bind HTML controls to data. Knockout.js uses the Model-View-ViewModel (MVVM) pattern.

  • The model is the server-side representation of the data in the business domain (in our case, products and orders).
  • The view is the presentation layer (HTML).
  • The view-model is a Javascript object that holds the model data. The view-model is a code abstraction of the UI. It has no knowledge of the HTML representation. Instead, it represents abstract features of the view, such as “a list of items”.

The view is data-bound to the view-model. Updates to the view-model are automatically reflected in the view. The view-model also gets events from the view, such as button clicks, and performs operations on the model, such as creating an order.

 

Our goals:

  1. Build a SPA and be able to log in with our SQL db
  2. Demonstrate ability to fire off a sproc to create a serial number
  3. Admin tools – Basic editable view of Processes and Steps.
  4. Display, entry and validation of a basic workflow on one process in buildHistory.

To do this I tried the following steps:

  1. Created a new ASP.NET website using the Single Page Application template.
  2. Changed the database connection to point to my SQL database. This has a set of tables we’ll need populated (AspNetUsers, Roles, etc.)
  3. Built and tried to log in – successful!
  4. Create a subfolder off Models called AutoGenerated and right click on it to add a new model to your existing db:
  5.  

You’ll see the following:

 

Go through ProductType.cs and copy and paste it to the main Models folder. Then go nuts on it. Add a reference to System.ComponentModel.DataAnnotations, and add some attributes. Make the ID fields so they don’t scaffold; add some Required attributes, etc.

 

There’s all kinds of cool things you could do above. Add CustomValidationAttributes, link to enums for dropdown lists, data type attributes, rangeattributes, regular expression and string length validators… the world is your oyster. Side note – I saw a ref to System.ComponentModel.DataAnnotations in the project, but couldn’t refer to it in the class. Turns out, when I chose the SPA template as my starting point, it was pointed to an older .NET framework version – .NET 4.5 versus .NET 4.5.1. Big difference!

Then go into App_Start and add events using Entity Framework for the Product class.

Build. You’ll need reflection to be up to date for the next step.

Now, right click on Controllers, and select Web API 2 Controller with actions, using Entity Framework.

In the next screen enter a good logical name for your Controller. Here I’m shortening the table to Product. Below I clicked on the new data context button – but don’t do this, just use the context you used with EntityFramework that’s already in your web.config.

Build it in your browser. Log in, and click on the API menu item. Look at the snazziness! Your new Product API class is available and – does it serve up data?

 

Punch in {yoursitename}/api/Product, and voila – hot steaming cup of JSON! (And, turns out, not so much – when I added new entities to the model, it returned EVERYTHING.)

Side Note

Trying to create a model initially didn’t show asynchronous methods available, which I favor. EntityFramework didn’t show in NuGet. However, running Install-Package EntityFramework in PackageManager Console did the trick. Now I see the following:

However, I’m still not getting reliable results. WebAPI, you’re out of time… for now. Sorry, would have been terrific if it was truly code-first.

In Summary

So, very frustrated. I think I’m trying to beat a square peg into a round hole. I’m getting [] JSON responses on my web services. Code that SHOULD work doesn’t; I honestly think WebAPI is meant for code-first/POCO approaches. There’s LOTS of examples, some very elaborate, of getting WebAPI to work – I’m thinking in particular this one and this one – without an existing db. But EF generated entities just aren’t working for us with a db-first approach. I’m running out of time; bagging it, and going with what I do know works – EF6, MVC generated controllers, so long MVVM/KnockoutJS. Simply put I don’t think we can guarantee delivery in the time the client demands at this point.

 

 

 

Helpful Links and References