Case Study: Fixing a WooCommerce Website for a New Client

I met Steven at his store on Bloomfield Avenue in Northern New Jersey. After I gave him my business card he told me his website needs help. The checkout wasn’t working, and users couldn’t even add products to their cart. This was how the previous web development vendor left things before their arrangement ended.

The website was powered by WordPress (managed by Bluehost), and used WooCommerce as its ecommerce solution. I helped him create a Stripe account, and connect it to his online store.  I finished configuring a premium WordPress theme called BeTheme, and gave him a multi-week marketing plan to help sales grow.

website screenshot

I used an image manipulation program (the GIMP) to create graphic assets used throughout the shop:

website graphic design

Many times I have to pick up where someone else left off. I could tell you another story about inheriting a Frankenstein tech stack from a previous vendor. They left off on non-talking terms after demanding back work payments to release the credentials to my team. My skill in figuring things out, regardless of the technology involved, shines in times like these.

My company tag line is “I can build your website” – it should really be “I can fix your website”. Business owners try to do it themselves, and often make it most of the way. When you need help, I am there to carry it over the finish line. I’ve been asked if services like Wix cuts into my business – it’s actually the opposite. Broken, incomplete, or unoptimized websites created on easy-to-use platforms have provided a solid market for my expertise.

Organic market

Local small businesses are what make neighborhoods unique and give families a chance to make a living themselves. It feels great to help people knowing we can both benefit. You can read more about the plan I use to help businesses with their existing website in another blog post.

Membership Discounts Without a Plugin

As part of the marketing plan, we decided to add membership accounts to the WordPress ecommerce website for Organic Sun Market. Enabling that capability was a few settings in the dashboard: WooCommerce > Settings > Accounts & Privacy

woocommerce accounts and privacy settings

I also added a “My Account” link to the site’s global navigation.

menu in wordpress

By default, WooCommerce provides a “My Account” page where users can log in, view their orders, update their information, and more. You can specify a custom page in the advanced settings: WooCommerce > Settings > Advanced

woocommerce advanced setting

The account page specified uses a WooCommerce short code to handle the content: [woocommerce_my_account]

account page shortcode

Change menu text if user is logged into WordPress

I wanted the “My Account” menu text to change if the user is not logged in. I was able to do this with the WordPress hook `wp_nav_menu` and a simple string replacement PHP function:

add_filter('wp_nav_menu', 'change_my_account_menu_item', 10, 2);

function change_my_account_menu_item($nav_menu, $args) {
// Check if the user is not logged in
    if (!is_user_logged_in()) {
        // Change "My Account" link to "Login/Register"
        $nav_menu = str_replace('My account', 'Login/Register', $nav_menu);
    }
    return $nav_menu;
}

To incentivize users to create an account, we offer a 5% discount to any one logged in. The checkout page contains conditional messaging (depending on wether they are logged in or not) to communicate this incentive.

conditional css messaging on checkout

Hide or show UI elements if user is logged into WordPress

I am able to apply that  style condition with two custom CSS classes, specific to the presence of the WordPress body class ‘logged-in’:

.only-show-while-logged-in{display: none;}
body.logged-in .dont-show-while-logged-in{display:none;}
body.logged-in .only-show-while-logged-in{display:block;}

Apply WooCommerce discount to logged in users

I applied the discount by using custom PHP code in the child theme’s functions.php file with the `woocommerce_before_calculate_totals` hook:

add_action( 'woocommerce_before_calculate_totals', 'no_discount_if_not_logged_in', 10, 1);
function no_discount_if_not_logged_in( $cart ) {
	if (is_user_logged_in()) {              
		foreach ( $cart->get_cart() as $cart_item ) {        
			$discount_eliminate = $cart_item['data']->get_regular_price();
			$discount_percentage = 5; // Set your desired discount percentage
			$discount_amount = $discount_eliminate * ($discount_percentage / 100);
			$new_price = $discount_eliminate - $discount_amount;

			$cart_item['data']->set_price($new_price);
		}
	}
}

Apply WooCommerce discount to logged in users on a specific category of products

Later, we changed the logic to be a 10% discount for logged-in members, but only on products that were part of a specific category called “bundles”.

add_action( 'woocommerce_before_calculate_totals', 'discount_for_specific_category', 10, 1);

function discount_for_specific_category( $cart ) {
    if ( is_user_logged_in() ) {
        // Define the category slug you want to apply the discount to
        $target_category = 'bundles';

        foreach ( $cart->get_cart() as $cart_item ) {
            $product_id = $cart_item['product_id'];

            // Check if the product belongs to the target category
            if ( has_term( $target_category, 'product_cat', $product_id ) ) {
                $discount_eliminate = $cart_item['data']->get_regular_price();
                $discount_percentage = 10; // Set your desired discount percentage
                $discount_amount = $discount_eliminate * ( $discount_percentage / 100 );
                $new_price = $discount_eliminate - $discount_amount;

                $cart_item['data']->set_price( $new_price );
            }
        }
    }
}

Print Design

Many local small businesses take their marketing offline and into the real world. Print marketing is a business I have been a part of for almost two decades. I have designed, delivered, and distributed flyers, menus, business cards and more. As the holiday season approached, Steven asked me to create a poster for one of his healthy products.

graphic design request via text message

He sent me a draft he has been working on, along with some inspiration examples that expressed the direction he wanted things to go. This was the final product:

Dog treats poster

And here it is hanging in the store front:

Printed poster design

Boost Your Marketing: Integrating Newsletter Signups with HubSpot API

hubspot api

I do a lot of in-person prospecting to win new business. I used to focus on giving out my business card, and then hoping the potential client would reach out to me. I learned that its better to capture their information, and then follow up. I used to collect so many business cards. Now I use a CRM, Customer Relationship Manager, called HubSpot. It does a lot of things, but primarily it helps to manage contacts. I want to let users sign up to my newsletter, and add themselves as a HubSpot contact, directly from my website.

hubspot forms

Create a Custom Newsletter Sign Up Form on Your Website Powered by HubSpot

Out-of-the-box, HubSpot can generate a number of different web forms that can be easily embedded into any website. These forms are used to capture leads and contacts.

HubSpot Private App

My website (this website) is mostly hand-coded. I want to build my own custom form, and submit the data to the HubSpot service. This is possible with the “Private app” feature. You can find this under ‘Settings -> Integrations -> Private Apps’. This strategy acts as a work-around to remove the HubSpot logo from forms without having to upgrade to premium.

HubSpot Private Apps

After entering a name and description for your “app”, you’ll need to select permission scopes. I called mine “Antpace-Website” and described it “signup forms on antpace.com”. The only scope is gave it was called `crm.objects.contacts.write`

hubspot permission scopes

CRM API – Create Contact

To create a contact programmatically through the HubSpot API, we use our private app’s access token. In my website’s HTML, I create a simple form:

<div class="col-md-12">
    <h1 style="text-align: center;">Newsletter</h1>
    	<p>Joining the mailing list!</p>
        <form id="hubspotForm" class="styled-form">
            <input type="hidden" value="subscriber" name="lifecyclestage">
            <div>
            	<div><input type="email" placeholder="Email *" value="" id="hubspot-email" name="email" class=""></div>    
                <div><input type="text" placeholder="First Name" name="firstname" value="" class=""></div>
                <div><input type="text" placeholder="Last Name" name="lastname" value="" class=""></div>        
                <div><input type="tel" placeholder="Phone" value="" name="phone" class=""></div>            
                <div><input type="text" placeholder="Company" value="" name="company" class=""></div>            
                <div><input type="text" placeholder="Website" value="" name="website" class=""></div>            
                
                <div><button type="button" id="signupButton" class="btn">Sign Up</button></div>
            </div>
	</form>
</div>

I add basic jQuery JavaScript to pass the form data along to my backend service when the button is clicked:

<script>
$(function(){
	const notifications = new UINotifications();
	$("#signupButton").click(function(){
		const email = $("#hubspot-email").val();
		if(email.length < 1){
			notifications.showStatusMessage("An email address is required.");
			return;
		}
		const formData = {
			properties: {}
		};

		// Iterate over form fields and add them to formData
		$("#hubspotForm input").each(function() {
			const fieldName = $(this).attr("name");
			const fieldValue = $(this).val();
			formData.properties[fieldName] = fieldValue;
		});
		$.ajax({
			type: "POST",
			data: JSON.stringify(formData),
			url: "/hubspot-service.php",
			success:function(response){
				console.log(response);
				notifications.showStatusMessage("Thank you for signing up.");
                                $("#hubspotForm")[0].reset();
			
			}
			
		});
	});

});
</script>

The HubSpot API documentation says, “To create new contacts, make a POST request to /crm/v3/objects/contacts“. Some simple PHP cURL commands accomplishes this. Here is the content of hubspot-service.php:

<?php

$url = 'https://api.hubapi.com/crm/v3/objects/contacts';
$accessToken = 'xxx';

$headers = array(
    'Authorization: Bearer ' . $accessToken,
    'Content-Type: application/json',
);

$postData = file_get_contents("php://input");

$ch = curl_init($url);

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);

if (curl_errno($ch)) {
    echo 'Error: ' . curl_error($ch);
}

curl_close($ch);
echo $response;

?>

You can see the end result by visiting my newsletter sign up page. Make sure you add yourself so you can stay up-to-date with technology tips for business.

Newsletter sign up page

I can use this same PHP service file for other HubSpot email sign up forms throughout my website.

Freelance Web Development: Delivering Value to Clients

freelance web dev process

When I win a new web development client I follow a structured progress. This ensures high quality results. Years of refinement and experience continue to define how I work with people and businesses to help them succeed.

Discussion

This is the first step. Communication is key.

This initial discussion allows us to explore your project’s overarching goals. It’s a high-level chat to understand your aspirations and ensure our visions align. We’ll delve into:

  • Nature of the Project: Is this a revamp of an existing platform or the birth of something entirely new?
  • Scope of Work: What exactly are we building? It could range from a website, a dynamic web application, an eCommerce storefront, to other web-based projects.
  • Branding Elements: Have you established a brand identity already? Do you possess logo designs or specific themes you want incorporated?
  • Budget Considerations: A transparent conversation about the budget ensures we shape the project according to the resources available.
  • Project Goals: What do you hope to achieve with this project? Understanding your objectives ensures we’re steering in the right direction from the get-go.

After our conversation, we’ll examine any pre-existing materials that are pertinent. Perhaps you have an existing website that needs sprucing up or logos that you’d love incorporated. Alternatively, you might point to other inspiring sites or platforms, even if they’re not yours, to give a clearer picture of your vision. This step is all about gathering resources and setting a concrete foundation.

Based on our dialogue and the data collated, I’ll recommend the best technologies and tools. This could encompass anything from choosing the right content management system, database technologies, or frontend frameworks.

Planning

Step two. Every element discussed in our initial conversation is now put down in black and white. It’s our chance to reiterate the goals and ensure we’re on the same page. This documentation becomes a reference point, ensuring we stay aligned with the project’s vision.

We detail objectives, decide on the most fitting technology stack, outline the budget, and establish a clear timeline.

Development

As we progress through this building phase, you’ll have access to a private server for reviews and approvals. Everything—from the user-friendly experience to backend configurations like domain setup, security measures, and CMS installation—is shaped by our prior discussions, ensuring both aesthetics and functionality are on point.

Content

During the website’s initial build, I typically use placeholder content. With the design and layout set, it’s your cue to provide the actual content. While you can opt to share materials earlier, this phase is ideal. And rest assured, you’ll retain full control to modify content as needed later on.

Quality Review

Before launching, I rigorously test the product across various devices, browsers, and screen dimensions to ensure quality. This phase is dedicated to refining the detail, ensuring both appearance and functionality are flawless.

Final Touches

I ensure that your website is fully optimized for SEO, integrating structured data, sitemaps, and relevant keywords. By enhancing its security, mobile responsiveness, and speed, your SEO score will naturally improve. Further bolstering this, I can register your site with Google Search Console and activate AMP (Accelerated Mobile Pages) to amplify its prominence in Google searches. Additionally, I’m here to guide you in devising a content strategy tailored to elevate your online visibility.

For those seeking email hosting, I offer solutions tailored to your needs, with Google Workspace being a top recommendation for those starting afresh. When it comes to choosing a CMS, WordPress or Shopify are often top picks for businesses.

Beyond these services, I specialize in web design, crafting a visual identity that seamlessly embodies your brand. And rest assured, user experience is a top priority; I design ensuring visitors experience positive, smooth interactions across your digital platform.

This framework is described and outlined on another page of this website. It is what I use when I engage a client that has an existing website that might need maintenance or improvements.

Meditation & Mindfulness for Programmers

Meditation & Mindfulness for Programmers

Programming and meditation have a lot in common. Both demand focus and concentration and can enhance your ability to think clearly and solve problems.

When you program, you are constantly thinking critically and solving problems. You must be able to debug your code when something goes wrong, pay close attention to the little things, and think rationally. This can be mentally difficult since it calls for intense focus and concentration.

Focus and concentration can be enhanced through the practice of meditation. It can entail sitting in quiet while concentrating on your breath or a mantra, which is a particular word or phrase. This can assist with distraction removal and strengthen your capacity for sustained attention.

I started meditating early in my career as a programmer. Having had an interest in Buddhism, the tangental practice of meditation was appealing as a self-care ritual. I didn’t anticipate the impact its benefits would have on my skill, motivation, and focus. These necessary attributes compounded as my practice grew.

Meditation can help reduce stress and anxiety. This is important for programmers, as the work can be challenging. The ability to stay calm and focused in the face of stress can be invaluable in the programming world.

I had always been a workhorse, spending hours upon hours coding and debugging. Meditating for just a few minutes a day helped me to clear my mind and focus on the task at hand. I discovered I could sleep better and was less irritable.

As I continued to meditate, I found that my productivity increased, and I was able to tackle problems that previously seemed insurmountable with ease. My coding was more precise and effective. I was able to think more imaginatively and provide fresh ideas for problems.

I was so impressed with the benefits of meditation that I began to teach it to my colleagues. They also discovered that it made people more productive and happier at work.

Writing as a Meditation Practice

In another post, Reading Habits for Programmers, I discuss the benefits of practicing focus to improve coding skills. I mention that “if reading benefits your coding ability, then meditation does too”. I would go as far as to say that reading is a form of meditation. Any time we intentionally shift our focus from scattered to laser-like, we are practicing mindfulness. Note-taking and blogging is a great way to do that too.

Writing about how the world seems through your own particular lens fosters mindfulness and appreciation. It keeps your mind grounded in this realm. Journaling is an important ritual that I practice daily, but it is hard to take note of and digest everything that happens in our lives. Doing it here is a way that I can highlight the stuff that has truly touched me.

To get philosophical about it, I think that what’s really out there and what we experience might be very different things.  Like how a the experience of a computer screen showing a beautifully drawn graphical user interface never hints at the reality of computer boards directing electrical circuits to represent the information we see. Our notion of reality is a digital simulation instigated by the sensory input interpreted through our senses.

Walking meditation (kinhin) is another form that has helped get my through challenging times. Solutions, both to engineering problems as well as life obstacles, reveal themselves mid-stride. Stress relief can be induced by physical activity. Fresh air and blood flow are good for the brain. Light exercise is the necessary distraction that gives our mind space to breathe.

Mindfulness

Our senses keep us plugged into reality. They instantly create a connection to the present. Paying attention is the only way to experience this moment in life. If you’re feeling distracted, panicked, or out-of-touch with reality, try taking time to intentionally notice the things that stimulate you.

Setting out a short period of time each day to sit quietly and concentrate on your breathing might serve as a simple way to include meditation & mindfulness into your regular schedule. There are numerous styles of meditation, so it’s worthwhile to try out different techniques to determine which ones suit you.

Though they may appear unrelated, programming and meditation have more in common than you may imagine. Making meditation & mindfulness a daily habit can help you focus better, manage stress and anxiety, and become a better programmer.

Even under the richest of experiential excitement, without mindfulness there is no participation with, nor illusion of, reality. If you mindlessly read a book, you might as well have not read it. If you day-dream during a movie, you may know as much about the plot as someone who has never saw it. The same is true for life in its entirety. Don’t miss out – pay attention.

You can train yourself to get better at paying attention. The better you get at it, the more you will experience the richness of vibrancy of this world. The two best techniques I have found for this is: meditation and reading.

Reading, Writing, and Mindful Literacy for Programmers

reading and writing blogs

The benefits of reading are well documented and enumerated. If you are a programmer, reading helped get you to were you are. Of course, as with any intellectual pursuit, consuming prosaic knowledge is a pre-requisite to success.

Having the time to read, think, and write is a luxury. It’s a habit that that many people claim they can’t afford. And ironically, those are the people that could benefit from it the most. Like strength training, it is something I’ve habituated myself to do daily.

Reading makes you a better software engineer, not because of the information ingested, but because of the byproduct mental skill built as a result. Reading, regardless of the subject matter, is strength training for your mind. It is a neighbor to meditation and mindfulness in regards to brain health.

And, to make the connection explicit: if reading benefits your coding ability, then meditation does too. I’m not the only one that thinks that meditation will make you a better programmer. Reading, and writing, can be meditative pursuits that afford the benefits enjoyed by mystics and monks, engineers and enigmatics*. Consuming knowledge is, in many ways, a programmer’s primary function. Let’s delve into the realms of reading and writing that act as superpowers in molding our intellect and efficiency.

Reading

Literacy seems to date back nearly five-thousand years. It might be even older. I wouldn’t be surprised if the timeline of civilization and humanity turns out to be much longer than what is currently accepted by historians and scholars. Reading and writing are low-tech, non-electrical, super powers that define and augment what it means to be a modern human. Like meditation, reading changes the brain’s physical structure.

Reading is a skill. Even if you “know how to read”, true literacy is highly perishable. Amber Peterson from The NCTE writes, “literacy is the way that we interact with the world around us”. Following the video-game, simulation theory, analogy – being literate is the opposite of being an “NPC” in real life.

This type of literacy flexes same brain muscles as mindfulness. It is the kind of mindfulness that allows us to actually experience life, or what Sam Harris calls “waking up”. Even if you live a very long time, if you were a mindlessly zombie the entire ride, then it might as well not even have happened.

Filmmaker Stephen Apkon is quoted as saying “True literacy is always a two-way transaction. We don’t just consume; we produce. We don’t just read; we write.”

Spoken communication already feels magical. From an alien perspective, it seems I can sing sounds to export my thoughts and ideas into another person’s mind. Writing, then, is an evolution of this transcendent practice that allows brain data to be store, shipped, and unzipped without a livestream.

Listening

Audiobooks unlock a new way to consume written words. Many people find it easier than reading. I think that is because it requires less focus. If I listened to a book, can I say that I have “read” that book? My opinion is “yes”, but does that mean that I can say that I have also “read” a podcast? Do we need new terminology to better describe our world?

I can get through a publication more quickly by listening. But, does that forsake the benefits of increased focus that I discussed above? Entrepreneur Naval Ravikant tweeted, “Listening to books instead of reading them is like drinking your vegetables instead of eating them.”

I love that analogy. It’s still good for you, but there is clearly something missing. And, how Faustianly modern it is to prefer a more processed option in favor of palatability. In another tweet, Naval says, “Reading is more efficient when at rest. Audio is more efficient when in motion.”

I agree, and reserve Audiobooks for when I am moving – walking, exercising at the gym, or even driving. Brian Tracy, author and top business-speaker, said “You can become one of the smartest and most knowledgeable people in your field by turning traveling time into learning time; by turning your car into a mobile classroom,”

I first discovered this concept of a “university on wheels” around 2008 after listening to one of my first-ever Audiobooks, “The Phoenix Transformation“. Around that time I had just finished college, and was trying to figure out what to do with my life. My primary source of income was delivering pizza, so I was on the road a lot, alone in my car.

This was before smartphones were popular, and as a poor young person, I could not afford a stand-alone MP3 player. I was able to download books and other audio programs (Tony Robbins changed my life), and burn them onto blank CD-R disks. A single book might be ten CDs long. If I heard something impactful or if there was an exercise prompt by the author, I would pull over and scribble my thoughts down onto a blank “guest check” pad, sparking the origins of my hypergraphia.

a blank guest check notepad

 

Tips, Tricks, and Recommendations

I recommend reading and writing every day.  I like to have two or three physical books that I switch between at home. The Kindle app is my electronic option for when I’m out and have a few minutes to kill. My Audible account keeps multiple audiobooks queued that I can switch between at the gym or on long walks. Here is a list of the books that I listened to in 2020:

audio books read in 2020

Read multiple books, and start new ones before you’ve finished them. Don’t worry about putting a book down and never picking it up again: Life is too short to finish books that you don’t like. Audible allows audiobook returns and refunds credits for reuse.

There’s so much content available, it is hard to decide where to direct your focus. As a rule, I try to not read any new books – meaning, I won’t read material that has been recently published. As a soft rule, I like books that have been released at least five years ago.

I avoid read popular books and best-sellers. I’m excited by obscure material containing alternative, even radical, ideas. If you only read the same books as everyone else, you will only have the same ideas that everyone else is having.

Reading will make you a better writer and content producer. Niall Ferguson mentions that quality books tend to have a thousand-to-one ratio; meaning the author has read about a thousand words on the subject for every one word written.

Niall continues about the compounding benefits of reading: “You’ve got to get that reading speed up early, and then you just have to read and read and read. And it is cumulative, not only in the sense that you get better at reading, but in a fascinating way the knowledge that you imbibe from books is cumulative.”

I am a slow reader. And, I am okay with that. I spend lots of time, in between sentences, thinking and contemplating. My advice is to not try reading faster, but instead to read for longer amounts of time. Like anything worth pursuing, it is about putting the hours in. “Reading is the quiet time in which you reflect and learn,” says author Ryan Holiday.

Writing

The best reading habit that I can recommend to you is to write while you read. A professor once told me: If you don’t have a pen in your hand, you’re not really studying. It ensures that you stay focused and engaged, and trains your mind to not wander. I have mentioned before that writing is “calisthenics for the brain“.

Digital devices, like the Kindle, make it easy to highlight text and take notes.  After each page, I like to jot down a synopsis or any tangental thoughts that were sparked in the past few minutes. I don’t read fast. I record and define any unfamiliar words, and keep lists of unique phrases and idioms.

If I really like a new word, I’ll rewrite it and what it means, multiple times. Sometimes, I’ll rewrite sentences that just sound nice, or have a musical quality to them. Then, I’ll try to author my own in a similar style.

Taking notes is a challenge when I listen to audiobooks. Audible provides a feature allowing listeners to bookmark audio clips, and add text comments. Periodically, I’ll audit my collection and transcribe my favorites into a journal.

Note taking on the Audible app

Journaling To Be A Better Writer (And Programmer)

Private journaling is vital to my process of writing publicly (blogging). I write a lot of stuff that I never publish. And that is the point –  it is a personal practice that makes everything public-facing better. That idea is inspired by Kevin Kelly who has said, “I write primarily to find out what I’ve been thinking, and I don’t know until I write it”. The common wisdom is that you should think first, and then write – but to me it is obvious that the reverse is true. Spilling lots of ideas down onto a page is how I get started.

Note taking, making lists, and other kinds of journaling are powerful tools for being prolific. Learning how to make and take good notes requires practice. Simple bullet point lists are an easy way to start. Morning journal pages serve as a long-form translation of the lists I scribble mixed with a stream-of-consciousness narration. I try to write something every single day – no zero days. That’s how I get the noise out of my head. It crystalizes the nebulas storm that rages within my “monkey mind” – a concept I borrow from Tim Ferriss.

The magic always happens when I go back to old scrap and put the editor hat on. I have multiple physical notebooks, and use Evernote on my digital devices. I jot down thoughts, copy ideas while I read, write down new word definitions, and try to fill an entire page with free-flow journaling each day. Organizing all of these sources has become a series of techniques I use to keep finding inspiration.

Digesting the messy ball of words is aided by adding lots of visual cues. I use different colored pens, add drawings and doodles. I lay index cards out on an empty space and take a photo. Volume is the important variable in this quality algorithm. Getting as much down on paper as you can is always the best first step to getting value out of the writing process.

Hand written notes while studying algorithms
Hand written notes while studying computer science algorithms

A coder’s diary

Taking notes about the coding challenges you’ve solved and the technical knowledge you’ve learned cements it. Even if you never read your notes again, the act of taking pen to paper will deepen the grooves in your mental records. You should consider keeping a blog for this reason. Having an archive of your experiences expounded, with the ability to search keywords, is invaluable. I include code examples, screenshots, relevant links and quotes, and a story to add context.

That compliments my main point:  writing prose will ultimately make you a better programmer. Coding is a discipline nearer to writing then it ever will be to mathematics. That seems counterintuitive to the uninitiated.

This blog acts as my technical log that I can back reference when I encounter a familiar problem. As time passes, and new projects take hold of your attention, it’s easy to forget how you did something, even a few months ago. If you also have a similar blog about tech send me a link – I’d love to read through it!

Note Taking & Processing

There is an art and skill to note taking. It is a neighbor to journaling. When I have the urge and energy to do work, but I am not sure where to begin, I hit my notebooks as step number one.

My process has evolved. I start with physical writing as my primary note taking method. I use a notebook and I use index cards. Eventually (at least months, sometimes longer), I revisit hand-written notes and “process” them. That “process” involves re-reading and commenting on them in their existing form. I move the important (and positive) things to Evernote. I have organized my Evernote in multiple Notebooks. My pipeline looks like: index cards -> notebook -> Evernote -> blog

I use Twitter as a public diary for single sentences, ideas, and quotes that won’t fit any where else.

Since this post is a WIP (work-in-progress), I’ll leave unpolished notes below. That way I can continue refining my thoughts on this subject as time goes on.

– The psychological benefit of writing out negative feelings, and later destroying the paper. (“Burn after writing”)

– Looking back on goals. Reviewing old budgets, and feeling gratitude for where I am now

– Doodling and drawing skills

Writer Kurt Vonnegut said about his process: “When I write, I feel like an armless, legless man with a crayon in his mouth”

 

Look-and-Say in PHP

The look-and-say sequence is a series of integers. It can grow indefinitely. It is generated by reciting a number phonetically, and writing what you spoke numerically. Its popularity is attributed to famed cryptographer Robert Morris. It was introduced by mathematician John Conway. It looks like this:

1
11
21
1211
111221
312211
13112221

The first line would be pronounced as “one 1”, and then written as “11” on the second line. That record would be spoken as “two 1’s”,  giving us the third line “21”. The greatest individual symbol you’ll ever find in this consecution is a 3.

This topic has lots of trivia, variations, and history that could be dug up and expounded upon. Here, I’ll explain a solution written in PHP to produce this chain of numerals. The input will be the count of how many lines, or iterations, in the series to generate. Below is the code:

<?php

echo "Count And Say: \n";

function countAndSay($count=0){
	$value = 1; // initial seed
	for($i=1;$i<=$count;$i++){
		echo $value . "\n";
		$value = calcOutput($value);
	}
}
function calcOutput($value){
	$value = "$value";  // change it into a string, so we can iterate over each character
	$current = $value[0]; // first character
	$count = 1;
        $return = '';
	for ($i = 1; $i <= strlen($value); $i++) { // keep going until we get through the whole string
		if ($current != $value[$i] || $i == strlen($value)) { // found a different character, or end of the input string
			$return .= "$count$current";
			$count = 1; // reset count
			$current = $value[$i]; // set new current character
		} else {
			$count++;
		}
	}
	return $return;
}

countAndSay(7);

echo "\n\n";

?>

I separated my code into two functions. I think this is the best approach. As an exercise, see if you can figure out how to refactor it into one. This could help you to internalize the logic as you write it out for yourself.

The initial seed value is “1”, and that is hard-coded at the top. The for-loop iterates based on the count input parameter. That means the code circles back and re-runs, with updated values, until its internal count (represented by the variable $i ) matches the $count variable passed into countAndSay($count).

The code that we loop over outputs the current sequence value (starting with 1) as its own line (“\n” will output a new line in most programming languages) , and then calculates the next. The function that determines the next line of output, calcOutput($value), takes the current value as an argument.

The first thing we do is cast the integer value passed along into a string. This lets us refer to each character by index – starting at zero – and save it to a variable $current. We start a new $count, to keep track of how many times we see the same digit.

The next for-loop executes for the length of the $value string. On each loop, we check if the $current character we saved matches the subsequent one in that $value string. It is again referenced by index, this time based on the for-loop’s iteration count represented by the variable $i.

If it does match, one is added to the $count variable that is keeping track of how many times we see the same character is a row. If it doesn’t match (or we’ve reached the end of the input), the $count and $current number are concatenated to the $return element. At that point, the $count is reset to 1, and the $current value is updated.

Writing an algorithm to generate the look-and-say (also known as, count-and-say) sequence is a common coding puzzle. You might run into it during a job interview as a software engineer. As practice, see if you can simplify my example code, or even write it in a different programming language than PHP.

7 tips for writing as a practice

Writing is the best way to develop new ideas. It exercises our ability to explain what we mean, what we want, and why. Clear writing is clear thinking.

Putting words down is good for our mind, and is calisthenics for the brain. Forcing ourselves to build coherent, connecting streams of thought flexes mental muscles that we usually ignore. Expression and mutation are two sides of the same coin.

It’s easy to state your opinions at a high level. But once you dig into it, you might realize you haven’t thought it through. At least, not recently. Writing adds flesh to otherwise gaunt stances. It turns shape-shifting clouds into crystals with obvious foundations.

Make it a habit. Turn it into a daily practice. Here are ten tips to develop a writing routine:

  1. Spend time writing fiction. Short stories, character profiles, fantasy, and fan-fiction each count. Glue yourself to the keyboard, until you can say “That’s my story, and I’m sticking to it.”
  2. Journal daily. Type out the things for which you have gratitude. Document your feelings. Spell out your hopes. Cast a silent incantation. Craft an ancient curse. The universe is listening. I wrote a blog post about journaling, you can read it here.
  3. Don’t be a perfectionist. Put sentences down, even if you don’t like them. Keep them around, even if you hate them. But please remember, that doesn’t apply to people in your life.
  4. Everything is a work-in-progress. Revisit your posts, essays and articles. Add that literary polish and be a wordsmith. This will help keep you from trying to be perfect.
  5. Start a blog. Build in public. Let the world see how you think. Most people aren’t paying attention anyway. And if you can’t come up with something new, update existing pieces.
  6. Editing counts. Delete unnecessary sentences. Remove unneeded words. Clarify things, find synonyms, and avoid using the word “really”.
    1. When I edit, I never actually throw anything away. I borrow the “soft delete” methodology from software engineering.  I flag writing as unusable, without actually getting rid of it. That way I can revisit it, use it for subsequent ideas, and remember where my mind was.
  7. Hoard notes. Keep a physical notebook. Use a note-taking app. Bookmark stuff. Markup books while you’re reading them. Keep a stack of index cards near by for when inspiration strikes
  8. Write more than you promised yourself you would, but only if you feel like it.

 

 

My experience building digital products

digital product

When writing about digital problem solving, I tell stories about past projects. On top of a tech perspective, I also dig into the business, design, marketing, and inter-personal aspects. I’ve been fortunate enough to have a wide breadth of tech experience through my career. It has helped me dive deep into principles and ideas about building digital products. This range of experience was afforded by continually pursuing new work. Finding room for side projects and extra gigs is a great way to grow.

After a daily, hour-long commute I could barely sneak an hour or two for my creative projects and side gigs. But I always did. Side projects were often for paying clients, but sometimes just for fun. They would include not just programming, but also design, marketing, networking, and infrastructure. On top of this, I always made sure my hobbies would serve my overall goals. Reading good books, playing quality games, and being physically competitive all lead to a better life and career.

The key take-away is to work on a variety of projects. Be ready to try different technologies and new platforms. In general, keep trying new things.

Understand infrastructure. Survive some horror stories.

Web infrastructure and hosting setup are skills often missed out on by both casual programmers and professionals. Configuring domain names, email, web hosting, and load balancers is usually reserved for system administrators. Working as one-stop-shop, on your own or in a company, can give you the opportunity to manage all of these details.

I’ve gotten to work with many third-party services and vendors. I’ve seen the good and the bad, and even worse. AWS (Amazon Web Services) has been the best infrastructure provider that I have used. I’ve had horrible experiences from other companies.

Once having had my web servers infected by ransom-ware, HostGator wanted to charge nearly a thousand dollars, to solve the problem. This was the only solution they offered while multiple web properties were infected and out of commission. I fixed the issue myself in less than a few hours by purging all data from the servers and redeploying source code from version control. That was a nightmare.

Another time servers provided by OLM went down for multiple days. This was in 2014. During this time, they wouldn’t answer telephones, letting them ring. I stood on hold for at least 30 minutes, multiple times per day trying to get through. After nearly a week, things started working again, with no explanation provided. That was one of the most unprofessional experiences of my career. I will forever shout them out about this.

Get your hands dirty

Looking forward, I’m excited to explore more of AWS. I’m currently learning through online courses from Udemy: “Certified Solutions Architect” and “Certified Developer”, and plan to take the certification tests. Next, I want to jump into their “Machine Learning” and “Internet of Things” services.

I regularly use AWS services for cloud computing, storage, and databases. My go-to for a new project is to spin up a EC2 instance. If I know I’m using WordPress, I may use a Bitnami AMI. Other times, I’ll create a basic Linux box, and setup Apache, MySql, and PHP myself. Here is the documentation I regularly reference: Install a LAMP Web Server on Amazon Linux 2. This process usually includes configuring a domain name, and setting up SSL: Configure SSL/TLS on Amazon Linux 2.

I’ll continue this post as a series. I plan tell stories about my experiences in building digital products. I’ll cover topics such as design, marketing software, customization, and APIs. Follow me on Instagram for regular updates: @AntPace87

Remove subdirectories from a URL string

javascript

I use GitHub to manage code that I’ll want to re-use. I had trouble finding a canned function to remove the subdirectory path from a URL string – so I wrote one and added it to my latest public repository: https://github.com/pacea87/ap-utils

I’ll keep adding useful code to it – and feel free to make a pull request and contribute yourself. This code should focus on utility functions for manipulating data in interesting ways. Below is the JavaScript code for removing the subdirectories from a URL string. This will also strip away any query string parameters.

function removeSubdirectoryFromUrlString(url){
  
  var ssl = false;
  if(url.indexOf("https://")){
    ssl = true;
  }

  url = url.replace("http://", "");
  url = url.replace("https://", "");
  var pathArray = url.split("/")
  url = pathArray[0];
  if(ssl){
    url = "https://" + url;
  }else{
    url = "http://" + url;
  }

  return url;
}

Now, you can get the current page’s URL, and strip off everything after the host name:

var url = window.location.href;
var baseUrl = removeSubdirectoryFromUrlString(url);
console.log(baseUrl);

Another example:

var url = "https://www.antpace.com/blog/index.php/2018/12/";
var baseUrl = removeSubdirectoryFromUrlString(url);

//This will return "https://www.antpace.com"
console.log(baseUrl); 

I used this code to re-write all URL references in an iFrame to be absolute. My implementation loops through all image, anchor, and script tags on the source site. It determines if each uses an absolute reference, and if not re-writes it as one. This was part of a project that uses a visual editor to allow users to manipulate a remote site. Check out my source code below.

pageIframe.contents().find("img").each(function(){
  var src = $(this).attr("src");
  if(src && src.length > 0 && src.indexOf("//") == -1){  //if not absolute reference
    var url = iframeUrlString;
    if(src.charAt(0) == "/"){ //only do this if the src does not start with a slash
      url = removeSubdirectoryFromUrlString(url); 
    }
    src = url+"/"+src
  }
  $(this).attr("src", src);
});

pageIframe.contents().find("script").each(function(){
  var src = $(this).attr("src");
  if(src && src.length > 0 && src.indexOf("//") == -1){
    var url = iframeUrlString;
    if(src.charAt(0) == "/"){
      url = removeSubdirectoryFromUrlString(url); 
    }
    src = url+"/"+src
  }
  $(this).attr("src", src);
});

pageIframe.contents().find("link").each(function(){
  var src = $(this).attr("href");
  if(src && src.length > 0 && src.indexOf("//") == -1){
    var url = iframeUrlString;
    if(src.charAt(0) == "/"){
      url = removeSubdirectoryFromUrlString(url); 
    }
    src = url+"/"+src
  }
  $(this).attr("href", src);
});

If you liked this, check out my other post about my reusable code framework for web apps, A framework for web apps and startups.