Author Archives: James Bradbury

Sleep data analysis – conclusions

I now have 433 days worth of data about my sleep. Although some of it is a bit subjective, I think it’s good enough to give me an idea and a whole lot better than the guesswork I was using before. It seems to be enough that some noticeable correlations are forming.

In order to be sure I’m not looking at noise and that I’m focussing on the most important things which affect my sleep, I’m only going to look at the most significant factors.

The correlations are against “missed sleep” which I defined before, so negative correlations show things which are good for my sleep.

The following were good for my sleep:

AM exercise (0-5) -0.178
Total Ex 5 days -0.174
Sugar (1-5) -0.115

The following seemed to have a bad effect on my sleep, though as you can see from the numbers, not very strongly:

Evening meal finish 0.078
Excitement (1-5) 0.117
Exercise after 6pm (0-5) 0.127

The following seemed to have no significant effect either way: Daylight hours, ZMA, Evening meal size, Worry, Screen after 6pm.

For me that’s enough to encourage me to make the following lifestyle changes in the hope of better sleep. I think this will be more personalised and useful to me than generic sleep hygiene.

  • Keep exercising, but mainly in the morning
  • Not to worry about evening screen time. It might affect some people, but doesn’t seem to stop me sleeping
  • Try to eat early in the evening, but not worry about the size of the meal

How to write a great bug report

“My client has a problem with a file”

The above is the full text of an actual bug report received by a former colleague of mine.

She could’ve contacted the person who raised the report asking him to tell her “Which client?”, “Which file?”, “What kind of problem?”, “Which system were they using?” or any other number of essential pieces of information. As my colleague had a list of bug reports numbering three figures, instead she shrugged and moved on to a report with better information.

No doubt the person who raised that report was also very busy, but they only wasted their own and others’ time by raising such an unhelpful report. I think that when reports like this are commonplace it suggests that there are some misunderstandings about communication between developers and users.

Can’t the developer just ask me for more information?

Perhaps the user whose client had a problematic file was only intending his very terse report to start a conversation.

That’s natural enough. When someone visits the doctor and says, “I feel unwell” they don’t expect a diagnosis straight away, rather a series of questions from the doctor to gain an  insight into the patient’s illness. That’s fine when both parties are sitting next to each other discussing it. When they are working in different offices, maybe different time zones, then it becomes a painfully slow process. If a developer asks for more information and the user is in a meeting or asleep, they can’t simply sit around waiting for a response, they’re forced to work on something else, with the associated cost of context switching. Sometimes further questions may be needed, but the user can jump-start that process with a clear report.

Surely the developer knows what I mean?

Users may have the impression that the software engineer knows more about the software than they do.

Software engineers may spend lots of time looking at code but much less, if any, time using the software. Users are the experts at how the software works as they often use it day in and day out. Their insights about how it works and how it should work are invaluable to developers. Sadly they are often left out of bug reports on the assumption that developers already know everything that users know.

The developer must be aware of this bug already!

A bug report might be seen by some as an official way to force a developer to fix an issue that they already know about.

Again, this isn’t usually the case. If a developer discovers an issue, they’d normally raise a bug report for it, even if they didn’t have time to fix it immediately. Everyone who raises reports should also be able to search the list of bugs to see if anything similar has already been reported. If the bug isn’t listed in the database, it’s likely that no one else knows about it. If it is, then there’s no point creating a duplicate.

Raising a duplicate report only creates confusion. Instead the user should be able to update the existing bug report perhaps to say, “This is also affecting client X” or “I have observed the issue on Sundays as well as Bank Holidays.”. This extra clue may make fixing the bug easier.

What does a good bug report look like?

If you write helpful bug reports, with a few minutes of your time you could save the developers hours, if not days, of their time. You do want this fixed quickly, right? Where developers can choose what to work on next, they’ll naturally prefer quick wins. Thorough yet concise bug reports focus the developer on a solvable problem. Vague ones feel like being asked to find a needle in a field full of haystacks.

Now I’ve lectured you on why it’s important to write good bug reports, here are my suggestions of their most important features. This list is generalised. For certain projects there may be additional essential information.

  1. Search for any similar bug report
    If found, optionally add to it. Do not create a duplicate. If unsure, link to the original.
  2. A short, descriptive title
    Enough to distinguish it from similar issues. Probably 4-10 words.
  3. Include all relevant details
    e.g.: Server, product, client(s) affected, file type, time of day, web browser version. Make that haystack smaller!
  4. Steps needed to reproduce the issue
    A developer may not know how to reproduce the issue. If they can’t do that they probably can’t fix it and definitely won’t know whether they’ve fixed it.
  5. Expected result
    Make it absolutely clear what you wanted the software to do. e.g.: “Display the total number of rows the uploaded file has at the top of the page.”
  6. Actual result
    Again this ensures clarity when compared to the above. e.g.: “Null is displayed and the menu-bar disappears.”

Those are the essentials. If you have time to investigate further then any other clues you can add are a bonus. For example, insights like these may also be helpful and speed up the process of debugging.

“This only happens on days immediately following bank holidays”

“It worked on Friday 4th, but failed on Monday 7th”

“It only affects admin users”.

I hope my suggestion helps users to get bugs fixed more quickly and developers to enjoy fixing them more.

Email campaign groups and charity

While there are no doubt many worthwhile causes that I agree with promoted by groups like 38degrees, there are some that I don’t agree with or don’t think are worth supporting.

The problem is how to decide which is which.

I’m not willing to blindly trust any organisation to decide on my behalf what is worth campaigning for by giving my support after only reading a brief email. I know we’re all inclined to believe simple ideas without much skepticism* if they align with our existing beliefs and I’m wary of making quick judgements that might reflect my existing biases more than careful consideration would.

The trouble is that I often find careful consideration of a new issue utterly exhausting. It requires time and a bit of intellectual effort. The volume of emails produced by most campaign groups, Avaaz, 38 degrees or others, are impossible to keep up with for anyone with a job, family, social life and regular exercise.

For me the same argument applies to charity cold-calling. I never sign up to anything on the doorstep or street. I already have regular charity commitments and make one-off donations to sponsor friends – should I change these when a representative of another charity knocks on my door? The answer depends on questions like how efficient the charity is, what they’ve achieved recently, if they’ve been involved in any scandals and how closely they align with my values. Not something I can judge in a five-minute or even half-hour conversation.

I admit that by refusing to consider every cause or charity that asks for my support I may be missing out on something I’d consider very worthwhile. I’m not saying I’d never explore new causes or charities, but the burden of choice means I’d prefer to start with a recommendation from a friend or trusted colleague or a subject matter I already know something about.

This might all be made simpler by having some independent reviewer of charities providing open and accessible comparisons of their finances and achievements. Until it becomes a lot easier to decide my default answer will be a simple, firm “No, thanks”.

 

* – I prefer Noah Webster’s “American” spelling of skepticism.

Garmin eTrex 30 review

I’ve been using the Garmin eTrex 30 for navigation and to record my rides for four years now. I like it a lot, but I don’t think it’s the GPS for everyone. Here’s my review.

Design and appearance

Garmin eTrex 30 mounted on road bike handlebarsTo be brutally honest, the eTrex is a chunky lump to put on your handlebars. If it was writing a lonely hearts ad it might describe itself as “rugged”. The device sticks up a good 45mm from the handlebars. It’s about 100mm long and 55mm wide. It can’t even pronounce the word aerodynamic. The colour probably won’t match your bike.

The reason it is a bit plus-sized is to fit two AA batteries and a 44x35mm screen. The wider reason for the form-factor is that the eTrex 30 is not aimed at racers, time-trialists or triathletes. It’s intended for hikers, sailors and touring cyclists. It is also very popular with audaxers like me.

Around the edge are five small rubbery buttons: Menu, Up, Down, Back and Light/On-Off. These need a firm press which can take a couple of tries in winter when I sometimes wear ski gloves, but I’d prefer this to them being flimsy and getting pressed by accident.

The screen is not touch-sensitive. Instead, on the top is a 4-direction “joystick”. It can also be pushed in to select items. Selection in this way is a bit tricky and it is easy to “miss” when trying to push the stick in and ending up pushing it up or down or doing nothing. I find this the same whether I’m wearing gloves or not. However, I’m seldom in a rush when using this button and I only tend to need it two or three times a day. I find that as long as I’m patient and pay attention to where I’m going the button does the job nicely. If my smartphone had an interface like this I’d hate it, but it doesn’t bother me on the GPS.

Features and function

The etrex 30 can be used for a lot of other activities like hiking, sailing, etc. It has a load of features I’ve never used, like a “Man Overboard” button. I can’t tell you about those features, as I’ve only ever used it for cycling.

eTrex front with joystick and screen showing time, Trip odometer, elevation, speed, etc.

My “data” screen

I followed some very thorough etrex 20/30 setup advice and went for a simple system of two screens, one for a the map, one for the numbers – time, distance, average speed, battery level, etc. You can choose which fields you want and have them in various layouts. I switch between the two screens using the back button which is quick and easy.

The main thing I use this for is guessing when I might arrive at the next control. If my average speed has dropped but my elevation is high, then I can expect to gain some speed when I descend. Arguably maximum speed is more for entertainment than anything else. Total ascent can be useful when Everesting or chasing AAA points.

I also put two boxes like these at the top of my map screen – Overall Ave. and Distance. You can have four boxes, but it starts to obscure the map a bit. With the help of the up and down buttons on the top left edge of the device (see image above) the map can be zoomed in or out much further than you’re likely to want. I use 120m scale for towns and 200/300m for countryside. If you get lost you can also scroll across the map using the joystick, but this is a bit clumsy and slow to update.

You can buy or find additional online maps, but I found those that are built-in to be fine for the UK.

When I’ve planned a long ride I usually copy a GPX file onto the device so I have something to follow for navigation. You can use the “Follow route” feature which provides a thick pink line as well as some peak and valley icons which don’t seem very accurate to me. For simplicity I prefer to simply “Show on map” and select a colour that I find easy to see. I prefer dark blue or red (see below).

I don’t get any warnings or beeps if I go off-route, but with an audax routesheet alongside I find navigation pretty easy.

eTrex screen showing red route not quite following every bend of the road

When trackpoints are reduced, the route shortcuts some of the curves of the road. This shot shows the pointer mode rather than my info boxes.

However, this is where you have to be a bit careful on longer rides. There is a track point limit and if you go over it, the end of the route will be cut short. I discovered this halfway through a 300km ride to my alarm. Thankfully I also had a routesheet. I’m not sure exactly what the maximum number of track points is, but it’s definitely less than 6500 and more than 4600. I’ve since learnt several ways to get around this and I always use the “View map” option on the GPS to check my routes are about the right length after I’ve copied them across. If I use a tool to reduce the number of track points the route often ends up slightly shorter  – say 98.6km instead of 100km due to the way the reduced route takes shortcuts across the bends in a road (see image). So I aim to reduce to 4500 track points to get the smoothest track without risking the eTrex cutting off the end. For routes longer than 200km I’d prefer to split the route into several sections.

Like most GPSs the eTrex 30 records the track you travel on for Strava or other ride-recording tools. What I found different to the Edge 500 was that once it’s set up the eTrex records all the time – no need to press start. You can save your track to another file or clear the current track, but it will keep recording. If you turn the device off or even change the batteries it will continue recording when you turn it back on. If you’ve moved while it was off it draws a straight line between the points. What this means is that you need to remember to clear the current track before you start a new ride. That way it doesn’t include your car/train/plane journey!

Note: If you’re concerned that your total ascent figure is as accurate (and large!) as possible when uploading from an eTrex to Strava, I’ve made some scripts to fix the way the altimeter data is read.

Other features

  • Takes 2xAA batteries which are available anyhere. Rechargeables work fine.
  • Good battery life – I’ve had Eneloops last well over 24 hours.
  • Can be powered (but not charged) via USB.
  • Mini-USB data connector.
  • Can display HR and cadence if attached via ANT, but doesn’t record them for Strava, etc.
  • Secure bike mount available and lanyard attachment point.
  • Reliable – never had a crash or loss of data in four years.

Conclusions

I previously used a Garmin Edge 500. The Edge 500’s navigation was very basic, consisting only of a wiggly line, no map and a buzz when you’re off course… or the GPS signal has failed. But most annoyingly the Edge 500 has a non-removable Lithium Ion battery that I could never get more than 12 hours out of. While charging on the go is theoretically possible with the right kind of cable, I always found that this reset my route. As I understand it, most of the Edge series (apart from the Edge Touring) is designed for training rides where you might want to record HR, cadence, power, etc, but not ideal for audax/touring.

When all I want is to record my ride and it’s less than an hour long, my phone is simpler. But on longer rides I like to conserve my phone’s battery in case of emergencies. I haven’t tried every GPS out there, but in spite of the user interface quirks already mentioned, I’m very happy with the eTrex 30 for touring and audax.

This is not a tour 400A photos

Why I’m riding “This is not a tour”

This weekend I’m riding the 400km on and off-road audax in the style and memory of Mike Hall. My motivation for this ride is similar to the reason I ride audaxes in general, but with the added variety of off-road sections. I’m interested in the question, “How much harder will that be?”. I met Mike only briefly, but I think this kind of event is what he would have wanted to inspire.

Long distance cycling is something I’ve got into over the past five years. Whenever I’ve mentioned one of my rides to friends I get bewildered responses ranging from admiration to horror. A lot of people ask if I’m doing it for charity.

“No” I say, “I’m doing it for… fun?”.

Yes, fun. I enjoy planning the route, deciding what clothing, lights and bike maintenance kit I should take. I enjoy the challenge of not knowing whether I can finish within the time limits. I enjoy the peace and solitude exploring deserted country lanes. I enjoy chatting with other riders. Sometimes I’m winding my way up a hill, sometimes I’m concentrating on a tricky descent. Sometimes I’m ambling along, sometimes I’m pushing to go as fast as I can. I enjoy the freedom of roaming and of self-sufficiency. I enjoy getting away from it all, relaxed but focused on the ride.

I’m not claiming that every journey is smooth and full of picture-postcard scenery. Things go wrong. Punctures happen, wrong turns happen, lights fail. Headwinds, achy legs and cold temperatures conspire against an easy ride. On most rides I’ll have a “low point” when I’m fed up, uncomfortable or hungry. Getting through that and whatever other challenges the ride may throw at me is part of the challenge and the reason I feel elated if I finish.

And I don’t always finish in time. If I always succeeded I’d wonder if I was limiting myself to easy challenges. Failure is a good way to learn, even though it hurts at the time.

I’m sure most of my bewildered friends take on similar challenges. Things which take unusual mental or physical effort, which take us away from the humdrum of everyday life. Things where success is not guaranteed, where temporary discomfort is tolerated to reach a goal. Everyone’s challenges are different, but we all need to be challenged.

Can you relate to that?

Commuting to Bristol in photos

I’ve spent a few years infrequently commuting to Bristol through the year. I’ve now left that job, so thought it would be interesting to share the photos taken on my usual routes.

Audax training plan

I’ve got some longer audaxes planned this year, so I thought I should actually have a training plan for once. I’ve avoided stating exactly what ride I’ll do on what day as I know life is likely to get in the way, but I still have some targets which I think are reasonable. Perhaps publishing it here will keep me honest!

Jan – Feb

  • 1 x interval session (outside or turbo) 30-60 mins per month.
  • 1 x 50km+ ride per week (could turbo)
  • 2 x 100km+ ride with 1000m+ climbing per month (could count as two of the 50km)
  • 400km and 5000m total per month

 

Mar – Apr

  • 2 x interval sessions (outside or turbo) 30-60 mins per month.
  • 1 x 50km+ rides per week (could turbo)
  • 2 x 100km+ ride (could count as one of the 50km)
  • 1 x 200km+ ride with 2500m+ climbing per month (could count as one of the 50km)
  • 600km and 7500m total per month

 

May – July

  • 2 x interval sessions (outside or turbo) 30-60 mins per month.
  • 1 x 100km+ rides per week (could turbo)
  • 2 x 200km+ rides with 2500m+ climbing per month (could count as the 100km)
  • 1 x 300km+ ride with 4000m+ climbing per month (could count as one of the 200km)
  • 900km and 12000m total per month.

UPDATE 10th August 2018

Now that I’ve completed the two big rides – 400km and 1000km, I thought I’d mention what I would change about this plan.

The first thing is that a lot of longer rides probably aren’t needed. As it turned out life got in the way and it was near-impossible to fit in all the long rides I had planned. It’s subjective, but I don’t feel like a 200km ride gives much more training benefit than a hilly 100km ride, especially if you do at least half of the 100km before having breakfast. 200km+ rides are really disruptive as I needed to take a day away from family at the weekend, or book a whole day off work. 100km can be done in half a day and if you start early, being back by lunchtime is possible. I do think it’s worth doing at least one 200km+ ride in a longer training period, just to get familiar with the effects of fatigue on speed and rest times, but I don’t see any real training benefit.

Secondly, I think interval sessions are great. I really felt like I got a lot of benefit from them in a short space of time and this was confirmed by my sleep monitor in terms of a lowering resting HR and physical recovery. So next time I’d do more of that.

The monthly distance and climbing targets were worth having as they did get me out on the bike regularly, though I might reduce them a bit next time.

Sleep: What am I trying to measure?

My last post about analysing my sleep data had plenty of caveats, but despite my caution I started to wonder whether I was taking an interest in the right variables.

I’m aiming to sleep better for health and to feel more alert during the day. My first thought was to find out what influences how many hours I sleep each night. This was a guesstimate of my hours of sleep based on roughly when I fell asleep and woke up, minus any trips to the bathroom or time spent starting at the ceiling in frustration. Then I’d compare this to various lifestyle measures like how much I’d eaten, exercise, screen time, etc to see what, if anything correlated with a long sleep. Despite buying a gadget to help measure it, I’m not sure I have a more accurate measure of sleep quality, so approximate time asleep is what I tried.

However, I’ve realised that there are several ways in which “Hours that night” as I call it might not be the most useful measure. For example, there are times when I can’t get a full night’s sleep no matter how well prepared my body is for it. Sometimes I have to get up early for work, to go on holiday or because I have an audax that starts at 6am. Occasionally my daughter is ill and will wake me up several times. These things are thankfully rare, but could skew the results. I could simply delete any results where my maximum possible sleep was less than six hours, but this leaves less extreme cases.

I also recorded the maximum possible hours I could get each night. In my spreadsheet I subtracted the “Hours that night” from this to get “Missed sleep”, thinking that would be a better measure. On the other hand, if I can only get three hours maximum and I miss none, is that really better than having a Saturday lie-in for up to nine hours, but only sleeping for eight, meaning missed sleep is one hour? Who knows how many hours I might have got if I’d tried to sleep for more than three hours?

So I tried working out some kind of scaling adjustment, so that “missing” one hour out of a possible nine gives a better score than missing one hour out of a possible seven. I could ignore anything over eight hours as most people are unlikely to sleep that long unless they’ve missed out on sleep the night before. But that makes a hard cut-off, which feels wrong.

So I’ve come up with a simple scaling algorithm which looks like this:-

def missed_sleep_scaled(row):
    useful_max = min(target_sleep, row['Max possible (hrs)'])
    if useful_max == float(0):
        # result is invalid.
        return -1
    max_expected_hours = min(target_sleep, row['Max possible (hrs)'])
    useful_missed_sleep = max_expected_hours - min(row['Hours that night'], target_sleep)
    if useful_missed_sleep <= hours_noise_threshold:
        useful_missed_reduced_noise = float(0)
    else:
        useful_missed_reduced_noise = useful_missed_sleep
    return float(10) * useful_missed_reduced_noise / useful_max

This “sleep score” correlates less strongly with “Max possible (hrs)” than “missed sleep” did (0.104 vs 0.198). That seems like a step in the right direction. I’m uncertain about whether I should tweak it until it doesn’t correlate with “Max possible (hrs)” at all.

Some sleep correlation data

You may have read my previous post that I’m trying to use data to work out why I’m sometimes not sleeping well and how I might sleep better. I’ve been doing that now for some 86 days and I’m excited enough to look at the data and see if anything interesting has shown up. Ideally I’d like a year’s worth of data to get reliable results, but I’m impatient.

You may be wondering why the title of today’s post is so undramatic, prosaic even. Well, I’m rather a newbie when it comes to data science and I don’t want to leap to conclusions from the first thing I try. As you’ll see from my GitHub project, all I’ve done so far is to read in the data and use Python Pandas to produce the correlation results. I then pasted this into a spreadsheet, sorted and highlighted some rows.

I used to think that correlation implied causation. Then I took a stats class. Now I don't. Sounds like the class helped. Well, maybe.

I’m also wary that correlation does not imply causation. But it does make for an interesting start.

With those caveats out of the way, this is what I’ve got so far.

Screenshot of spreadsheet showing potential influences on the "hours that night" variable.

Plain correlation from the first 86 days of data

The factor I’m hoping to maximise is “Hours that night” – how many hours I sleep on a night after all those potential influences have been measured. So I’m interested in things which might be positive or negative influences on that.

The top two I’ve put in grey, as I think they’re not very interesting, except to show that the correlation function seems to be working as expected.

  • “Max possible” is low when I have to get up very early, say to travel somewhere, so it’s always going to limit my sleep.
  • “Av hrs past 5 days” is a rolling average of “Hours that night” over the last 5 days. That I’m more likely to sleep if I’ve built up a huge sleep debt recently is unsurprising, but also confirms that the model seems reliable.
  • ZMA and FOS are two supplements I’ve been taking recently which are said to help with sleep, the ZMA particularly for those doing a lot of exercise. Evidence is limited and I’m not keen on trying every eccentric treatment “because you never know”, but they’re cheap and the side-effects are trivial. However, I’ve only been taking these for a couple of weeks, so I don’t think there’s enough data to say if they have helped me.

Eating

If I had guessed I would’ve expected “Evening meal finish” – the time at which I finish dinner to have had the greatest negative effect on my sleep as I often wake early feeling boated if I’ve eaten late. It does seem to be a negative factor, along with “Evening meal size (0-5)”. I’ll aim to eat earlier and keep recording results.

Alcohol

This wasn’t a significant factor for me. This is supposed to make you fall asleep later but wake up too early, losing sleep overall. Anecdotally, I have found to be true for me. However, I drink quite rarely and haven’t had more than four units a day in any of the last 86 days, so my stats so far may not say much about that.

Daylight, Sugar, Screen time, Fasting

I’m recording these as they’ve either been blamed for bad sleep or hailed as a helpful thing. They don’t seem to be a big deal for me. I may consider stopping recording them so I have more time/space for other data.

Worry, Excitement

It interesting that these have some negative effect on my sleep, but as they’re all day values, there’s probably not a huge amount I can do to control them.

Exercise

I am surprised and, if I’m honest, disappointed to see “Exercise (1-5)” as such an apparently bad influence on my sleep. Studies have suggested that exercise should have a positive effect on sleep, but that may depend on intensity.

For me, and exercise score of 1 indicates a day where I didn’t walk for more than 15 mins and did no other exercise, 2 a normal day where I cycle to/from the station, about ten minutes each way, 3 is a bike ride of up to 3 hours or a 20-min weights/callisthenics session, 4 is a 3-6 hour bike ride, 5 is reserved for the all-day and sometimes all-night rides I occasionally do.

Perhaps this isn’t enough data on what, for me, may be an important question. Questions I’d like to answer might include.

  • Is morning exercise better or worse for sleep than evening exercise?
  • Is moderate exercise better for sleep than either extreme?
  • Does taking ZMA (or something else) mitigate the apparently negative effects of exercise on sleep?

Finally, instead of simply “Hours that night” should I be measuring the sleep I got as a fraction of the “Max possible” sleep? That might account for strange circumstances where I was still cycling at 1am and inevitably scored a 5 for “Exercise”.

Conclusions

I shouldn’t be drawing any firm conclusions yet, I think. 86 days is not that much data and there are many confounding factors that could be influencing things. I have a lot of thinking, learning and tweaking to do.

I plan to keep recording the data, expand my exercise data to include AM/PM and separate short intense efforts from longer endurance ones.