Tackling Regex – Value cannot start or end with space, but can contain spaces and selected characters, up to max length

Regex Sucks!

But I needed to update a form field regex validation, so I tackled it head-on and won.

As a side note, regular expression creation is also one of the best examples of where Test Driven Development (TDD) works well. You really cannot create or maintain a regex without having all the test cases written first.

 

Validation Requirements

For a value entered in the field, it:

  • Cannot start with a space.
  • Cannot end with a space.
  • May contain a one or more sapces (surrounded by other allowed characters).
  • May also contain the following characters: A-Z, a-Z, 0-0, “-“, “_”, “\”, “/”.
  • If a value is entered in the field the total character count may be from 1 to 20 characters.

 

Regex String

^([A-Za-z0-9\\\/_\-]|([A-Za-z0-9\\\/_\-][A-Za-z0-9\\\/_\- ]{0,18}[A-Za-z0-9\\\/_\-]))$

Regex Summary:

  1. For the first group (green):
    1. If the string contains only 1 character, ensure it is a valid character.
  2. OR, for the second set of 3 groups (purple):
    1. Ensure the first character is a valid character.
    2. Ensure 0-18 of the next characters is a valid character.
    3. Ensure the last character is a valid character.
    4. The combination of point 2.1, 2.2 & 2.3 handle scenarios of 2 up to 20 characters.

 

Test Data

kkdkd df sdf lk aj33<-- Pass
12345678901234567890<-- Pass
kjlf l-Ka034-/\_ kj0<-- Pass
adsfdsafsdaf dsfsdfa<-- Pass
dlASjd83_-/\dfdsfsda<-- Pass
adsfsdas  sdafsdafsa<-- Pass: Contains multiple spaces in a row
dsfsdf<-- Pass
2<-- Pass
11<-- Pass
111<-- Pass
- dsf<-- Pass
-df<-- Pass
/dsaf<-- Pass
\asdf<-- Pass
_asdf<-- Pass
_ sdfjlksdaflk jasdf<-- Pass

123456789012345678901<-- Fail. More than 20 characters
 asdf<-- Fail: Starts with a space
adsfsdas  sdafsdafs#<-- Fail: Ends with a #
 adsfsdafsdfsdfsadds<-- Fail: Starts with a space
dfsdafljkasdfklsdsd <-- Fail: Ends with a space
#<-- Fail: Invalid character only
 <-- Fail: Space only
2 <-- Fail: Ends with space
 2<-- Fail: Starts with a space

<-- Ignore: Blank line

 

See it in action

https://regex101.com/r/2uMivO/6

 

Tricky Bits

It took some trial and error to get this and using https://regex101.com was a huge help and time saver.

My final problem was allowing a single character, and that was whee the OR (“|”) came in, adding it to the start of the group.

webpack issue: “The CLI moved to a separate package: webpack-cli”

I’m working on a project that uses ‘webpack’. After pulling in a code update that required developers to clear out node_modules and update yarn, I started receiving the following prompt when running webpack:

The CLI moved to a separate package: webpack-cli
Would you like to install webpack-cli? (That will run yarn add -D webpack-cli) (yes/NO)

(I found running this – even manually running the yarn command – didn’t actually install the CLI and in fact, produced further errors).

Even trying to return the webpack version raised the prompt:

 

The problem, I have been told, is the version of webpack being loaded with “npm install -g webpack” was higher than the version we actually wanted and included ‘webpack-cli’ being split into a separate package. Specifically, we want to work with version 3.8.1.

You can see in the screenshots above just running “npm install -g webpack” installs version 3.8.3 (incidentally I cannot find a reference to version 3.8.3 on the NPM webpack page or webpack’s GitHub releases page).

 

The solution:

1) Delete the ‘npm’ and ‘npm-cache’ folder from your user profile Roaming AppData folder (i.e.  from the Windows “Run” prompt run %AppData%).

2) Install the specific webpack version. i.e. npm install -g webpack@8.3.1

Now you can run ‘webpack’ as expected.

Working with JavaScript dates deserialized from JSON

This is a quick post inspired by a problem I helped a colleague with yesterday.

The problem is a “date.getFullYear is not a function” error was thrown when calling getFullYear() on a TypeScript Date object.

This was happening when the Date object was populated from a deserialized JSON string and the deserialization was silently failing in the background in the app.

It happens due to the format of the date string, and on top of that, the string is in the format “dd/mm/yyyy” (the short date format used by most of the world)..
JavaScript being what it is, it doesn’t like this for dates like “18/05/2018” (18th May) because it actually wants to do a conversion on “05/18/2018” (US short date format).
More importantly, you can’t implicitly deserialize a string representation of a date to a JavaScript Date object. How does the dezerializer (in this case JSON.parase()) know the string is really a date?

How do we fix this?

There are 2 parts to the answer:

  1. We need to explicitly set the target/deserialized date variable/field to a Date()
    i.e. myObject.myDate = new Date(“date-string-in-accepted format”);
    For example: myObject.myDate = new Date(“05/18/2018”).
  2. Ensure the string we are passing into the Date() object is in an allowed format (best format is ISO: yyyy-mm-dd).
    For example:
    myObject.myDate = new Date(“2018-05-18”) – using ISO date format.
    myObject.myDate = new Date(“05/18/2018”) – using US date format.

Below you can see it a quick running code sample I whipped up to demonstrate this.

Play around with commenting.uncommenting the “json = “…”;” lines and the “let dataObject: DataObject = JSON.parse(json);” line.

Running Example

NOTE: You can pop the editor open in a new window by selecting “Edit On StackBlitz” in the bottom-left of the inserted window.
Select the folded-page icon at the top of the left column (below the StackBlizt blue/white icon) to see the list of files.

If you’re using Internet Explorer or there’s just a black window below, here’s the link to the code (and I suggest using a “modern” browser – Chrome and Edge both work): https://stackblitz.com/edit/typescript-riapny.

What is a predicate in computer/software programming?

I’m a very practical developer. My learning style has always been to learn how to do something, usually by example, now what it’s called.

As such, I know that I know how to write code with predicates, but I might still fail a multiple-choice test to describe what a predicate is.

So I looked it up again. And it’s really quite simple:

A predicate is a statement (or function) that returns either true or false.

You pass some data into the predicate. The predicate logic then performs a check on the data. Then the function/statement return a true or false result to the caller.

The 2 clearest resources with descriptions and examples I’ve found so far are this StackOverflow answer and this other StackOverflow answer (which is C# oriented).

A common example is a function or short comparison statement you write and pass into a function on a list that then performs a mapping or reduction on the list (e.g. to find a subset of items in the list that contain the value(s) your predicate function or statement is checking for).

For example, if I have a list or array of People objects and each object has an Age property, I can write a predicate …

(Person p) => (p.Age >= 18)

… that I pass into a select() function on the list to return only those people who are age 18 or older.

For example:

var australianDrinkingAgePeople = fullList.Select(Person p => p.Age >= 18);

In this case, it’s a shortcut for writing your own big for loops and if statements over the list (although there’s nothing to say that the select() statement doesn’t implement that logic behind the scenes).

SQL SERVER WHERE clause returns match when field contains trailing space

It’s nice to know you can still discover new things after 20 years in the industry.

Last week while investigating a defect of some data import work I’d done in SQL SERVER, one of my initial steps was to query the database for the imported records. For example:

SELECT * FROM [MyTable] WHERE [SomeField] = ‘SomeValue’;

That’s a standard, simple query. Nothing tricky about it.

However, what I had already discovered from inspecting the value returned to the application that uses it, is my value actually had a trailing space (i.e. ‘SomeValue ‘).

What surprised me was when I ran the query above it still returned the record.

That is: [SomeField] actually equals ‘SomeValue ‘ (with a trailing space) in the database record, yet my comparison to ‘SomeValue’ (no trailing space) still returned the record.

It turns out this is a quirk of SQL SERVER’s implementation of SQL.
It also turns out in all my years working with databases I must have been cleansing my data enough to never encounter this (in this instance I was generating SQL statements in Excel and was explicitly told not to touch import values [some of which included an incorrect trailing space]).

Check out this StackExchange question for more information.

WordPress: An embedded page at widgets.wp.com says – Request failed. Returned status of 404

Key Stats:

  • Publication Date: 06 May 2016
  • WordPress Core Version: 4.9.5–en_AU
  • JetPack Version: 6.1

My WordPress-based Knowledge Base site has started displaying an unwanted JavaScript dialogue box on post pages saying:

An embedded page at widgets.wp.com says
Request failed. Returned status of 404

 

It turns out I’m not the only one with this issue (as this WordPress Support page indicates) and the problem looks to be coming from the JetPack plug-in.

After finding a few keywords on that support and testing on my own site, it turns out the problem is being caused by the “Show Likes.” feature on the post:

 

Untick the “Show Likes.” option and save the post again and the problem goes away.

 

Now we just need to wait for a fix from JetPack (which seems a bit slow coming).

Note for developers: This type of error should never be logged in the UI via a JavaScript dialogue box. Why? It’s truly bad user experience for non-technical end users (who in the case of WordPress websites are most likely to see it). Log it to the console instead.

Views on Software Development Team Leadership & People Management

These are my views and approaches on leading software development teams and managing people in general. They come from the culmination of a few years of on-and-off leadership, and a lifetime of observation (plus a share of suffering under poor regimes along the way).


In no particular order:

  • Work for your team.
  • Protect your team.
  • Never pass problems down the line.
  • Don’t talk about money with the team. They don’t need to know if the project is running over budget. They don’t even need to know the budget. That’s a management concern, not a worker’s concern.
    (Definitely, don’t use budget issues as a motivator to make the team work more.)
  • Push back on upper management if their requests and expectations are unreasonable.
  • Give the team the tools they need to do their job.
  • Don’t be cheap on tools and equipment. Supply computers with appropriate specifications, decent chairs, multiple monitors.
  • Give the team the information they need to do their job.
  • Give the team the support they need to do their job.
  • Be patient.
  • Don’t reprimand people. Be a “guide” for team members not performing to your standards.
  • Be very clear about standards and KPIs if you’re going to hold people to them.
  • If someone is not performing to a standard you expect, talk with them, work with them, help them be better. Raise the issue and talk to them early (don’t wait until the annual performance review).
  • Leadership and management will mean tough, icky conversations. If you don’t have the stomach for that, don’t do the job. Skirting tough conversations is dangerous for the team and work outcomes.
  • Don’t set estimates when you already have a deadline in mind. Just say the deadline and work with the team to figure out how to deliver.
  • Don’t ask for estimates then hold people to it (Dr Evil style). It’s called an estimate for a reason.
  • Software estimation is hard. Really hard. Really, very hard. Always remember that.
  • Be clear about deadlines. And why the deadline was set.
  • Realise that almost every single software delivery deadline set by business is arbitrary. And will slip. And people will burn out and get angry pushing to deliver for a deadline that slips anyway.
  • Agile “story points” only work in true agile projects that don’t have time-based deadlines. Those projects are rarer than hen’s teeth.
  • If you’re going to hold a team to story point velocity, you’re doing it wrong (and everyone better be very clear from day one what the real effort of a point is).
  • You have smart, capable people in your team. Let them think and contribute.
  • Team discussion is good, healthy, and expected.
  • After the discussion, the decision at the end of the day is yours. That’s part of your responsibility.
  • Don’t dictate to people. Direct and guide.
  • Good leaders realise they have a team of smarter people or capable people, and enable the team to do good work. That’s the job of a leader – enabling.
  • Don’t allow or make people feel guilty about mistakes.
  • Understand the hurdles people face. Understand their problems. Understand the blockers.
  • Understand what’s slowing people down. It’s not about working people like slaves but making sure the natural pace is not slowed down (e.g. by inadequate equipment, poor process, lack of understanding, stress bubbling from management).
  • Don’t push people like slaves.
  • People are people, not resources. Never call a person a resource.
  • Praise goes to the team. Blame stops with leaders (never pass blame down to the team). A leader’s reward for a job well done is internal satisfaction.
  • Software developers need time to breath, take a break, and refresh during the day. And during the week. And periodically over a long, hard project.
  • Software coders should not be in front of their computer coding 8 hours per day. If they’re doing that then something is wrong.
  • Working software developers hard for long periods will lead to burn-out and discontent.
  • I don’t believe a rewards or hall-of-fame type system should exist for people who do extra work (hours) or produce extra stuff. That a) is the encouragement of overtime and, b) isolates the 90% of good people just getting their job done.
  • Don’t ask for overtime. Ever. (Unless you can absolutely guarantee a time-off-in-lieu soon after the reason for overtime has passed). Overtime just means fuck-up somewhere up the management or sales chain that software developers are going to pay for by fixing it.
  • Ask what people enjoy doing and want to do. What motivates people? What are their interests?
  • Give people training.
  • Give people support in career progression.
  • Don’t presume you know everything as a leader/manager – you don’t. Don’t presume you have all the answers – you don’t. That’s not your job.
  • Leaders don’t need to know everything. That’s why you have a team.
  • A leader’s job is to have enough knowledge and experience to ask the right questions, trust their staff, do research and make good decisions.
  • Draw the best knowledge, experience and ability out of people in the team.
  • A leader needs to be “people” person. They need good social and communication skills. They need empathy and reflection. They need patience and a thick skin.
    Managers also need at least some of this.
  • Never assume a team member has a certain level of knowledge, especially in software languages, technology and tooling. For example, don’t assume everyone has the same level of Git knowledge (I recently made that mistake and had to correct it). Keep asking questions – basic questions – to understand everyone’s knowledge and comfort levels.
  • Listen.
  • Don’t talk “at” people.
  • Don’t talk over people.
  • Don’t micromanage your team, even those who are slow or make mistakes. Micromanaging is just a band-aid. If there’s a problem, work at finding and resolving the root cause – whether it’s a change of process, education or allowing someone time to learn and practice a new way of thinking and working.
    Often a problem one person is having is a [silent] common problem across a team.
    A soldier needs to learn to shoot a rifle on their own. Different soldiers need different paths to reach proficiency. A leader’s job is to help each person on their own path, so when the time comes to use the rifle each soldier can do it on their own without a leader on their shoulder telling them what to do.
  • Keep processes simple.
    Keep simple checklists.
    Keep help easy to find.
    Think like soldiers and pilots.
  • Document. Document. Review. Document.
  • Never stop thinking about how to improve processes, information, and team conditions.
  • Never bring your ego.

Finally:

  • Don’t elevate a good senior technical person to a lead role that they’re not prepared for, wanting to do, or able to do.
    I’ve seen too many good “senior developers” with poor people skills placed in a lead role that end up hurting teams (at worst the team and project becomes toxic).
    Leave technical people in technical roles.

Recommended Software Development Tools

From years of experience and use (and a few recommendations from other people), I recommend the following tools:

IDEs/Editors

  • Visual Studio Code – Windows/Linux/Mac. It might be from
  • Atom – Windows/Linux/Max
  • Cloud9 – Browser-based IDE. The original version was better. Now owned by Amazon AWS and they’ve made a royal mess of the licensing, usage and documentation. Still good under the covers though.

GUI Git Managers

Command-line has its place but for the complicities of Git-based source control (and being a visual person), I prefer a good GUI for Git management.

File Compare and Merge

Web Proxy for Debugging

  • Telerik Fiddler – Windows (Beta for Max/Linux)
  • Charles Proxy – Windows/Mac/Linux
  • OWASP ZAP – Windows/Max/Linux (I’ve not used this, but OWASP does good work in security and have seen others recommend it)

General Development Helpers

  • JSON formatter – Great for inspecting large sets of JSON (and now XML and YAML)
  • RegEx Testers (enter a regex expression, test it, find out what it does):
  • Can I Use – The best resource to determine what CSS and JavaScript feature the major browsers support.