Pour kettle and let steep the gods of tea. I built NewsBlur and Turn Touch.
1074 stories

Stop Using Python 2: What You Need to Know About Python 3

1 Comment

Though Python 3 was released in 2008, many projects are still stuck on Python 2.

It’s understandable that porting large existing codebases to a new version is a prospect which sends a shiver down many a developer’s spine. But code inevitably needs to be maintained, and so when all the shiny new features that would fix everything are in a new version, is it really worth staying rooted in the past?

We’ll take you through some of the features that Python 2 programs are missing out on, not only from 3.0 but up to the current release (3.7).

Why Python 3 Happened

Before 2008, Python developers had a bit of a headache. The language that started in the 1989 Christmas holidays as the pet project of Guido van Rossum was now growing at a fast pace. Features had been piled on, and the project was now large enough that earlier design decisions were hindering implementation. Because of this, the process of adding new features was becoming an exercise in hacking around the existing code.

The solution was Python 3: the only release that deliberately broke backwards compatibility. At the time, the decision was controversial. Was it acceptable for a publicly used open source project to purposefully break on older code? Despite the backlash, the decision was taken, giving Guido and the developers a one off chance to clean out redundant code, fix common pitfalls and re-architect the language. The aim was that within Python 3 there would be only one obvious way of doing things. It’s testament to the design choices made back then that we’re still on 3.x releases a decade later.

The __future__ is Now

The __future__ import is a slice of time-travelling wizardry which allows you to summon select features from future releases of Python. In fact, the current Python release, 3.7, contains __future__ imports from releases which haven’t yet been written!

Ok fine, so it’s not quite as grandiose as that, a __future__ import is just an explicit indicator of switching on new syntax which is packaged with the current release. We thought we’d mention it because a few of the Python 3 features listed below can be __future__ imported and used in 2.6 and 2.7, which were released to coincide with 3.0 and 3.1 respectively. Having said this, upgrading is, of course, still advised as new features are ‘frozen’ in past releases and will not benefit from the evolution and maintenance of current versions.

Onto what you’re missing out on in Python 3…

Print is a Function

Yes, we know that most people are aware of this, but it’s one of the most used statements by Pythonistas who are starting out. print moved from a keyword to a function, which just makes sense.

This Python 2 code

print "Fresh Hacks Every Day"
print "Foo", "some more text on the same line as foo"

will become the following in Python 3.

print("Fresh Hacks Every Day")
print("Foo", end='')
print("some more text on the same line as foo")

Souped up Unpacking

Here we have a tuple containing some data. In Python 2, we can already unpack into different variables like so:

person = ("Steve", "Hammond", 34, "England", "spaces")
name, surname, age, country, indent_pref = person

But let’s say we only care about the first name and indentation preference. In Python 3, we can now unpack like this:

person = ("Steve", "Hammond", 34, "England", "spaces")
name, *misc, indent_pref = person

# These would also work
name, surname, age, *misc = person
*misc, indent_pref = person

This provides much more flexibility when unpacking — especially handy if dealing with tuples longer than the one in this example.

Unpacking is commonly used in for-loops, especially when using things like zip() or enumerate(). As an example of applying the new syntax, we now have a function, get_people_data(), that returns a list of tuples like the person example above.

for name, *misc, indent_pref in get_people_data():
    if indent_pref is not "spaces":
        print(f"You will feel the full wrath of PEP 8, {name}.")

This works great. But wouldn’t it be nice if we could store the indentation preference in a better way than just a string? In a way similar to an enum in C?


Enums in Python. What a treat. Due to popular demand, they’ve been in the standard library since 3.4.

Now we can define indentation preference like this:

from enum import Enum

class Indent(Enum):
    SPACES = 'spaces'
    TABS = 'tabs'
    EITHER = 'either'

person = ("Steve", "Hammond", 34, "England", Indent.SPACES)
# or
person = ("Steve", "Hammond", 34, "England", Indent("spaces"))

# Let's try and initialise with an invalid value
person = ("Steve", "Hammond", 34, "England", Indent("invalid value"))
# 'ValueError: 'invalid value' is not a valid Indent

The syntax seems a bit strange, but it can be useful when dealing with numeric constants or initialisation from strings.


A simple but major change: when dividing integers in Python 3 we get true float division by default (dividing two integers in Python 2 always resulted in an integer result).

This is the Python 2 behaviour:

>>> 1 / 3
>>> 5 / 2

Whereas in Python 3 we get more accuracy:

>>> 1 / 3
>>> 5 / 2

// can of course be used for floor integer division if this is required.

This change is one that should definitely be noted if you’re porting code from 2 to 3; it’s an easy one to slip under the radar that could cause major issues in program logic.

Chaining Exceptions

It’s very common to catch one exception, then raise another. This could be because your application has a defined set of custom exceptions, or simply because you want to provide more information about what went wrong.

Here we have a program which crudely calculates the number of days needed to be worked to earn a certain proportion of yearly pay.

class InvalidSalaryError(Exception):

def days_to_earn(annual_pay, amount):
    """Return number of days worked to earn `amount`."""
        annual_frac = amount / annual_pay
    except ZeroDivisionError:
        raise InvalidSalaryError("Could not calculate number of days")
    return 365 * annual_frac

if __name__ == '__main__':
    print(days_to_earn(0, 4500))
    print(days_to_earn(20000, 4500))

We can see that if an annual pay of zero is specified and a ZeroDivisionError occurs, this is caught, and an InvalidSalaryError is raised.

Let’s try running this with Python 2.

$ python days_calc.py
Traceback (most recent call last):
  File "exception_chaining.py", line 13, in <module>
     print(days_to_earn(0, 4500))
  File "exception_chaining.py", line 9, in days_to_earn
    raise InvalidSalaryError("Could not calculate number of days")
__main__.InvalidSalaryError: Could not calculate number of days

Because we caught the ZeroDivisionError, it got swallowed, so only the InvalidSalaryError traceback is shown.

Now let’s run this with Python 3.

$ python3 days_calc.py
Traceback (most recent call last):
  File "exceptions_chaining.py", line 7, in days_to_earn
    annual_frac = amount / annual_pay
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "exceptions_chaining.py", line 13, in <module>
    print(days_to_earn(0, 4_500))
  File "exceptions_chaining.py", line 9, in days_to_earn
    raise InvalidSalaryError("Could not calculate number of days")
__main__.InvalidSalaryError: Could not calculate number of days

We got a far more detailed error report, explaining what caused the InvalidSalaryError, complete with a traceback for the ZeroDivisionError. This is particularly useful when you’re using code written by someone else, which might not have the most verbose error messages.

We won’t go into it here, but there’s also new raise ... from syntax which allows for explicit exception chaining.

Side note: dealing with large numbers in Python

In the above program we had to deal with ints in the tens of thousands. Writing long numbers like 20000 or 0b001110100010 is a recipe for screen squinting. How about separating them like this: 20_000, 0b_0011_1010_0010? This is another way Python 3 will make your life easier – optional underscores in numeric literals, which can help to make things more readable.

Unicode and Bytes

In Python 2 the concept of bytes and strings were pretty much interchangeable, and both came under the str type. This led to some very nasty conversion consequences and unpredictable behaviour. The headline to remember is that in Python 3 all strings are unicode. A distinction was very deliberately created between text and bytes, offering a much more defined way of working.

In the below examples, we test the type of a bytestring, ‘normal’ string and unicode string in the interpreters of Python 2 and 3.

Python 2.7:

>>> type(b'foo')
<type 'str'> # In Python 2, a bytestring is a normal string!
>>> type('foo')
<type 'str'> # The same bytes type as above
>>> type(u'foo')
<type 'unicode'>

Python 3.7:

>>> type(b'foo')
<class 'bytes'> # In Python 3, this has its own bytes type
>>> type('foo')
<class 'str'> # In Python 3, 'str' means unicode
>>> type(u'foo')
<class 'str'> # It's a normal string

This means that dealing with encodings is much clearer in Python 3, even if it comes at the cost of slipping in a few more .encode()s. Chances are that when your program communicates with anything in the outside world, such as files or sockets, you’ll have to encode and decode your data.

As an example, if you’re using pyserial to read/write to a serial device, you’ll need to explicitly encode and decode your messages.

import serial

PORT = '/dev/ttyACM0'
BAUD = 115200
ENCODING = 'utf-8'

if __name__ == '__main__':
    ser = serial.Serial(port=PORT, baudrate=BAUD)

    response_bytes = ser.readline()
    response_str = response_bytes.decode(ENCODING)

String Formatting

Formatting strings in Python 2 was performed in a similar style to C:

author = "Guido van Rossum"
date = 1989
foo = "%s started Python in %d" % (author, date)

# Guido van Rossum started Python in 1989

The docs explicitly state that this way of formatting “exhibits a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly)”. It’s also inflexible, and starts to become ugly to look at when dealing with long strings.

We now have two new ways of formatting strings. One is ultra-convenient, and one is ultra-powerful.

Formatted String Literals

Often referred to as ‘f-strings’, these provide an incredibly easy way to reference any variable available in the current scope.

Checkout how intuitive and readable this code is:

author = "Guido van Rossum"
date = 1989
foo = f"{author} started Python in {date}"

# Guido van Rossum started Python in 1989

Anything inside the curly braces will be evaluated as an expression, so you can put small logic or statements inside the string if you so desire. It’s probably not very readable to contain program logic within a string, but if it’s just getting logged to provide extra debug information then it’s really handy.

author = "Guido van Rossum"
date = 1989 
foo = f"{author.split()[0]} started Python {2000 - date} years before the turn of the century"

# Guido started Python 11 years before the turn of the century

The .format Method

In Python 3, every string has a .format method, which provides a dazzling array of options for formatting, covering the overwhelming majority of use cases. We won’t go into detail here as it is backported to 2.6 and 2.7, so won’t be a big upgrade pull for most Python 2 users.

Here’s one of our favourite guides for reference.


Let’s say that you’re using Python 2, and have the following file hierarchy:


run.py simply imports and calls something from the service module in the pkg package.

But service.py relies on functions contained in utils.py. So at the top of service.py we have this statement.

import utils

Seems fairly unassuming, and everything will work just fine. But what if our folder structure now changes, with pkg acquiring a new utils module?


Time for confusion: our code now switches and uses the utils.py file within pkg. Things would get even more messy if we happened to have a library installed named utils. This approach isn’t defined enough, and consistently led to unpredictable behaviour in Python 2.

Python 3 to the rescue: it’s no longer supported syntax if it’s ambiguous whether the import is supposed to be absolute or relative. The top of service.py could become any of the following options depending on what’s required.

# To import from within pkg, either use relative
from . import utils
# or absolute
from pkg import utils

# To import from the same level as run.py, use absolute
import utils

This feature might seem like a bit of a nicety in this example, but when dealing with big codebases containing large package/import hierarchies you’ll be glad of it.


There are many, many other features which offer improvements and entirely new features over Python 2, even if some are only useful in niche areas. Here are just a few:

  • The addition of the asyncio library makes writing asynchronous programs a breeze. A must in modern programming.
  • Other major standard library additions (like concurrent.futures, ipaddress, and pathlib)
  • Accessing a parent class in Python 2 is needlessly heavy on syntax. In Python 3, super() becomes even more magical.
  • Many builtins such as zip(), map(), and filter() now return iterators instead of lists. In many cases, this will save significant amounts of memory without you even knowing.


If you decide that porting code from Python 2 to 3 is the way to go, there are some existing tools to make your life easier.

  • 2to3 – the official automated code translation tool. Yes, it will port the code for you! Not guaranteed to catch everything, but does a lot of the tedious syntactic fiddling.
  • caniusepython3 – a nifty utility for detecting which of your project dependencies are stopping you from making the leap.
  • tox automates and streamlines the testing of Python code. It allows you to easily test your code on multiple versions of Python, which is fantastic for any project in general, but particularly comes in handy when you’re testing the success of your newly ported codebase on different versions.


There are countless reasons to upgrade to Python 3 – not just because of the convenience of new features, but because random, obscure bugs in the language get fixed regularly by Python developers, in Python 3 alone. Only the most robustly tested, never-need-to-change codebases have an excuse to remain at Python 2. Everything else should be enjoying the fantastic hard work put in by Python developers to make the language what it is today.

Read the whole story
2 days ago
NewsBlur is still firmly in python 2.7 land. One day I’ll make the 2to3 upgrade but I’m understandably worried about encodings going haywire.
The Haight in San Francisco
2 days ago
is there a reason you chose v2 at the time? supporting libs?
2 days ago
In 2009? Because it was the only choice. Python 3 was not feasible back in 2009, libs or not.
1 day ago
For what it is worth anecdotally, I've only seen encodings getting better in a 2-to-3 transition. Cleaning up the mess that was 2 encodings was a big part of 3 and alone is one of the reasons I'd never willingly go back to 2.
Share this story

The Cero One, a Modular, Electric Cargo Bike Based on Japanese Utility Bicycles

1 Comment and 2 Shares

Take a trip to virtually any region of Japan and you'll see plenty of mamachari; translated as "mom's bike," mamachari are no-frills utility bicycles with a handy basket used as grocery getters, kiddie haulers and commuter vehicles.

The Cero One is a cargo bike that takes its inspiration from the mamachari. It doesn't look like a cargo bike; the only giveaway is the extra-large rear wheel. But kitted out with a series of modular baskets and rackets, the Cero One offers a 12-way modular cargo system--and an electric motor, giving you up to 93 miles of range.

"Our goal was to design and build a modern version of the Japanese 'Mamachari,' a practical utility bike that could be used by almost anyone as a replacement for a car in their daily lives," said Kiyoshi Iwai, founder of CERO.
"The CERO One allows urban dwellers to do almost anything they'd do in a car, but more quickly and efficiently. A powerful electric motor and wide range of accessories make the bike perfect for getting around town as well as carrying almost anything, whether that's groceries, pizza for delivery or precious cargo. I even take my surfboard to the beach near our office in Santa Monica with CERO One."
< span="">

Check it out here.

Read the whole story
3 days ago
Not the prettiest but it's up there against all the other e-cargo bikes.
The Haight in San Francisco
Share this story

Anatomy of a CR2032 Battery

1 Comment and 2 Shares

Disassembled CR2032 battery From left — negative cup from inner side with layer of lithium (oxidized in air), separator (porous material), cathode (manganese dioxide), metal grid — current collector, metal casing (+) (damaged while opening the cell), on the bottom is plastic insulation ring

via Wikipedia article for Lithium battery

Read the whole story
3 days ago
I order these by the thousand and I’ve never opened one up before.
The Haight in San Francisco
3 days ago
I haven't torn one apart due to concerns about the lithium in them...
3 days ago
where is all the electricity? must have spilled
Share this story

Turn Touch: Beautiful Control [Sponsor]


Simplify your smart home with a gorgeous wooden remote control. The Turn Touch combines natural mahogany and rosewood, a simple, elegant design, and sophisticated control of your smart home devices that is as good-looking in your home as it is useful.

The Turn Touch features just four buttons, but with taps, double taps, and tap-and-hold, the device puts an astonishing range of control at your fingertips. The Turn Touch is tough too. It’s constructed from dense, durable woods that stand up to shocks, drops, and dirt. What’s more, the Turn Touch is always on, ready to make the most of your smart home devices.

The Turn Touch works with a long list of smart devices. Control your Mac or iOS devices, Hue lights, Sonos speakers, WeMo devices, smart thermostats, and much more. Configuring the Turn Touch is simple from an iOS device or Mac, and once it’s set up, the Touch Touch’s battery lasts about a year ensuring that it’s there when you need it.

The Turn Touch Pedestal, which is sold separately, makes a perfect home base for the Turn Touch too. Rest it on a table or mount it on the wall to use it as a smart wall switch. The Turn Touch is held in place with cleverly-hidden magnets.

For a limited time, MacStories readers can purchase the Turn Touch Pedestal for 25% off at checkout by using the coupon code PEDESTAL25.

Smart devices don’t have to be made of cheap, ugly plastic. Check out Turn Touch today to learn more, and bring beautiful control to your smart home.

Our thanks to Turn Touch for sponsoring MacStories this week.

Support MacStories Directly

Club MacStories offers exclusive access to extra MacStories content, delivered every week; it's also a way to support us directly.

Club MacStories will help you discover the best apps for your devices and get the most out of your iPhone, iPad, and Mac. Plus, it's made in Italy.

Join Now
Read the whole story
4 days ago
Turn Touch is an elegant way to transform smart home technology into a more humane experience.
Space City, USA
4 days ago
Sponsoring Macstories this week. Turn Touch is now only $49! And $79 buys you a remote and a beautiful pedestal.
The Haight in San Francisco
Share this story

Our 7 Favorite Packrafting Trips

1 Comment

Packrafting isn’t exactly new. Small, portable rubber rafts have been used in expeditions since the mid-1800s. But there’s been a spike of interest in the durable one-person crafts that can be carried in your backpack. The American Packrafting Association reports that 76 percent of its members picked up the hobby in the past five years, and outfitters from Alaska to Montenegro are tapping into the trend with guided trips that involve hiking to and rafting down some of the world’s most remote waterways. If you’re looking to really get away, sign up for a trip or get equipped with the knowledge and supplies you’ll need to plan your own excursions. Here’s where to start.

Wrangell-St. Elias National Park

(Courtesy Kennicott Wilderness Guides)


Being able to travel by water opens up Alaska’s vast stretches of untouched wilderness. Kennicott Wilderness Guides offers two-day courses in Wrangell-St. Elias National Park, an expanse of jagged peaks larger than Switzerland, that’ll teach you skills such as trip planning, river-running strategies, and self-rescue. If you’d rather have a guide lead the way, book a half-day, full-day, or weeklong trip, and you’ll hike to a glacial lake and run mellow Class II rapids while someone else takes care of the logistics (from $130).

Magpie River

boreal river
(Courtesy Boreal River Adventures)

Quebec, Canada

On this guided 12-day trip with Boreal River Adventures, you’ll fly by helicopter from Sept-Îles, Quebec, into a remote northern forest before spending three days backpacking, rappelling, and orienteering through trail-free wilderness to Lake Magpie, the source of the famed Magpie River. From there, you’ll paddle your craft more than 100 miles down Class III and Class IV rapids to the Atlantic Ocean, catching brook trout for dinner along the way ($4,486).

Grand Canyon National Park

(Courtesy Wildland Trekking)


Thanks to packrafts, you can combine a world-class Grand Canyon backpacking journey with a jaunt down the river. Wildland Trekking has a six-day rim-to-rim trip where you’ll hike into the canyon via the North Bass Trail, paddle across the Colorado River, then ascend the South Bass Trail. The $1,775 price tag includes all your camping and paddling gear and meals, plus transportation to and from Flagstaff, Arizona.


(Courtesy Outventurous)


Gabriel Gersch is a 31-year-old adventurer who guided in Alaska’s Brooks Range before launching Outventurous, a wilderness travel company that hosts expeditions across Europe. He bought his first packraft in 2010 and has undertaken trips through some of the world’s wildest mountain ranges from Patagonia to Pakistan. Gersch offers custom-made trips and logistical support for planning your own outing, coordinating details like budgeting, permitting, and food supplies. But the coolest thing about Gersch is that, for a relatively affordable fee, he’ll let you join him on his own adventures. This summer and early fall, he’s leading passages across Greenland (from $3,402).

Tara River Canyon

(Courtesy Packraft Touren)


To truly experience the Montenegro’s Tara River Canyon, one of the longest and deepest gorges in Europe, you’ll have to take to the water. On this weeklong expedition from Packraft Touren, you’ll explore the 74-mile canyon through the mountains of Durmitor National Park, as well as the Morača River and Bosnia’s Neretva River. The $721 trip includes transportation and guides, but not food, lodging, or gear. You’ll have to pitch a tent or stay in the hotels and bungalows along the river. Most camps have food available, or pack your own.

Snake and Hoback Rivers

(Courtesy Teton Backcountry Rentals)

Jackson, Wyoming

Want to go off the grid in the Tetons? Teton Backcountry Rentals will rent you pretty much everything you need, including tents, backpacks, crampons, ultralight cookware, and, yes, packrafts. This summer, the company has teamed up with Rendezvous River Sports and the American Packrafting Association to offer guided trips on the area’s Snake and Hoback rivers. It’s also teaching two-day clinics that cover essentials skills like swiftwater rescue, paddling techniques, and river navigation.

Fiordland National Park

(Courtesy Expedition X)

New Zealand

Expedition X is New Zealand’s only packrafting guide company, and it specializes in tours of the South Island’s Fiordland National Park. The company’s day trips will see you paddling the Waiau River and hiking the renowned Kepler Track (from $202). Longer trips will take you deeper, covering up to 93 miles of rugged wilderness, crossing alpine lakes and camping on sandy beaches and isolated islands. Or you can sign up for a safety and skills course and head out on your own for as long as your heart desires.

Read the whole story
10 days ago
Such luxury!
The Haight in San Francisco
7 days ago
Looks like fun, I am doing my first canoe portage trip in a few weeks and can't wait!
Share this story

How—And Why—To Avoid Tolerance Stacking In Your Technical Drawings

1 Comment

If you want to have your part designs fabricated, you’re going to need to provide the manufacturer with a technical drawing. Yes, 3D printers and many modern machine tools rely on toolpaths created from 3D models. But, there is a good chance the manufacturer will be recreating the 3D model in their own system, instead of using the one you provided. Or, they may use traditional manual machining and not touch a 3D model at all. More importantly, the technical drawing gives them vital information on how closely they need to adhere to your dimensions in order for you to accept the parts.

On a technical drawing, the dimension that you want is called the nominal. But, no manufacturing is ever perfect, so you have to allow some wiggle room in what you’ll accept. That wiggle room is called tolerance. Maybe your part could be a little longer than specified and it wouldn’t affect the functionality. Maybe it could be a little shorter—or either. Specifying a tolerance is necessary, because it tells the manufacturer exactly how much wiggle room you’re giving them.

But, tolerances can introduce unforeseen consequences if you’re not careful. The wiggle room provided by tolerances is absolutely necessary, but if you don’t use them properly you can easily end up with unusable parts, even if the manufacturer followed your instructions to the letter. That usually happens because you have multiple tolerances being added together, which is called tolerance stacking.

Compounding Problems

Take a look at the dimensions of the part shown above, can you see the problem? At first glance, you might assert that this tells the manufacturer that the right-most hole can be between 189.90 and 190.10 mm from the left edge of the part. In reality, this actually tells them that it can be anything from 189.50 to 190.50 mm. That’s because each dimension is based on the feature before it, which is flexible by 1/10th of a millimeter in either direction. That compounds with each new feature, and the tolerances stack to eventually end up with a lot more wiggle than you likely intended.

Now, it’s entirely possible that a total potential variation of 1mm may not make your part unusable. But, even if that’s the case, this is still bad practice because it’s unclear if that is your intention or not. The entire purpose of the drafting discipline is to remove ambiguity when communicating a part design, and tolerance stacking is very ambiguous. If your right-most hole can have a 0.50mm tolerance in both directions, that should be explicitly stated.

Using Ordinate Dimensions

How do you definitively specify that without stacking your tolerances? In this example, the simplest solution is to use ordinate dimensions, which all reference a single solid origin point. The edges of the part are hard edges, and are likely what you want the interior features to be measured from. Therefore, you can use ordinate dimensions, like below, from the left or right edge so that every hole has a non-flexible reference and avoiding tolerance stacking.

Unfortunately, ordinate dimensions won’t work in all situations. For instance, the part below has features that are arranged radially. The dimensions—and therefore tolerances—are in degrees, not a distance like with millimeters. But, this is still a case of tolerance stacking, and the first and last holes could end up being anywhere from 132 to 138 degrees apart.

In that situation, the prudent solution would be to base each dimension off of a single geometric reference point, like the top dead center. So, the second hole would be 45°, the third would be 90°, and the fourth would be 135°. But, once again, that’s only a solution to another specific example; what you really need is a firm understanding of the problem, and to use critical thinking to recognize it and solve it in your own technical drawings.

Don’t Make Them Guess

Tolerance stacking happens when a feature’s placement is measured from another feature that has a position that could change slightly. In some cases, you may want that. In the example above, it’s possible that, in your design, the third and fourth holes being 45° apart is more important than their position relative to the first hole, or the part in general. You’re the only one who knows what’s necessary for your part to function properly, and it’s the manufacturer’s job to simply follow your technical drawing as closely as possible.

You always need to keep that concept in mind as you’re drafting your technical drawings. Ask yourself how much wiggle room you’re willing to give the manufacturer. But, at the same time, ask yourself what that wiggle room is based off of. Maybe a particular feature needs to fall within a specific tolerance from the edge of the part—or maybe it’s more critical that it be located precisely in relation to a neighboring feature. Only you know.

The purpose of a technical drawing is to tell the manufacturer exactly how to make your part, and to do so without any potential confusion. If they follow your drawing to the letter, you can’t then reject a delivery of 1,000 parts because they didn’t correctly guess your intent. In most cases, the machinists won’t know or care how your design actually works, they only care about how precisely they can adhere to your drawing. So, it’s up to you to fully understand what your drawing is telling them, and how to avoid problems like tolerance stacking.

Read the whole story
23 days ago
Nice intro to tolerance stackup.
The Haight in San Francisco
23 days ago
When did hackaday start having such great articles?
Share this story
Next Page of Stories