Musings of a dad with too much time on his hands and not enough to do. Wait. Reverse that.

Category: technology (Page 30 of 36)

Rick Rolling with matplotlib

I know this meme is 100 Internet years old, but when I read this awesome post from Little Miss Data, I knew what I had to do:

Ok, ok.  So there are a few problems with the GIF:

  1. Rick’s head isn’t exactly centered and doesn’t pivot in a fluid way
  2. It would probably be nicer if the labels were over their respective wedges.

In Little Miss Data’s post, she uses R code to first generate her charts, then save them to PNG files, then load those PNG files as background images to pre-created, animated GIFs.  Unfortunately, I could find no way in Python to replicate that behavior.  So, I cheated a little: in a loop, I created my chart, dropped the Rickster on top of it, and saved the image to disk.  With every loop iteration, I slightly rotated Rick.  Outside of my loop, I used the imageio package to load all the saved images into one animated GIF.  Here’s a look at my code:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
data = [['Give you up', 30],
        ['Let you down', 20],
        ['Run around \nand dessert you', 20],
        ['Make you cry', 15],
        ['Say goodbye', 10],
        ['Tell a lie \nand \nhurt you', 5]]

headers = ['thing', 'percentage']

df = pd.DataFrame(data, columns=headers)

[os.remove(f) for f in glob.glob('fig_*.png')]  # remove any images from previous runs
pngs = []

for i in np.arange(0, 10):
    fig, ax = plt.subplots()
    img = plt.imread('rr2.gif')
    img_w, img_h, x = img.shape
    df.plot.pie(y='percentage', labels=df.thing, figsize=(9, 9), legend=False,
                title='Things Rick Astley would never do', ax=ax)
    ax.set_ylabel('')
    fig_w, fig_h = fig.get_size_inches()*fig.dpi
    rr = ndimage.rotate(img, i*36)
    _ = ax.figure.figimage(rr, fig_w/2 - img_w/2, fig_h/2 - img_h/2, zorder=1)
    fig.savefig('fig_{0}.png'.format(i))
    pngs.append('fig_{0}.png'.format(i))
   
images = []
for png in pngs:
    img = imread(png)
    images.append(img)
mimsave('rr_final.gif', images)

The full code is available on my Github page.

As for fixing the problems I identified earlier, I’m sure that can be done with some smarter calculations in the figimage line and the labels should be able to be adjusted through appropriate calls to the ax object, but I’ll leave that to someone with more time on his hands…or not, as this is probably a dumb thing to spend your time on.

Anyway, there you go: rick rolling the matplotlib way!

Comparing files for backup

For particular reasons I won’t go into here, when it comes to backing up family photos–photos taken by my family’s digital cameras and various phones–I try to pull all those files together periodically and back them up under one common folder on my NAS, organized in year and month sub-directories.  The process works out well for the most part but I occasionally have to deal with the problem of duplicate files–files I’ve already backed up once but weren’t removed from the device in question–or, worse, files sharing the same name but are entirely different pictures.

Compare-Object

One way to identify these problems is with PowerShell’s Compare-Object cmdlet.  Imagine this scenario: I have a folder of pictures I downloaded from one of my kids’ phones.  That folder contains pictures taken in both June and July but I only want to determine if there are any new July pictures that I need to backup.  I can run the following at the PowerShell command prompt:


1
2
3
4
PS > $backed_up_files = gci "C:\my_nas_backup\Pictures\2018\July"
PS > $files_to_be_backed_up = gci "J:\104APPLE" | ? {$_.LastWriteTime -ge "2018-07-01" -and $_.LastWriteTime -lt "2018-08-01"}
PS > $c = compare -ReferenceObject $files_to_be_backed_up -DifferenceObject $backed_up_files
PS > $c | ? {$_.SideIndicator -eq "<="}

This produces a list of files that are not presently backed up, but I have two problems with this approach:

  1. The Compare-Object cmdlet can be slow, often taking several seconds to run, particularly if you have a few thousand photos to examine and
  2. More importantly, if you have photos that share the same filename yet are completely different photos, Compare-Object doesn’t seem to be smart enough to see the difference and point this out.

Enter Robocopy, FTW

There are lots of hidden gems in Windows, not the least of which is Robust File Copy (robocopy for short).  Robocopy is a fast and clever command line tool for copying folders and files and a great solution for some of your more challenging backup needs.  Leveraging some help from this post, I constructed the following robocopy command to see what July photos still needed backing up:


1
C:\>robocopy "J:\104APPLE" "C:\my_nas_backup\Pictures\2018\July" /l /ns /ndl /njs /njh /xx /minage:20180801 /maxage:20180701 /log:rc_july.log

Lot of command line arguments there!  Here are their explanations:

  • l – List only – don’t copy (this will just list out the files robocopy would normally want to copy over)
  • ns – don’t log file sizes
  • ndl – don’t log directory names (I’m only looking at files, not directories, anyway)
  • njs – No Job Summary (trying to keep my log file trim)
  • njh – No Job Header
  • xx – eXclude eXtra files and directories; “extra” files seem to be those files already in my backup folder.  For this particular problem, I only want to know about files I’ve yet to back up.
  • minage – exclude files newer than n days/date
  • maxage – exclude files older than n days/date (I only want photos taken in July, so I need to set these values accordingly)
  • log – output status to LOG file (the results of the comparison will be written to this file)

Robocopy applies different labels to the files it examines.  In my case, it applied the “extra” label to photos already in my backup directory.  Since I’m not concerned about these, I used the “xx” argument to suppress that information.  Next, it applied the label “new” to files in the phone directory but not in the backup directory.  Those are photos I definitely need to add to the backup.  Finally, it applied the label “newer” to photos in both directories that share the same file names but are completely different photos.  Sweet!

All this and robocopy copy ran in sub-seconds.  I think this will be my go-to tool going forward when comparing photos for backup.

Don’t forget about Linux on Windows

I love articles on “Top X tools for…whatever”.  Recently, I was reading an article on essential tools for data scientists.  Tool #1: wget.  I’ve used wget in the past at work and suddenly realized I actually had a need for wget at home.  Unfortunately, wget is a tool for Linux operating systems, not Windows, the system I typically use at home.  What to do?  I’ve been using Git Bash quite a bit lately and that shell includes several Linux utilities.  Maybe it has wget?  No dice.  You can add more utilities to Git Bash, but I wonder if there’s a better solution.

Again at work I occasionally use Cygwin and was just about to download it to my home workstation when I suddenly said to myself, “Self, you silly goose!  Microsoft just released a Linux sub-system for Windows!  Why don’t you install that?”  So, that’s what I did!

Step 1: Enable the Linux Subsystem

Obviously, you’ll want to make sure you’re version of Windows 10 supports the Linux subsystem.  If it does, fire up a PowerShell command shell as Administrator.  The easiest way to do that is to right-click on your Start Menu icon on your taskbar.  A context menu will pop up with the option Windows PowerShell (Admin).  In the shell, execute this statement:


1
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

Step 2: Install the Linux “app” of your choosing

I rarely use the Windows Store, but once you enable your system to support the Linux sub-system, you’ll have to jump into the store and install the particular flavor or flavors of Linux you prefer.  Yes, that’s right: apparently you can install more than one flavor of Linux.  HowToGeek.com has a detailed article on installing the Linux app from the Windows Store that I highly recommend.  I was particularly excited to see Kali Linux as an option!

Note well: It seems like Microsoft recommends not letting Windows software interact with files you manage in you Linux sub-system.  For my immediate purposes, I simply wanted to download some web resources with wget.  I would, though, like to read that downloaded content in one of my Windows browsers, but where the heck are those files?

To find your home directory in your Linux sub-system, follow these steps:

  1. Open Windows Explorer, and drop this in the address bar: %LOCALAPPDATA%\Packages
  2. That takes you to a directory of installed packages.  Find the directory of the Linux sub-system you installed (hint: the folder should start with the name of the distribution like “KaliLinux” and the timestamp of the folder should match the date and time you installed the sub-system).
  3. Double-click into the appropriate Linux folder then navigate to LocalState\rootfs\home and look for your user.

Now, you have access to the folders and files you created in your home directory.  Again, though, treat those resources with kid gloves.

So now you have wget and a host of other cool Linux tools all on Windows!

 

« Older posts Newer posts »

© 2025 DadOverflow.com

Theme by Anders NorenUp ↑