DEV Community

Cover image for Sal’s Shipping Struggles
DaoistRose
DaoistRose

Posted on

Sal’s Shipping Struggles

Expanding the User Experience — My Beginner’s Journey

Sal’s Shippers is the busiest logistics outfit in the tri-county area. With a growing customer base and a variety of services, Sal needed a solution that would help users quickly determine the most affordable way to ship their packages. That’s where my next Codecademy Python project came in: build a simple, functional, and friendly tool to compare shipping options based on weight.

It started as a basic calculator. But just like last time, I saw opportunities to explore more: adding polish, improving the flow, and thinking about the user first.


Getting Started

I’m still early in my coding journey (Day 4), but each new project is an invitation to go beyond the requirements. Codecademy asked me to write a Python script that takes a package’s weight and calculates shipping costs for three different options: Ground Shipping, Premium Ground, and the high-flying new Drone Shipping.

This felt like the perfect next step from my Magic 8-Ball project. The logic was a bit more involved, and there were plenty of places to make things friendlier, clearer, and more reusable. I started simple, then looked for rabbit holes to follow and lessons to uncover.


Project Overview

Write a program that asks the user for the weight of their package and then tells them which method of shipping is cheapest—and how much it will cost.

Starting Points

  • Prompt the user to enter the package weight.
  • Calculate the cost for:
    • Ground Shipping (tiered rate + flat fee)
    • Premium Ground Shipping (flat rate only)
    • Drone Shipping (tiered rate, no flat fee)
  • Compare the three and return the cheapest option.
  • Test with example weights like 4.8 lbs and 41.5 lbs.

Enhancing the Experience

User Input Validation

  • Caught invalid or negative weight entries with try/except and a while loop.
  • Helped users recover from errors without crashing the program.

A More Conversational Flow

  • Added a warm intro and a thank-you message.
  • Used time.sleep() to add short pauses, just enough to simulate a helpful assistant thinking things through.
  • Wrapped everything in a loop so users could price multiple packages without restarting.

Getting the Output Just Right

Since the program calculates dollar amounts, I wanted all cost values to show exactly two decimal places—no more, no less. At first, I tried using round() for this. While it worked in theory, I ran into a visual problem: Python would display values like $45.20 as $45.2, which felt sloppy for something involving money.

To fix that, I switched to using the .format() method with a format specifier. Specifically:

{:.2f}

Here’s what that does:

  • : starts the format specification
  • .2 ensures exactly two decimal places
  • f means it’s a floating-point number
    # define which is the cheapest way to ship an item
    if ground_shipping_price < ground_shipping_premium and ground_shipping_price < drone_shipping_price:
        cheapest_option = 'Your cheapest option to ship this item is with ground shipping. Total cost: ${:.2f} \n'.format(ground_shipping_price)
    elif ground_shipping_premium < ground_shipping_price and ground_shipping_premium < drone_shipping_price:
        cheapest_option = 'Your cheapest option to ship this item is with premium ground shipping. Total cost: ${:.2f} \n'.format(ground_shipping_premium)
    elif drone_shipping_price <= ground_shipping_price and drone_shipping_price <= ground_shipping_premium:
        cheapest_option = 'Your cheapest option to ship this item is via drone shipping. Total cost: ${:.2f} \n'.format(drone_shipping_price)
    else:
        cheapest_option = '\nPlease enter a valid weight '
Enter fullscreen mode Exit fullscreen mode

So, for example, a package that weighs 6.3 pounds and costs $45.20 to ship will now show up properly—decimal and all. Small fix, big improvement.

Readable, Reusable Code (Almost)

While I haven’t modularized things into functions yet, duplicating logic for repeat packages showed me how useful reusable code will be in the long run.


Lessons Learned

  • Validating user input is essential and feels empowering to get right.
  • while loops + try/except = smooth UX.
  • Small touches (like a pause or a prompt) go a long way.
  • Writing slightly messy code first is okay, it teaches you what to clean up later.

What I’d Add Next

As I keep learning, I already have a few ideas I’d love to implement when I understand Python a bit more:

  • Create items based on input: Let users name their packages and keep a record of each one, including weight and shipping method.
  • Show a full breakdown: Display the price for all shipping options—not just the cheapest so the user can see the full picture.
  • Use functions: Right now my code repeats a lot. Once I better understand how to write and call functions properly, I’d love to restructure this project into clean, reusable blocks.

These aren’t “musts” for a basic program, but they’re the kinds of improvements that turn something simple into something polished.


Final Thoughts

This project pushed me to think about more than just math and logic. It encouraged me to consider how real people would interact with the code—and how to make that interaction as clear and enjoyable as possible.

Here’s to Sal, shipping, and the small wins that feel big when you’re learning to code.

If you’re also learning Python or working through Codecademy’s curriculum, I’d love to hear how you’d improve this one! Would you have done anything differently? What would you refactor first?

Let’s connect and learn together—every project brings something new.


The Code


python
# Sal's Shipping - Codecademy Project
import time

# greeting the user
print("\nWelcome to Sal's Shipping! Let's find the best way to ship your package.")
time.sleep(2)
print("We offer three shipping options: Ground Shipping, Premium Ground Shipping, and Drone Shipping. \n")
time.sleep(2)

# define the package weight
weight = input('Enter the weight of the package in pounds: ')

# validate user input for weight
while True:
    try:
        weight = float(weight)
        if weight < 0:
            weight = input('\nPlease enter a valid weight (must be positive): ')
        else:
            break
    except ValueError:
        weight = input('\nPlease enter a valid number for weight: ')

# define ground shipping price
if weight <= 2:
    ground_shipping_price = 1.5 * weight + 20
elif weight <= 6:
    ground_shipping_price = 3 * weight + 20
elif weight <= 10:
    ground_shipping_price = 4 * weight + 20
else:
    ground_shipping_price = 4.75 * weight + 20

# define premium ground shipping (flat rate)
ground_shipping_premium = 125

# define drone shipping price
if weight <= 2:
    drone_shipping_price = 4.5 * weight
elif weight <= 6:
    drone_shipping_price = 9 * weight
elif weight <= 10:
    drone_shipping_price = 12 * weight
else:
    drone_shipping_price = 14.25 * weight

# determine cheapest option
if ground_shipping_price < ground_shipping_premium and ground_shipping_price < drone_shipping_price:
    cheapest_option = 'Your cheapest option to ship this item is with ground shipping. Total cost: ${:.2f} \n'.format(ground_shipping_price)
elif ground_shipping_premium < ground_shipping_price and ground_shipping_premium < drone_shipping_price:
    cheapest_option = 'Your cheapest option to ship this item is with premium ground shipping. Total cost: ${:.2f} \n'.format(ground_shipping_premium)
else:
    cheapest_option = 'Your cheapest option to ship this item is via drone shipping. Total cost: ${:.2f} \n'.format(drone_shipping_price)

print(cheapest_option)
time.sleep(2)

# allow multiple items
more_items = input("Thank you for using Sal's Shipping! Do you have another package to ship? (yes/no) \n").strip().lower()
while more_items not in ['yes', 'no']:
    print('Please answer with "yes" or "no". \n')
    more_items = input("Do you have another package to ship? (yes/no)  ").strip().lower()

while more_items == 'yes':
    weight = input('Enter the weight of the package in pounds: ')

    while True:
        try:
            weight = float(weight)
            if weight < 0:
                weight = input('\nPlease enter a valid weight (must be positive): ')
            else:
                break
        except ValueError:
            weight = input('\nPlease enter a valid number for weight: ')

    if weight <= 2:
        ground_shipping_price = 1.5 * weight + 20
    elif weight <= 6:
        ground_shipping_price = 3 * weight + 20
    elif weight <= 10:
        ground_shipping_price = 4 * weight + 20
    else:
        ground_shipping_price = 4.75 * weight + 20

    ground_shipping_premium = 125

    if weight <= 2:
        drone_shipping_price = 4.5 * weight
    elif weight <= 6:
        drone_shipping_price = 9 * weight
    elif weight <= 10:
        drone_shipping_price = 12 * weight
    else:
        drone_shipping_price = 14.25 * weight

    if ground_shipping_price < ground_shipping_premium and ground_shipping_price < drone_shipping_price:
        cheapest_option = 'Your cheapest option to ship this item is with ground shipping. Total cost: ${:.2f} \n'.format(ground_shipping_price)
    elif ground_shipping_premium < ground_shipping_price and ground_shipping_premium < drone_shipping_price:
        cheapest_option = 'Your cheapest option to ship this item is with premium ground shipping. Total cost: ${:.2f} \n'.format(ground_shipping_premium)
    else:
        cheapest_option = 'Your cheapest option to ship this item is via drone shipping. Total cost: ${:.2f} \n'.format(drone_shipping_price)

    print(cheapest_option)
    time.sleep(2)

    more_items = input("Do you have another package to ship? (yes/no)  ").strip().lower()
    while more_items not in ['yes', 'no']:
        print('Please answer with "yes" or "no".')
        more_items = input("Do you have another package to ship? (yes/no) ").strip().lower()

print("\nThank you for using Sal's 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)