On occasion I get a little blue and need a little music to cheer me up, but clicking the start button and finding my media player takes sooooooo long. I want a faster way to play a song.

The challenge:

Write a program that:

  • Choose a song from my home directory (so you don’t mix-up program sound files with music) (this includes sub folders of the home directory).

  • This song should be a random choice from all the media in my home folder. This doesn't need to be a perfect random, but I don't want to hear the same song multiple times. (unless that's my only song ;)

  • To make it simple you should only look for files ending in .mp3.

  • In the event that you find no music in my home dir, you should print Sorry Joe, no Jams! to stdout or closest equivalent (btw my name isn't Joe ;)

  • The layout of my home folder will contain no infinite loops

  • You should use system to play the song instead of using built in media playing APIs in your language (i.e. I want the song to play in the default player for my system).

  • I should be able to place this file anywhere on my computer (e.g. my desktop or start folder)

  • Your answer should work on windows, multi-platform is a (un-scored) bonus

This is code golf so the shortest program in bytes wins!!

  • 2
    \$\begingroup\$ What is your home dir? \$\endgroup\$
    – Adám
    Oct 13 '15 at 13:41
  • \$\begingroup\$ It will differ from computer to computer, so you should use a builtin in your land to determine that. (e.g. in python os.path.expanduser('~')) \$\endgroup\$
    – J Atkin
    Oct 13 '15 at 13:47
  • \$\begingroup\$ Lol, I meant lang, not land \$\endgroup\$
    – J Atkin
    Oct 13 '15 at 13:54
  • 2
    \$\begingroup\$ waiting for an answer in CJam :) \$\endgroup\$ Oct 13 '15 at 14:26
  • \$\begingroup\$ May I post a theoretical answer? I haven't used Windows in years, but I think I know an answer. It won't be golfed because I don't know that I can actually test it. \$\endgroup\$ Oct 13 '15 at 15:17

PowerShell, 59 52 bytes

ii(ls -r./*.mp4|random);(,"Sorry Joe, no Jams!")[$?]

-7 byte golf improvements, thanks to Jaykul:

  • Use ii (Invoke-Item) instead of saps
  • No need to use Get- in Get-noun commandlet names, it will be searched by default.
  • No space needed after -r

Previously at 59 bytes

saps(ls -R ~/*.mp3|Get-Random);(,"Sorry Joe, no Jams!")[$?]

It will throw an error if there are no files, but it will print the message too.


  • saps is an alias for Start-Process
  • ls is an alias for Get-ChildItem
  • ~ maps to the home directory, and -R is -Recurse
  • Get-Random selects a random item from the pipeline.
  • After trying to launch it, it uses the previous command exit value as an index into a two-item array which either does nothing, or returns the apology message.
  • \$\begingroup\$ Wow that is short, very nice! \$\endgroup\$
    – J Atkin
    Oct 14 '15 at 15:10
  • 1
    \$\begingroup\$ You can shorten that to ii(ls -r./*.mp4|random);(,"Sorry Joe, no Jams!")[$?] or if you're not willing to assume PowerShell is in the home directory already (that's it's default), then add one character: ii(ls -r ~/*.mp4|random);(,"Sorry Joe, no Jams!")[$?] \$\endgroup\$
    – Jaykul
    Dec 21 '15 at 19:13
  • \$\begingroup\$ @Jaykul Thanks! I can probably take Get- out of loads of my answers now. \$\endgroup\$ Dec 21 '15 at 21:18
  • \$\begingroup\$ save one more byte by replacing ii(ls -r./*.mp4|random); with ls -r./*.mp4|random|ii; \$\endgroup\$
    – Clijsters
    Nov 15 '17 at 15:18

Dyalog APL, 78 75 73

{0::'Sorry Joe, no Jams!'⋄⎕SH⍵,{⍵⊃⍨?≢⍵}⎕SH∊'dir/b '⍵'*.mp3'}'%HOMEPATH%\'


{...} unnamed function, wherein represents whatever is to the right of the }
APL statements (separated by ) are executed leftmost first, but each statement is evaluated from right to left (no precedence rules), so each function gets whatever is to its right as argument
0:: sets a trap for all errors to return the string instead
∊'dir/b '⍵'*.mp3' makes the three strings into a single string
⎕SH passes its argument to cmd.exe
?≢⍵ random 1 ≤ integer ≤ count (or 0 < float < 1 if count is 0)
⍵⊃⍨ pick that element (floats are invalid indices, so an error is triggered here if count was 0)
⍵, prepends the home dir
⎕SH passes its argument to cmd.exe

  • \$\begingroup\$ I may be missing somthing, but where does it print "Sorry Joe, no Jams!" if no media is found? (full disclosure, I have no idea how APL works ;) \$\endgroup\$
    – J Atkin
    Oct 13 '15 at 14:26
  • \$\begingroup\$ @JAtkin Yeah, I forgot. Fixed. \$\endgroup\$
    – Adám
    Oct 13 '15 at 14:27
  • \$\begingroup\$ @JAtkin Do you wan't an explanation now, or was "I have no idea how APL works" only a joke about my mistake? \$\endgroup\$
    – Adám
    Oct 13 '15 at 14:41
  • \$\begingroup\$ No, that was for real, I have no clue how APL works. \$\endgroup\$
    – J Atkin
    Oct 13 '15 at 14:56

Python 2, 178 bytes

import glob,os,random
try:os.startfile(random.choice([y for x in os.walk(os.getenv('HOMEPATH'))for y in glob.glob(os.path.join(x[0],'*.mp3'))]))
except:print"Sorry Joe, no Jams!"

Works on Windows, as per the spec.

  • \$\begingroup\$ Nice. I can confirm this works. \$\endgroup\$
    – J Atkin
    Oct 13 '15 at 14:29
  • \$\begingroup\$ You can probably get rid of the []. Also, if you only need it to work on Windows, can't you just replace the call to os.path.join with x[0]+'\*.mp3' or something like that? It looks overly portable for golf :) \$\endgroup\$
    – Lynn
    Dec 22 '15 at 2:47

Linux shell utilities, 74

Ok, so this one's not going to work on windows, but in case you decide to use a real OS (😉), here's what you could do in Linux:

find ~ -name \*.mp3|shuf|(read l&&xdg-open "$l"||echo Sorry Joe, no Jams!)
  • \$\begingroup\$ Hey! I actually like windows 10. But I also like bash... \$\endgroup\$
    – J Atkin
    Oct 13 '15 at 17:54
  • \$\begingroup\$ I have a copy of bash and the unix utils installed on my windows 7 box. So this could work on windows if you have it set up right. \$\endgroup\$ Dec 21 '15 at 21:43
  • \$\begingroup\$ Is it possible to decompile this to Batsh? \$\endgroup\$
    – dorukayhan
    Jun 15 '16 at 18:11
  • \$\begingroup\$ @dorukayhan Probably, though I don't see what it would gain, given the dependencies on GNU find and shuf and xdg-utils xdg-open. \$\endgroup\$ Jun 15 '16 at 18:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.