3D Printing with Ninjaflex on a Mendel90

Today, for the first time I tried printing with Ninjaflex. Having not printed with it before, I was a little concerned that it might prove a touch difficult. It really didn’t, but I did learn that most people set their printers to run a lot hotter and faster than I do.

Printer: Mendel90
Filament: 3mm Ninjaflex in blue

Before I started I did a bit of reading around the subject:

Based on the advice in those articles (and a test print at 195°C which failed to extrude properly) I tried the following settings:

  • Print speed: 30mm/s
  • Printing temperature: 210°C
  • Bed temperature: 50°C
  • Retraction:
    • Minimum travel: 1mm
    • Z hop when extracting: 0.1mm

If you would like the full profile I used it’s here: https://raw.githubusercontent.com/HACManchester/cura-settings/master/ninjaflex.ini

I coated the bed in dilute PVA just as I would if I were using PLA in the printer although it appears you can also get good results using blue printers tape or possibly even nothing on the bed.

2016-08-18 14.52.57

The final print is a bit bobbly in places but has generally come out pretty well:

2016-08-18 15.53.59 2016-08-18 15.54.11

JQuery snippet: automatic highlights

Sometimes you want to highlight a word automagically without having to go through and manually add <span> tags all over the place. Of course you also want to do this without breaking anything else that has been wrapped in a <p> tag. Ahem, WordPress I’m looking at you.

The first line of this iterates over every single <p> tag on the page.

The if statement then checks to see whether or not the paragraph in question actually contains the phrase and if it does replaces the sections of it that contain the phrase with the alternative text.

NOTE: if you don’t nest the actual replace within a $(this).html(); call what you end up with is just the text being returned and any child elements (e.g. p or img elements being removed from the DOM. This might not bother you if you’re working with a site only you are ever likely to update because you will be aware of the issues, however, if you’re working with clients you probably want to make sure nothing unexpected is going to happen.

(function($) {
  $('p').each(function() {
    var search_this = $(this).text();
    if (search_this.indexOf('Highlight phrase') >= 0) {
      $(this).html($(this).html().replace(/Highlight phrase/g, "<span>Highlight </span> phrase"));
    }
  });
})(jQuery);

Obviously this wont highlight any instances of the word “highlight” that have been incorrectly spelled but that, is a different problem.

WordPress Basics: get recent featured images by category

Sometimes you want to have an image slider which not only contains the most recent images on your site but does so by category to ensure that all of the categories on your site are included:

First get the categories:

$categories=get_categories();

By default this returns the categories in alphabetical order and ignores any empty ones. That’s fine by me so I’m not going to fiddle with it.

Now we’ve got our categories we need to loop over them. Don’t forget to close your foreach!

 foreach ($categories as $category) :
    # code here
endforeach; 

Inside that foreach loop we’re going to run a new WP_Query(), first though we need to set up our args:

$args = array(
            'cat' => $category->term_id,
            'post_type' => 'post',
            'posts_per_page' => '5'
          );

This pulls out the first 5 posts in each category. Once we’ve done that we can run our WP_Query().

$images_query = new WP_Query( $args );

if ( $images_query->have_posts() ): ?>
    <?php while ( $images_query->have_posts() ) : $images_query->the_post();
        if ( has_post_thumbnail() ) :
            the_post_thumbnail('post-thumbnail', array("class" => "slider_image"));
endif; endwhile; endif;?>

Excluding a category

In this example I don’t want to pull out featured images associated posts in the category 'Blog' so I added

&& $category->cat_name != 'Blog'

to the if statement inside my query.

Argh! I have posts in more than one category and the images are duplicating

To get rid of duplicate posts add the following on the line above your call to get_categories:

$do_not_duplicate = array()

Then, under $images_query->the_post(); add

$do_not_duplicate[] = $post->ID;

Now, that we have an array containing the ID’s of the posts that have already been pulled we can add a line to our $args to make the query check it:

$post__not_in => $do_not_duplicate

Voila, no more duplicate images.

Flask basics: lose the favicon 404

If the fact that the Flask development server cant find your favicon annoys you shove your favicon into your static folder and do this:

@app.route("/favicon.ico")
def favicon():
    return(url_for('static',filename='favicon.ico')

NOTE: this is one of several ways of getting rid of that particular error and is the one I’m using today. I’ll add more as I use them.

Running a Flask App on a Raspberry Pi in kiosk mode

Got a Flask app you want to run on a Raspberry Pi in kiosk mode? Here’s how.

Setup

Set up your Raspberry Pi to work in kiosk mode – I usually set it to go to Google or the BBC News, something I know is unlikely to fall over while I’m testing.

Once you know it is working rename .xsession to xsession so that it doesn’t run automatically. This allows you to boot your pi normally and check that your app is working before you setup all the auto-booting magic.

Transfer your Flask App on to your pi. Personally I favour packaging apps as a tarball (using setuptools) and pip installing later but you don’t have to. The simplest way to get the files from your computer to your pi is probably via sftp, just set up as a normal connection using the ip of the pi and shunt files as usual. I’ve tried a variety of ftp clients and recommend Transmit (Mac), however if you’d prefer an open source alternative Cyberduck (Windows/Mac) is also very good.

Virtualenv and flask app installation

While Virtualenv isn’t strictly necessary it’s still good practice so lets grab that and set up a venv for our app

  1. Install Virtualenv using either sudo apt-get install virtualenv or pip install virtualenv.
  2. Jump into your project folder cd my/project/folder and create a Virtualenv:
    virtualenv -p python3 venv

    If you want a python2.* environment then you can miss out the -p python3.

  3. Activate your Virtualenv:
    cd venv
    source /bin/activate
  4. Install your Flask app either using pip install your_flask_app or by installing it and it’s dependencies.NOTE: If you’re using bcrypt you will first need to sudo apt-get install python3-dev otherwise it will fail.

Start your app to make sure everything’s working.

Auto-start Virtualenv and Flask

There are a variety of ways to do this: chron (Running A Python Script At Boot Using Cron), daemons (see Getting a Python script to run in the background (as a service) on boot and http://raspberrypi.stackexchange.com/questions/12580/run-python-flask-server-from-daemon), rc.local.

Partly because cron was failing me (and I couldn’t work out why) I went with the second simplest solution which was adding the following to my rc.local before exit 0:

. home/pi/PATH_TO_VENV]/bin/activate
python home/pi/PATH_TO_FILE_THAT_STARTS_APP.py

Reboot your pi and navigate to http://127.0.0.1:5000/ to check that everything works (or just skip this step if you’re super confident).

Auto-start Chromium in Kiosk mode

Put your .xsession file back: mv xsession .xsession

Then edit it so it’s hitting http://127.0.0.1:5000/ rather than whichever random site you told it to go to before.

Reboot one more time just to prove to yourself that everything is absolutely working. Do a dance1 and go make yourself a $beverage – mines a black coffee, ta :).

Raspberry Pi Kiosk Mode using Raspbian Lite

Download the latest Rasbian Lite from the Raspberry Pi Foundation (at time of writing we’re on Jessie) and unpack it so you’ve got a .img file.

Setting up the SD card

NOTE: The following section is a truncated version of the Mac instructions from the Raspberry Pi Foundation. Instructions for other operating systems (or further details for Mac users if the below fails) are available here: https://www.raspberrypi.org/documentation/installation/installing-images/README.md.

  • Open a terminal window and run:
    diskutil list
  • From the list identify the disk (not partition) of your SD card in this instance it is disk4:Screen Shot 2016-07-05 at 14.41.44
  • Unmount the SD card
    diskutil unmountDisk /dev/disk<NUMBER>
  • Copy the data to the card
    sudo dd bs=1m if=route/to/disk/image.img of=/dev/rdisk<NUMBER>
  • Wait. There will be no on screen info during this time.
  • Run:
    sudo diskutil eject /dev/rdisk

    then remove the disk from your computer and plug it into your Pi.

Setting up the Pi

WiFi

Setup your network by editing wpa_supplicant.conf to include your network data (instructions via The Pi Hut). Open the file using Nano:

sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

Then add the following to the bottom of it:

network={
         ssid="YOUR_SSID"
         psk="YOUR_PASSWORD"
}

Then save (ctrl+o) and exit (ctrl+x). Run sudo reboot to connect to your network.

Code editor

If like me, you have a preference as to text editor you will want to install that next:

sudo apt-get install vim

Check everything’s up-to-date

Even though you only just downloaded the disk image you will want to run the following:

sudo apt-get update && sudo apt-get -y upgrade

Install the stuff you need in order to have a GUI

sudo apt-get install --no-install-recommends xserver-xorg xinit xserver-xorg-video-fbdev lxde lxde-common lightdm
  • --no-install-recommends stops it installing ALL THE THINGS which it will otherwise do
  • x gives you a screen session
  • lxde gives you the UI
  • light dm is the login manager

Do some configuration

Type raspi-config into the command line and do the following:

  1. Expand the file system
  2. Disable overscan from the advanced menu. This helps ensure the display fills the entire screen rather than leaving black bars down the sides.

Install Chromium

This should be simple… but really isn’t. Fortunately this blog post explains how to do it.

These links take you to the latest libcrypt11Chromium and Chromium codecs. Once you have the correct links you need to wget them onto the Pi then install. (It’s simplest to run headless when doing this because copy/paste).

wget http://launchpadlibrarian.net/237755896/libgcrypt11_1.5.3-2ubuntu4.3_armhf.deb
wget http://launchpadlibrarian.net/263322752/chromium-browser_51.0.2704.79-0ubuntu0.14.04.1.1121_armhf.deb
wget http://launchpadlibrarian.net/263322754/chromium-codecs-ffmpeg-extra_51.0.2704.79-0ubuntu0.14.04.1.1121_armhf.deb

sudo dpkg -i libgcrypt11_1.5.3-2ubuntu4.3_armhf.deb
sudo dpkg -i chromium-browser_51.0.2704.79-0ubuntu0.14.04.1.1121_armhf.deb
sudo dpkg -i chromium-codecs-ffmpeg-extra_51.0.2704.79-0ubuntu0.14.04.1.1121_armhf.deb

You may need to run sudo apt-get -f install after you’ve done this to install the dependencies.

Unclutter

Install unclutter to hide the curser:

sudo apt-get install unclutter

Auto-login

sudo vim /etc/lightdm/lightdm.conf

Then uncomment and amend the following lines so that the match the below:

autologin-user=pi
autologin-user-timeout=0

Setup your .xsession script

If you don't have a .xsession file in /home/pi/ then create one and add the following to it:

# Dont want screensavers or screen blanking
xset s off &
xset -dpms &
xset s noblank &

# Hide the mouse cursor
[ ! -x "`which unclutter 2>/dev/null`" ] || unclutter -idle 10 -noevents &

# Sit and wait until you can hit the URL you'll be showing in the kiosk
while ! curl http://urlofthepageyouwanttoload.co.uk 2>/dev/null | grep -q "String that's on the page you want to load";
    do sleep 1
done

# Sit for 3 seconds
sleep 3

# Open chrome in incognito mode + kiosk mode
/usr/bin/chromium-browser --incognito --kiosk http://urlofthepageyouwanttoload.co.uk

Make sure everything works

Run sudo reboot. If the chromium browser doesn't fill the whole screen you may need to edit .config/chromium/Default/Preferences

It's an awful file to navigate visually and the code is in one very long string, I've put it on separate lines here to make it more readable.

"window_placement":{
    "bottom":1050,
    "docked":false,
    "left":0,
    "maximized":false,
    "right":1680,
    "top":0,
    "work_area_bottom":1050,
    "work_area_left":0,
    "work_area_right":1680,
    "work_area_top":0}},

You need to change the values for "bottom" and "right" to the maximum dimensions of your screen and ensure that "top" and "left" are 0.

Things I read in order to make this happen (that aren't explicitly mentioned above)

Thanks guys 🙂

Jessie on Raspberry PI 2 with Docker and Chromium

Kiosk Display on Raspbian Jessie

Inkscape – where have all the triangles gone?

Triangles are one of those things that seem like they should be a fundamental part of any vector graphics program but sometimes don’t appear in the menu. Like Adobe Illustrator, Inkscape classes triangles as polygons. So, to make a triangle you first select the star/polygon tool:

Screen Shot 2016-05-03 at 20.34.48

When you click on it you’ll get a new menu at the top, you want the following settings:

Screen Shot 2016-05-03 at 20.43.46

It actually doesn’t matter with a three sided shape whether you select star or polygon as your starting point, however, if you use star you’ll need to set the spoke ratio to 0.5 otherwise you’ll get additional unexpected corners in your shape.

You don’t want any rounding for a true triangle so set rounded to 0.

If you want an equilateral triangle then set “Randomized” to zero.

Pull out your triangle (holding down the ctrl key if you wish to align it horizontally/vertically).

Making the triangle have precise dimensions

Once you’ve drawn your triangle click on the Select tool:

Screen Shot 2016-05-03 at 20.34.48-1

This will change the handles on your triangle from this:

Screen Shot 2016-05-03 at 20.54.21

to this:

And will allow you to manipulate the width and height of the shape using the menu bar at the top:

Screen Shot 2016-05-03 at 21.03.20

If the lock is closed then changing either the width (W) or the height (H) will also change the other property. If it’s open they can be changed independently. Click the lock to toggle between the two.

If you click in either the width or height box you can type the dimension you wish the shape to have in, or you can use the up and down arrows on the right hand side to change the dimension by 0.1 of a unit (clicking in the box and using the up/down arrow keys will also change the value by a 0.1 of a unit).

The units ( cm / mm / px / % / &c ) can be changed by clicking on the dropdown to the right of the width/height boxes.

Flask basics: dynamically adding form elements

Sometimes you want to dynamically add elements to forms if certain information pre-exists. In this instance I wanted to add an option change the information displayed but I didn’t want the form fields to be there all the time and it was neater to simply not render them than remove them using JavaScript.

First, I was checking to see if there was more than one “narrative” in the database, and if there is I want to give the user the option of jumping between them, if there isn’t then they don’t need the extra fields and having them could cause confusion and result in the user attempting to input data which will cause errors.

A bit of searching revealed that dynamic form field generation is not only really simple to do, it’s a common enough request that its made it into the docs. However I’m putting it here because neither the docs, nor the in depth mailing list post included a fully worked example, and frankly writing it down means I stand a better chance of remembering what I did.

This form is actually a hybrid static/dynamic form. The static elements are defined in my forms file as UploadForm so I need to pass forms.UploadForm to my instantiated form.

from wtforms import StringField, RadioField

def admin(): class OptionalFields(forms.UploadForm): pass

Since I only want to render my new form fields if a certain criteria is met I wrap them in an if statement. Inside that statement I create a static field, and and unknown quantity of dynamically created ones. The static field is there because the existence of multiple “narratives” doesn’t necessarily mean that the user will want to jump between them at this point.

    if len(check_for_things) > 1:
        OptionalFields.pick_narrative =
                       RadioField(label="Swap?",
                                  choices=[("True", "Yes"),
                                           ("False", "No")])
        for thing in check_for_things:
            setattr(OptionalFields, thing,
                    StringField(thing.title()))

Once I’ve done that I need to change my form instance to the one I’ve just created. As I’ve been using form=forms.FormImUsing it’s just a case of changing forms.FormImUsing to OptionalFields

So, that displays the data, now I need to get at it. Because these fields are dynamically generated attempting to access them via form.fieldname.data results in an error and it’s equally not possible to pass a variable to fieldname.

Fortunately however it is possible to iterate over form.data.items() and pull out just the items you’re looking for.

    for fieldname, data in form.data.items():
        if fieldname == 'pick_narrative':
            # do whatever you'd normally do with the data
        if fieldname in check_for_things:
            # do whatever you'd normally do with the data

Putting it back: how to output the variable data to the form so the user can see it

Sometimes, you want to output previously input data to a form so that the user can edit it. It’s pretty easy to do this with wtforms, you just pass the form it’s data as an obj:

edit_this = models.Narrative.get(models.narrative.unique_data == unique_data)
form = OptionalFields(obj=edit_this)

It’s even easy enough to pass a bit of data that uses a different name to your form so say you use site in your database and website in your form you just do this:

form = OptionalFields(obj=edit_this, website = edit_this.site)

However, it suddenly starts looking a lot more complicated when you don’t know the field names, this is where dictionaries and kwargs come in handy. While you’re looping over the things you’re checking you might as well create a dictionary of the ‘thing’ against its ‘value’. Then you just unpack the dictionary as part of the function call:

    if len(check_for_things) > 1:
        OptionalFields.pick_narrative =
                       RadioField(label="Swap?",
                                  choices=[("True", "Yes"),
                                           ("False", "No")])
        thread_dict = {}
        for thing in check_for_things:
            setattr(OptionalFields, thing,
                    StringField(thing.title()))

            if thing_to_be_output == check_against_this:
                 thread_dict[thing] = value

        form = OptionalFields(obj=edit_this, **thread_dict)

And now, magically you have the current values visible in your form, even though you didn’t know what the form fields would be called in advance.

WordPress hacking: display only future posts

I recently inherited a WordPress site which uses a future posts plugin to allow you to publish posts with dates in the future. This is great and a very simple solution for sites that list events but don’t need complex calendar functionality. However, it had no way of automatically removing events listings which were now in the past and was showing a list of two year old events on the day I inherited it. I’m a coder, therefore lazy, there’s no way I’m removing posts manually, there’s far too much chance of me messing up and forgetting to remove one at the right moment.

The quick and dirty simple and recommended solution to displaying future posts, or posts in any specified date range, is to set up a new WP_Query() (via the recommended get_posts() route) using the date or relative date (e.g. today or 30 days ago) you want to start from as one of the $args something like this:

$args = array(
              'order' => 'ASC',
              'date_query' => array(
                                    'after' => '-1 days'
              ));
$i=0;
$posts = get_posts($args);
if ($posts) : foreach ($posts as $post) : setup_postdata($post);
    // code to display the post

This will display the event up-to and including the date that it’s on, then it will magically disappear. Neat huh?

Rainbow text using css

I fancied making some rainbow text for a project I’m working on, and in order to maintain accessibility, I wanted to do it using css. It turns out that that isn’t actually too difficult. All you need to do is:

  • generate a linear-gradient
  • clip it to the text
  • change the text colour to transparent
  • set display to inline-block so that the length of the gradient matches the length of the text

Rainbow text with soft colour changes

&amp;lt;h1&amp;gt; {
  background: linear-gradient(to right, red 0%, orange 22%, yellow 36%, green 50%, blue 64%, indigo 78%, violet 100%);
  background-clip: text;
  color: transparent;
  display: inline-block;
}

This produces a nice gradient that eases between the colours. It was a bit of a faff working out where the centres of the various colours should be (probably because I’m trying to do this with a bad cold). The centres for Red and Violet need to be at 0 and 100% respectively which means each takes up half the total space of the rest of the colours (basically there’s 7 colours but you need to treat it like 6). Once I got the proportions right, it looks pretty good.

example of rainbow text using centre stops

I found quite a lot of the css rainbow examples looked a bit muddy so I took some time trying various different ways of setting up my gradient and found that defining the actual colours you’d see in a rainbow as the centre points (or for the child’s rainbow below as the whole block) works best.

Rainbow text with hard colour changes

The other way to do it, if you want a more defined, child-like rainbow is to double the stops up. This results in a rainbow gradient with hard colour changes:

h1 {
  background: linear-gradient(to right,
                              red 0%, red 14%,
                              orange 14%, orange 28%,
                              yellow 28%, yellow 42%,
                              green 42%, green 56%,
                              blue 56%, blue 70%,
                              indigo 70%, indigo 84%,
                              violet 84%, violet 100%);
  background-clip: text;
  color: transparent;
  display: inline-block;
}

This produces an effect more like a child’s drawing of a rainbow with clear lines between the colours:

example of rainbow text using hard stops

The background incidentally is another linear gradient. This time vertically, from sky blue to white because yellow is quite hard to see against white, and I wanted it to blend back into the page.

#container {
  background: linear-gradient(to bottom, rgba(135,206,235,0.5) 0%, rgba(255,255,255,1) 100%);
}