Cameras are the devices that capture and display the world to the player. By customizing and manipulating cameras, you can make the presentation of your game truly unique. You can have an unlimited number of cameras in a scene. They can be set to render in any order, at any place on the screen, or only certain parts of the screen.
| Property: | Function: |
|---|---|
| Clear Flags | Determines which parts of the screen will be cleared. This is handy when using multiple Cameras to draw different game elements. |
| Background | The color applied to the remaining screen after all elements in view have been drawn and there is no skybox. |
| Culling Mask | Includes or omits layers of objects to be rendered by the Camera. Assigns layers to your objects in the Inspector. |
| Projection | Toggles the camera’s capability to simulate perspective. |
| Perspective | Camera will render objects with perspective intact. |
| Orthographic | Camera will render objects uniformly, with no sense of perspective. NOTE: Deferred rendering is not supported in Orthographic mode. Forward rendering is always used. |
| Size (when Orthographic is selected) | The viewport size of the Camera when set to Orthographic. |
| Field of view (when Perspective is selected) | The width of the Camera’s view angle, measured in degrees along the local Y axis. |
| Clipping Planes | Distances from the camera to start and stop rendering. |
| Near | The closest point relative to the camera that drawing will occur. |
| Far | The furthest point relative to the camera that drawing will occur. |
| Viewport Rect | Four values that indicate where on the screen this camera view will be drawn. Measured in Viewport Coordinates (values 0–1). |
| X | The beginning horizontal position that the camera view will be drawn. |
| Y | The beginning vertical position that the camera view will be drawn. |
| W (Width) | Width of the camera output on the screen. |
| H (Height) | Height of the camera output on the screen. |
| Depth | The camera’s position in the draw order. Cameras with a larger value will be drawn on top of cameras with a smaller value. |
| Rendering Path | Options for defining what rendering methods will be used by the camera. |
| Use Player Settings | This camera will use whichever Rendering Path is set in the Player Settings. |
| Vertex Lit | All objects rendered by this camera will be rendered as Vertex-Lit objects. |
| Forward | All objects will be rendered with one pass per material. |
| Deferred Lighting | All objects will be drawn once without lighting, then lighting of all objects will be rendered together at the end of the render queue. NOTE: If the camera’s projection mode is set to Orthographic, this value is overridden, and the camera will always use Forward rendering. |
| Target Texture | Reference to a Render Texture that will contain the output of the Camera view. Setting this reference will disable this Camera’s capability to render to the screen. |
| HDR | Enables High Dynamic Range rendering for this camera. |
| Target Display | Defines which external device to render to. Between 1 and 8. |
Cameras are essential for displaying your game to the player. They can be customized, scripted, or parented to achieve just about any kind of effect imaginable. For a puzzle game, you might keep the Camera static for a full view of the puzzle. For a first-person shooter, you would parent the Camera to the player character, and place it at the character’s eye level. For a racing game, you’d probably have the Camera follow your player’s vehicle.
You can create multiple Cameras and assign each one to a different Depth. Cameras are drawn from low Depth to high Depth. In other words, a Camera with a Depth of 2 will be drawn on top of a Camera with a depth of 1. You can adjust the values of the Normalized View Port Rectangle property to resize and position the Camera’s view onscreen. This can create multiple mini-views like missile cams, map views, rear-view mirrors, etc.
Unity supports different rendering paths. You should choose which one you use depending on your game content and target platform / hardware. Different rendering paths have different features and performance characteristics that mostly affect lights and shadows. The rendering path used by your project is chosen in Player Settings. Additionally, you can override it for each Camera.
For more information on rendering paths, check the rendering paths page.
Each Camera stores color and depth information when it renders its view. The portions of the screen that are not drawn in are empty, and will display the skybox by default. When you are using multiple Cameras, each one stores its own color and depth information in buffers, accumulating more data as each Camera renders. As any particular Camera in your scene renders its view, you can set the Clear Flags to clear different collections of the buffer information. To do this, choose one of the following four options:
This is the default setting. Any empty portions of the screen will display the current Camera’s skybox. If the current Camera has no skybox set, it will default to the skybox chosen in the Lighting Window (menu: Window > Lighting). It will then fall back to the Background Color. Alternatively a Skybox component can be added to the camera. If you want to create a new Skybox, you can use this guide.
Any empty portions of the screen will display the current Camera’s Background Color.
If you want to draw a player’s gun without letting it get clipped inside the environment, set one Camera at Depth 0 to draw the environment, and another Camera at Depth 1 to draw the weapon alone. Set the weapon Camera’s Clear Flags to depth only. This will keep the graphical display of the environment on the screen, but discard all information about where each object exists in 3-D space. When the gun is drawn, the opaque parts will completely cover anything drawn, regardless of how close the gun is to the wall.
This mode does not clear either the color or the depth buffer. The result is that each frame is drawn over the next, resulting in a smear-looking effect. This isn’t typically used in games, and would more likely be used with a custom shader.
Note that on some GPUs (mostly mobile GPUs), not clearing the screen might result in the contents of it being undefined in the next frame. On some systems, the screen may contain the previous frame image, a solid black screen, or random colored pixels.
The Near and Far Clip Plane properties determine where the Camera’s view begins and ends. The planes are laid out perpendicular to the Camera’s direction and are measured from its position. The Near plane is the closest location that will be rendered, and the Far plane is the furthest.
The clipping planes also determine how depth buffer precision is distributed over the scene. In general, to get better precision you should move the Near plane as far as possible.
Note that the near and far clip planes together with the planes defined by the field of view of the camera describe what is popularly known as the camera frustum. Unity ensures that when rendering your objects those which are completely outside of this frustum are not displayed. This is called Frustum Culling. Frustum Culling happens irrespective of whether you use Occlusion Culling in your game.
For performance reasons, you might want to cull small objects earlier. For example, small rocks and debris could be made invisible at much smaller distance than large buildings. To do that, put small objects into a separate layer and set up per-layer cull distances using Camera.layerCullDistances script function.
The Culling Mask is used for selectively rendering groups of objects using Layers. More information on using layers can be found here.
Normalized Viewport Rectangle is specifically for defining a certain portion of the screen that the current camera view will be drawn upon. You can put a map view in the lower-right hand corner of the screen, or a missile-tip view in the upper-left corner. With a bit of design work, you can use Viewport Rectangle to create some unique behaviors.
It’s easy to create a two-player split screen effect using Normalized Viewport Rectangle. After you have created your two cameras, change both camera’s H values to be 0.5 then set player one’s Y value to 0.5, and player two’s Y value to 0. This will make player one’s camera display from halfway up the screen to the top, and player two’s camera start at the bottom and stop halfway up the screen.
Marking a Camera as Orthographic removes all perspective from the Camera’s view. This is mostly useful for making isometric or 2D games.
Note that fog is rendered uniformly in orthographic camera mode and may therefore not appear as expected. This is because the Z coordinate of the post-perspective space is used for the fog “depth”. This is not strictly accurate for an orthographic camera but it is used for its performance benefits during rendering.
This will place the camera’s view onto a Texture that can then be applied to another object. This makes it easy to create sports arena video monitors, surveillance cameras, reflections etc.
A camera has up to 8 target display settings. The camera can be controlled to render to one of up to 8 monitors. This is supported only on PC, Mac and Linux. In Game View the chosen display in the Camera Inspector will be shown.


::include_app(
knitr"https://mattkmiecik.shinyapps.io/boot-perm-app/", height = "1400px"
)
Bootstrapping and Permutation Testing: A Shiny App
We have since upgraded this shiny app to a shiny dashboard. Click here to see it!
Purpose
This post serves as a brief overview of the difference between bootstrapping and permutation testing with a shiny app to visualize their differences. The example statistic we use here is a correlation; however, these techniques can be extended to a variety of statistics (e.g., t-test, ANOVA, PCA).
Shiny App
Here’s the shiny app used to illustrate these concepts. Click here to see the app in full screen.
Bootstrapping
When you think of boostrapping, think confidence intervals. Bootstrapping samples observations with replacement without breaking the relationship between measures (e.g., X and Y). The number of samples is equal to the number of observations (i.e., sample size). After sampling with replacement is finished, the statistic of interest, such as a correlation, is computed and stored.
When you think of boostrapping, think confidence intervals.
This process explained above is then repeated hundreds or thousands of iterations resulting in a distribution of values for your statistic of interest. This distibution will be centered about the original statistical value that you computed before any resampling occured. In other words, the mean of these stored values will equal your observed statistic.
As with any distribution, you can calculate what are the lower bounds and upper bounds of values for a given percentage. This percentage is determined by the researcher/statistician/hockey analyst enthusiast and is called a confidence interval (95% is a common confidence interval). These bounds are usually reported in square brackets in the format: confidence interval % [lowerbound, upper bound]. For example, “There was a positive correlation observed between X and Y, r = .31, 95% CI [.21, .41].”
Permutation Testing
When you think of permutation testing, think of p-values. Permutation testing does not sample observations with replacement, but instead breaks the relationship between measures (e.g., X and Y). This is done by shuffling/randomizing/sampling the observed data points for one variable, while keeping the other (or others) intact. In terms of correlation, this would mean that X would be shuffled within the sample, while Y remained the original values. After the responses for one variable are randomized the statistic of interest, such as a correlation, is computed and stored.
When you think of boostrapping, think confidence intervals.
This process explained above is then repeated hundreds or thousands of iterations resulting in a distribution of values for your statistic of interest. This distibution will not be centered about the original statistic value that you computed before any shuffling occured, but rather will be centered around the null. In terms of correlation, a null distribution would center about r = 0; meaning no linear relationship between variables.
In other words, a null distribution is created by shuffling the values in X but not Y. This is because the relationship has been broken between X and Y.
A p-value is calculated by first counting the number of statistical values that are more extreme than your observed statistic. Put another way, how many times did the statistical value that emerged from a “null distribution” surpass your original computed statistic (before any shuffling). Then, you take the number of times that the null distribution is more extreme than your original value and divide it by the number of permutation iterations (number of observations in your null distribution).
For example, let’s say I ran a permutation test on a correlation of r = .5 and shuffled X, kept Y, computed their correlation, stored this value, and repeated this 100 times. Out of 100 times, there were 4 correlations that emerged that were greater than .5. Therefore, my p-value for this correlation would be 4/100 = 0.04.
Shiny App Code
Below is the code that runs the shiny app:
# Packages required ----
library(shiny)
library(dplyr)
library(ggplot2)
library(tibble)
library(purrr)
library(broom)
library(MASS)
library(modelr)
library(shinythemes)
library(shinycssloaders)
# Global aesthetics ----
# Main color palette (Flatly bootstrap theme)
<- c('#2C3E50', '#18BC9C', '#94A5A6', '#3498DC', '#F39C13', '#E74C3C')
flatlyPal
# loading spinner options
options(spinner.color = flatlyPal[1], spinner.type = 8)
# Plot constant
<- theme(plot.title = element_text(hjust = 0.5, size = 15),
plotFinish text = element_text(size = 15),
plot.caption = element_text(hjust = .5)
)
# Turning off scientific notation for p-values
options(scipen = 999)
# UI ----
# Define UI for application that draws a histogram
<- fluidPage(theme = shinytheme("flatly"),
ui
# Title
h2("Bootstrapping and Permutation Testing"),
# Author info
h4("Matthew J. Kmiecik & Ekarin E. Pongpipat"),
# Blogpost info
p("See our ",
a("blog post", href="https://mattkmiecik.com/post-Bootstrapping-and-Permutation-Testing-Shiny-App.html"),
"for more information about this shiny app."
),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
sliderInput(inputId = "rUser",
label = "Correlation (r): ",
min = -1,
max = 1,
value = .3,
step = .1,
ticks = FALSE),
sliderInput(inputId = "sampleN",
label = "Sample size (N): ",
min = 10,
max = 200,
value = 50,
step = 10,
ticks = FALSE),
sliderInput(inputId = "bootIters",
label = "Bootstrap Iterations: ",
min = 100,
max = 2000,
value = 100,
step = 100,
ticks = FALSE),
sliderInput(inputId = "ciUser",
label = "Bootstrap Confidence Interval: ",
min = .80,
max = .99,
value = .90,
step = .01,
ticks = FALSE),
sliderInput(inputId = "permIters",
label = "Permutation Iterations: ",
min = 100,
max = 2000,
value = 100,
step = 100,
ticks = FALSE),
width = "2"),
# Plots
mainPanel(
flowLayout(
plotOutput("scatterPlot") %>% withSpinner(),
plotOutput("bootPlot") %>% withSpinner(),
plotOutput("permPlot") %>% withSpinner()
)
)
)
)
# Server ----
<- function(input, output) {
server
# Defined variables
<- 2 # Minimum of 2 variables are required for correlation
vars <- rep(0, vars) # Means of all the vars are 0
mu
# Calculates sigma
<- reactive({matrix(input$rUser, nrow = vars, ncol = vars)})
re_sigma
# Establihses sigma = 1
<- reactive({re_sigma() - diag(vars)*(input$rUser) + diag(vars)})
re_sigma2
# Gathers correlations
<- reactive({as.tibble(mvrnorm(n = input$sampleN,
re_rawvars mu = mu,
Sigma = re_sigma2(),
empirical = T
)%>%
) rename(x = V1, y = V2)}
)
# Bootstrapping procedure ----
<- reactive({re_rawvars() %>%
re_bootResults ::bootstrap(input$bootIters) %>%
broomdo(tidy(lm(scale(y) ~ scale(x), .))) %>%
filter(term != '(Intercept)')})
# Confidence interval calculations ----
<- reactive({(1-input$ciUser)/2})
re_ciUserL <- reactive({input$ciUser + re_ciUserL()})
re_ciUserU <- reactive({quantile(re_bootResults()$estimate,
re_ciObs c(re_ciUserL(), re_ciUserU()))})
# Permutation testing procedure ----
# From: https://www.rdocumentation.org/packages/modelr/versions/0.1.1/topics/permute
<- reactive({re_rawvars() %>% permute(input$permIters, y)})
re_perms <- reactive({map(re_perms()[["perm"]],
re_models ~ lm(scale(y) ~ scale(x), data = .))})
<- reactive({map_df(re_models(), broom::tidy, .id = 'id') %>%
re_tidyd filter(term != '(Intercept)')})
# Calculates p value from permutation testing
<- reactive({
re_permPVal if (input$rUser >= 0) {
sum(re_tidyd()[["estimate"]] >= input$rUser) + 1)/input$permIters
(else if ( input$rUser < 0 ) {
} sum(re_tidyd()[["estimate"]] <= input$rUser) + 1)/input$permIters
(
}
}
)
# Scatterplot ----
$scatterPlot <- renderPlot({
output
# Caption for Scatterplot
<- round(cor.test(re_rawvars()$x, re_rawvars()$y)$p.value, 3)
corResP <- ifelse(corResP > .001, corResP, .001)
corResPFinal <- ifelse(corResP > .001, '= ', '< ')
pSign <- paste0('r (', input$sampleN-2, ') = ', input$rUser,
scatRes ', p ', pSign,corResPFinal)
# Plot
ggplot(re_rawvars(), aes(x, y)) +
geom_smooth(method = 'lm', se = T,
color = flatlyPal[6], fill = flatlyPal[3]) +
geom_point(color = flatlyPal[1], alpha = 2/3) +
labs(x = 'X', y = 'Y',
title = 'Scatterplot', caption = scatRes) +
theme_classic() +
plotFinish
})
# Bootstrap Plot ----
$bootPlot <- renderPlot({
outputggplot(re_bootResults(), aes(estimate)) +
geom_histogram(binwidth = .05, fill = flatlyPal[1]) +
geom_errorbarh(aes(xmin = re_ciObs()[[1]], xmax = re_ciObs()[[2]],
x = input$rUser, y = nrow(re_bootResults())/10),
height = 0, color = flatlyPal[2], size = 1) +
geom_point(aes(x = input$rUser, y = nrow(re_bootResults())/10),
size = 4, color = flatlyPal[2]) +
labs(x = 'Correlation', y = 'Frequency',
title = 'Bootstrapping',
caption = paste0(input$ciUser*100, '% CI [',
round(re_ciObs()[[1]], 2), ', ',
round(re_ciObs()[[2]], 2), ']')
+
) theme_classic() +
plotFinish
})
# Permutation plot ----
$permPlot <- renderPlot({
outputggplot(re_tidyd(), aes(estimate)) +
geom_histogram(binwidth = .05, fill = flatlyPal[1]) +
geom_vline(aes(xintercept = input$rUser),
color = flatlyPal[6], linetype = 2, size = .75) +
labs(x = 'Correlation', y = 'Frequency',
title = 'Permutation Testing',
caption = paste0('r = ', input$rUser, ', p = ', round(re_permPVal(), 5))
+
) theme_classic() +
plotFinish
})
}
# Application ----
shinyApp(ui = ui, server = server)
References
Readers who would like more theoretical or technical explanations of boostrapping and permutation testing are encouraged to read:
Efron, B. (1979). Bootstrap methods: Another look at the jacknife. The Annals of Statistics, 7(1), 1-26.
Ludbrook, J., & Dudley, H. (1998). Why Permutation Tests are Superior to t and F Tests in Biomedical Research. The American Statistician, 52(2), 127-132. doi:10.1080/00031305.1998.10480551
Wright, D. B., London, K., & Field, A. P. (2018). Using Bootstrap Estimation and the Plug-in Principle for Clinical Psychology Data. Journal of Experimental Psychopathology, 2(2). doi:10.5127/jep.013611


Video: Watch Salman Khan and Jacqueline Fernandez shaking a leg on 'Munni Badnam'
by TIMESOFINDIA.COMOn one hand where the trailer of ‘Dabangg 3’ is creating a lot of buzz, on the other hand, the video of Salman Khan and Jacqueline Fernandez dancing on ‘Munni Badnam’ is winning hearts.
In the video Jacqueline Fernandez is dressed in a pink beautiful outfit, while Salman Khan is wearing black t-shirt with blue jeans and jacket. Along with them is Maniesh Paul in black tee, jeans and wine hued jacket.
Check out the video here:
The song ‘Munni Badnam’ was featured in the first part of ‘Dabangg’, in which Malaika Arora performed.
Further, now talking of ‘Dabangg 3’, the movie is slated to release on December 20. The movie has Saiee Manjrekar as Salman’s first love and Kichcha Sudeep as his enemy.


| Drag a column header and drop it here to group by that column | |||||
| 1 2 3 4 5 6 7 8 9 10 ... 335104 items in 33511 pages | |||||
| 1 | Chai | $18.00 | 10 bxes x 20 bags | 39 | |
| 2 | Chang | $19.00 | 24 - 12 oz bottles | 17 | |
| 3 | Anyseed Syrup | $10.00 | 12 - 550 ml bottles | 13 | |
| 4 | Chef Anton's Cajun Seasoning | $22.00 | 48 - 6 oz jars | 53 | |
| 5 | Chef Anton's Gumbo Mix | $21.35 | 36 boxes | 0 | |
| 6 | Grandma's Boysenberry Spread | $25.00 | 12 - 8 oz jars | 120 | |
| 7 | Uncle Bob's Organic Dried Pears | $30.00 | 12 - 1 lbs pkgs. | 15 | |
| 8 | Northwood's Cranberry Sauce | $40.00 | 12 - 12 oz jars | 6 | |
| 9 | Mishi Kobe Niku | $97.00 | 18 - 500 g pkgs. | 29 | |
| 10 | Ikura | $31.00 | 12 - 200 ml jars | 31 |


---
layout: post
title: Programming on the Toilet
date: 2014-07-12 21:46:08.000000000 -05:00
type: post
published: true
status: publish
categories:
- Ruby on Rails
tags: []
meta:
_publicize_pending: '1'
publicize_twitter_user: bobr_az
is_reblog: '1'
post_id: '77'
blog_id: '50374290'
reblog_snapshot: "O:8:\"stdClass\":8:{s:5:\"title\";s:25:\"Programming on the Toilet\";s:4:\"type\";s:4:\"post\";s:9:\"mime_type\";s:0:\"\";s:6:\"format\";b:0;s:12:\"modified_gmt\";s:19:\"2014-03-23
12:11:48\";s:9:\"permalink\";s:67:\"http://brianslam.wordpress.com/2014/03/21/programming-on-the-toilet\";s:7:\"content\";s:4364:\"
\n\nIt's 5PM. I've been working on the same code for
hours, grinding out an implementation one line at a time. It's been a torturous
process. Some days, code just naturally flows from my brain to my fingertips.
This is not one of those days.\r\n\r\nI've been tasked with adding
new functionality to a class. \"Easy\", I thought. \"I wrote this class, so it
shouldn't be hard to figure out how to extend it.\" So, after a delicious lunch,
I sat down and started coding.\r\n\r\nThings started out all right - I had a vague
idea of how the new functionality would fit in the class. However, the deeper
I got into my implementation, the more I realized my vague idea wasn't good enough.
Functions needed access to data that wasn't available to them. I was creating
edge cases left and right, making the class much more fragile and bug-prone. On
top of that, unit tests were constantly failing when I ran my new code.\r\n\r\nI
fell deeper and deeper into the rabbit hole over the next few hours, until I could
barely recognize the code I had written. I was constantly looking at the diff
between my local code and the original to figure out what I had changed. I no
longer had a mental model of how the code worked, or how I wanted it to work.
Things soon degraded into a battle between me and my computer.  I've all but given up on finishing the feature today. \"There's no
way,\" I think. \"It would take me an hour just to untangle this mess of code.\"\r\n\r\nI
stand up from my desk in defeat, my head hanging low, and make my way towards
the bathroom. I sit down on the toilet, take a deep breath - and that's when I
obtain enlightenment!\r\n\r\n
The Throne of Inspiration
\r\n
Suddenly, I see everything clearly. Code is racing through
my mind. I can see the class, all of its functionality and its use cases. I can
see exactly where to add new code for the feature. I can see it all! \r\n\r\nI
finish my business (
wash hands before returning to work!) and rush back
to my desk to start banging out code. My fingers can't type fast enough to keep
up with the code that's rushing out of my brain. The keyboard starts losing structural
integrity as my fingers hammer it with the force of a thousand suns. The computer
and I are no longer enemies - we are the closest of allies, working together with
a common goal.\r\n\r\nThirty minutes later, the code successfully compiles. All
of the unit tests pass. I run down the list of requirements for the new feature,
and each one works as expected. \"I've done the impossible, I finished it!\"\r\n\r\nAs
I come down from my coding high, I reach a single, infallible realization:
The
most efficient programming I've done has not been in front of a keyboard, but
on a toilet.\r\n\r\n
Step Back (From Your Code)
\r\n\r\nNow, I'm
not saying that toilets have magic code-architecting properties (
although
I do think they're a great invention). However, I am saying that all but
the most trivial coding tasks will be 10x easier if you step away from your computer
and think things through at a high level. Whether it's going to the bathroom,
taking a walk to the park, or just sitting in your office kitchen, getting away
from your screen will clear your head and allow you to see the forest for the
trees.\r\n\r\nMany programmers are hesitant to step away from their desks. They
consider time spent away from an IDE to be wasted, or worry that they'll be looked
down upon. \"Why isn't he at his desk coding!? Time for that demotion,\" their
managers will say.\r\n\r\nI would argue that this logic is completely backwards
and counterproductive. Programmers are not paid to sit at a desk, or to stare
at a screen, or even to write code. These are all just steps on the way to a programmer's
real goal: to create functionality for the end-user. If you're able to create
that functionality more quickly and efficiently by stepping away from your desk,
then that's what you should be doing.\r\n\r\nIn conclusion: don't forget to use
the bathroom while coding.\r\n
\";s:15:\"images_mirrored\";i:1;}"
publicize_twitter_url: http://t.co/RvjiedTV2J
_wpas_done_7641025: '1'
_publicize_done_external: a:1:{s:7:"twitter";a:1:{i:2516516912;b:1;}}
publicize_linkedin_url: http://www.linkedin.com/updates?discuss=&scope=336165323&stype=M&topic=5893948274842292224&type=U&a=vQMg
_wpas_done_7777887: '1'
author:
login: broberts65
email<EMAIL_ADDRESS>display_name: Bob Roberts
first_name: ''
last_name: ''
---
This is so true. I usually get my epiphanies at the end of the day in the shower. :)


Narrated Abdullah bin Umar:
Allah's Apostle used to pray two rak`at before the Zuhr prayer and two rak`at after it. He also used to pray two rak`at after the Maghrib prayer in his house, and two rak`at after the `Isha' prayer. He never prayed after Jumua prayer till he departed (from the Mosque), and then he would pray two rak`at at home.


Home
About Us
Are you a Student?
Are you a Teacher?
Contact Us
Student Login
Username:
Password:
Haven't registered yet? Register here!


China Sea water transport nutrient transports data Chen Taiwan chemical East HYCOM northern Res. South Wang measured {border-style concentrations ECS kmol px;} #ffffff;} River SSH Supplementary wind Shelf Strait using speed difference seasonal values Kuroshio SCS northward respectively. variations Fig. Geophys. Zhang production southern Cont. Liu Ocean TA, TS. [], data. (Fig. . ± . Oceanogr. carbon increasing primary ratio summer DIC, N/P anomalous current differences estimated increased published range sea southward study transport, water, ./j.csr... C-TA Guo Huang TS, Yangtze depth higher highest px; regression section winter {font-family ./s--- DIC Nutrient Res.-Oceans SCS, Sci. University, area average biological concentration fluxes font-size grid.. inorganic long-term obtained overestimated phytoplankton ratios represent salinity surface (.°E, ./S-()- . ± ., . ± . mmol C Changjiang Data Department Mar. National Pearl averaged chlorophyll consistent double; flow main major monthly moving nutrients results shelf tidal total trend variability variation (Table -month ./JC China, December ECS. Fang Figure However, Jan Lin Pacific T-H Tang Yang adopted analyzed associated blooms border-color border-width derived determination different dissolved empirical evaluate excess factor formula gauging input layer level line lines parameters precision respectively satellite situ solid; station stations time used value waters {font-style {font-weight (). (see .°N; .–. CCC Carbon Commons Compared Creative Current December. Dongji Interannual Island Lee Overall, PDO Prog. S-Y Science Table Water algal article blue bold coastal coefficients courier; directly distribution em; equations gauge harmful height high http://orcid.org/--- local low lowest masses material mentioned method model monsoon northeast patterns productivity pt;} ranges related result riverine season section, series similar simulated source southerly summer, temperature times transports, transports. upwelling – m


What’s up, everyone? This is Courtland from IndieHackers.com and you’re listening to the Indie Hackers Podcast. On this show I talk to the founders of profitable internet businesses and I try to get a sense of what it’s like to be in their shoes. How did they get to where they are today, how do they make decisions both at their companies and in their personal lives, and what exactly makes their business tick? And the goal here, as always, is so that the rest of us can go on to build our own successful companies.
Today I’m talking to John Doherty, the founder of a company called Credo, which is an online marketplace which has generated many millions of dollars’ worth of marketing work for SEO experts and other marketers as well.
So John, welcome to the show and thanks so much for joining me.
Thanks for having me, Courtland. It is my absolute pleasure to be here.
It’s my pleasure to have you. I actually got the chance to finally meet you in person at MicroConf back in May. What did you think about the conference?
I thought the conference was awesome. The content was solid, the speakers were really, really good. But I would say that the thing that I took away from that the most was just that it’s one of the most valuable conferences I’ve been to in terms of just the quality of people that are there. Everyone there is smart, interesting. There’s no one that’s just kind of putting in their time at a company and looking to grow a little bit. Everyone is working really hard and creative and trying to build something of value. So I thought it was absolutely incredible.
Yeah. This was my second year going to MicroConf, and I feel the same way. They’ve done an incredible job bringing in the right kinds of people who are serious about building a business or learning how to build a business, or in many cases, already are building a business.
And I think meetups, and to a lesser degree conferences, have a reputation for attracting people who aren’t really that serious, who just want to come to mingle, but don’t want to really go anywhere with it. So hats off to Mike and Rob and everybody involved for running a conference that really attracts very high-quality people.
And I think also them splitting up the – with the growth track, which you and I were both at, which is everyone that’s doing, what is it, 150k-plus a year, something like that; and then they also had starter for a couple days after growth finished, where that was everyone looking to get started.
So I think that split it up nicely that the growth track – we could focus on growing a business and people talking about going from 20k to 80k a month – it’s like the guys from FOMO talked about – is super valuable there, versus someone that doesn’t have any revenue coming in. That’s not really going to gel for them. So it was great. I loved it.
So let’s talk about how you’ve grown your business. Can you tell us a little bit about Credo? What is it exactly, how does it work, and why do people pay for it?
So basically, Credo currently is a – the best way to describe it is a lead-generation service for digital marketing agencies and consultants. So what we do is help businesses that are looking to hire an agency or a consultant to do SEO, content marketing, link building, Facebook ads, AdWords, those sorts of things – help them to get connected up with the right agencies, continue those conversations, and then hopefully, ultimately, hire someone to help them grow their business.
I started this business five and a half years ago, which is crazy, beginning of 2013, because I saw a need. And then it kind of ticked along as a side project for a number of years, for a couple years, two and a half years, and then I started working on it full time end of September of 2015.
 I’ve been through three or four different business models, and it was a fully automated marketplace at one point. I realized that didn’t work and went back to a higher touch model. And I’ve kind of been through a lot with it, but it’s a good business, I think it fits a need in the digital-marketing industry, and it’s afforded me a good lifestyle. So I have no complaints.
Yeah, I can’t wait to get into all these details about your business model changes and your realizations and learnings.
But first, are you willing to share any numbers about the size of the company; maybe the number of employees and how much money you’re making?
Sure. I tend the run the team pretty lean. My business couch would tell you that I run it too lean. So it is myself working on it full time as well as doing some SEO consulting with some big companies. And then I have two part-time people at this point; one person kind of an admin assistant and sales development, and then a part-time developer as well.
So I run it super lean. I’m trying to grow it a little bit in that way, though still figuring out a lot of processes and roles and that sort of thing.
On the revenue side, the business right now does anywhere between about 5k a month just on the lead-generation side and the directory-listing side.
And have you raised any money, or is this endeavor entirely bootstrapped?
I have raised no money. It is entirely bootstrapped mostly from – I started this company working on it full time because I got laid off, and so I had some severance from there, and then I’ve also done consulting all along the way. And that’s basically bankrolled everything.
A lot of people have this dream of leaving their job, maybe not necessarily getting laid off, but quitting and then going to start their own company and then making multiple hundreds of thousands of dollars a year by themselves or maybe with a small team.
You’re actually living this dream. How does that feel?
It’s both a dream and a nightmare sometimes, to be totally honest with you. It’s great. I’m the master of my own domain for better or worse, I get to work from home.  And I, to a large extent, can set my own schedule and all of that, I can make decisions, no one can tell me not to do something specifically, so the world is kind of my oyster.
All that good stuff.
Yeah, exactly. But it is a lot of fun, and ultimately, at the end of the day, I love working for myself. I love not having a boss. But it also has very real challenges and ups and downs, and businesses go through different stages. And just because you’ve grown and it’s --
Managing a business that is doing – so in 2017, my business did about 350k in revenue across the lead-generation business and consulting. And managing that size of business – that was over double from the previous year, and it is so much more work to manage a business of that size as well.
You have to automate a lot of things, you have to rely on a lot of people, and make the decisions about what to invest in, who to hire, what services to pay for. For example, I pay for bookkeepers and accountants and that sort of thing so that I can actually focus on growing the business. All of those decisions become a lot harder as you grow, but at the same time, they’re growth problems and they’re good problems to have.
Yeah, those are great problems to have. So let’s talk about how you’ve actually gotten to where you are. Because from what I understand, Credo is the first business you’ve started, which is pretty unusual for the people that I talk to on the show.
What are some of the more influential life events that led you to this point?
So as you said, Credo is my first business that has ever made any revenue, it’s the first business entity I ever formed. I’ve had side projects and such and sold consulting before, and Credo actually came out of me stopping doing my own consulting back at the end of 2012. Obviously, I do my own now still.
So what got me to this point is – so I was trained as a web developer in college. I went to James Madison University in Virginia, where I’m from. And had an internship as a web developer at a software company in the Northern Virginia area summer 2007, so we’re going back a decade now, which makes me feel old.
I was trained as a frontend web developer, and then was basically helping to run a company from Switzerland for about a year, where we were selling English-language books, but we were based in French-speaking Switzerland in a bootstrapped company, myself and the founder. And basically, I had to learn how to market things online.
And so SEO just made sense, and so I basically started learning SEO and was blogging. We now call it “content marketing.” And it just kind of came to me. It just kind of made a lot of sense to me and kind of how my brain is put together.
Over the course of my career, I helped to run that company, though I wasn’t the founder and I was probably too inexperienced to really be doing it. And I’ve worked agency side. I worked for a couple different agencies and worked in-house for a couple of years as well, running SEO marketing and growth on a couple of Zillow’s sub-brands.
So I’ve built teams, I’ve grown teams, I’ve managed people, I started stuff on my own, done my own consulting. I am (inaudible) enough as a web developer. I built most of the Credo platform with myself with some help from some freelance developers.
But I think one of the biggest things that I’ve done over the course of my career is to kind of be a jack of all trades and know a little bit about a lot of things and know a lot about a couple of things.
Were you always that way? What were you like a kid? Did you think that you wanted to be an entrepreneur, be a jack of all trades, or did you fall into this because of your job?
I don’t know that I’ve really thought about it that deeply, to be totally honest with you. I was always kind of a little bit of a lazy student. I come from a family of educators. My father worked in higher education for about 30 years, and my mom is an elementary school teacher. And I was homeschooled until high school as well, so I didn’t really apply myself a ton in high school, didn’t really have specific things that I really enjoyed.
Ended up graduating top 10% in my class. I know I could have done better if I had worked harder. I could have gotten a better SAT score if I had studied harder, but I basically just figured, “Hey, I’m doing enough to get by and I’m happy.” I’ve never been that person that I’m like, “I want to have a $10-million-a-year business, or I want to get my MBA from Stanford” or something like that. Not that there’s anything wrong with either of those, but I just haven’t been that type of person, super focused in that way really ever in my lifetime.
I like learning, I like reading, and I’ve recently tried to dial that back a little bit and practice a little bit more just-in-time learning and taking care of things when they need to be done as opposed to, “This strikes my fancy now, so I’m going to do it.” But I think part of that as well is just getting a little bit older and having a business that works and having customers that are relying on me and having to be more strategic in that way.
It’s fascinating to hear you talk about how you weren’t really motivated to try very hard at school and you didn’t really give it your all, because being a solo founder and being a jack of all trades really requires a substantial amount of effort. There’s no real way that you can just phone it in. You have to try hard in order to get to where you’ve gotten.
So what I want to know is: What changed in your mindset to allow you to start and run Credo?
Yeah. I think I had to find something that I was really passionate about and that really drove me; not that necessarily I’m super passionate about generating leads for marketing agencies, but it’s something that I can do and that I can do well. And I think passion only gets you so far.
But I’ve always had a good work ethic, but it was a matter of finding something that I wanted to really apply that work ethic to, if that makes sense.
Yeah.
I didn’t love school, I don’t love having a boss, which is part of why I work for myself, so therefore I don’t really enjoy having a teacher or someone keeping me accountable to things like that.
All of those just weren’t really how I was put together. But once I actually commit to something – on my own personal website, my personal blog, I blogged twice a week every Tuesday and Thursday from the very beginning of 2011 until almost the end of 2013. So for about three years I published two blogposts a week. So I can keep at things and I can commit to things, but it has to be something that I’m really committed to doing.
It’s totally underrated how much satisfaction you can derive from just being good at things. I remember being a kid and spending a lot of time on the computer. And a lot of it was just because the adults around me were encouraging and they would say things like, “Oh, you’re really great at computers, keep it up.” And so I just took pride in getting that kind of feedback.
And it’s the same with running a business. If you find something that maybe isn’t the most interesting thing in the world, but you’re really good at it and you can take pride in being good at it, then that can keep you motivated when things get tough.
Totally. And I think for some of us, just having a problem to solve is a big driver as well. I see people up on Indie Hackers or other places launching these SaaS apps for scheduling social media posts. No one’s like, “Oh, you know what I’m really passionate about? Letting people automate their social media accounts.” No one says that. They’re like, “Hey, this is an interesting problem to solve, there’s a business opportunity here, and so I’m going to see what it can be.”
And then also especially developers are really good at building new apps and making things work. And you can always move onto something else as well. Just because you built one tool doesn’t mean that you can’t move on and do other things or expand the vision of that company, and then ultimately, shut down the thing that you started with. There are so many different ways to go with a business.
So earlier I asked you about funding Credo, and you mentioned getting laid off from you job and using your severance to fund your business. What’s the story there?
Yeah, it’s a fairly quick story. I was working inside of Zillow Group and I’d just moved over to a new brand. I’d been running marketing on one brand and moved over to another brand that they had acquired. And basically, some things moved around internally. And the team that I had brought over to that brand with me and myself ended up getting laid off near the end of 2015, end of September 2015.
So I think a lot of people have been through that with acquisitions and moving into a new role and it doesn’t work out, and it’s part of business. It’s actually interesting that a lot of people that I’ve spoken with, a lot of entrepreneurs and such as well, have also been laid off and actually started working for themselves because they got laid off.
So I think there’s something to that. Just like when I worked for an SEO agency, we found that a lot of the best SEOs that we hired had been former professional poker players. So think it’s the same way with entrepreneurs. Whenever I see a successful entrepreneur, I’m like, “When were you laid off?” And most of them have been.
Why after getting laid off did you decide to go into business for yourself? Because I think most people in that situation would feel a lot of pressure to go and look for another full-time job.
There was pressure; I didn’t have the desire. So I did interview some, and I had actually been interviewing before I got laid off as well, just kind of trying to figure out what was there. And my wife and I were based in San Francisco at the time.
But I started interviewing with some companies. And some called me back and had good conversations, had interviews, had a number of in-person interviews. I was offered three different director-of-marketing jobs in the next four to six months, something like that. And I entertained them. And it was San Francisco and they were director-of-marketing jobs. It was good salary.
But basically, my gut told me, “Don’t do it. Don’t take them. You’re not going to be happy. You might stick around for a year, year and a half.” And I didn’t really have an interest in playing the startup lottery either. You never know with companies, especially if you’re not the founder, you’re not controlling the ultimate destiny. And if you’re kind of banking on stock being worth something someday, then it’s kind of a crapshoot.
So I just didn’t really have the desire to do it. And I got laid off on a Monday and told some people on Tuesday, and by the end of that week, I had had a ton of people wanting to work with me and basically had to stop taking phone calls because I had so many people wanting me to consult with them.
 And so I didn’t and wanted to see what my business could be, and I always figured that I could go back and get a job. And I still kind of think about it that way. It’s like, “Well, if this doesn’t work out, I can start another company or I can just consult or I can go get a job.” So there wasn’t a, “I have to figure it out in the next month, otherwise I’m not going to be able to pay my bills” sort of thing. I’ve been fortunate in that way.
So I just decided it wasn’t for me, and I wouldn’t be okay with myself if I didn’t give this a go.
lots of people who are afraid or concerned about the risk involved with starting a company I think would do well to learn from your example, or even my example, where I could always fall back on my programming skills and I know I can get a job as a developer. So starting a company isn’t that scary for me.
 And so again, starting a company really wasn’t that risky or that scary for you.
Yeah, exactly. And I think that’s also the value of having a skill that you go deep in. We talked at the beginning about being a jack of all trades and knowing a little bit about a lot of things, but also having some things that I know a whole lot about; so for example, SEO. And I’ve been in SEO for almost a decade now, which is a lot of time and it’s constantly changing, and I’m not passionate. As we were talking about earlier, I’m not passionate about it like I once was, and that’s okay. But I’m good at it and I can provide a lot of value to companies doing it. And sometimes that’s all you need.
What are some of the lessons that you’ve learned from doing your consulting work? Because I think being a consultant is the perfect bridge between being an employee and running a more scalable business.
Yeah, it is. And for a little bit, the first three to four months after I got laid off, I was basically consulting full time, and then evenings and such was trying to carve out some time for getting started on Credo and fixing the site as it was at that point. It was a different brand name and kind of getting it to a point where I could do a launch. And then I did that, and then I had to go through a rebranding.
It’s really a lot of managing your time. Getting consulting clients isn’t really a challenge for me because I’m fairly well-known in the SEO world and have a specific niche type of website that I work on. And so basically, if a website that has more than 100,000 pages, that’s a pretty good brand, that’s dealing with technical SEO issues and needs a seasoned consultant to come in and kind of guide them and work with their team to get things done, I’m their guy and I know that I can close those projects.
So the lead-gen part was never hard for me and to this point hasn’t been a challenge for me. Even now I still turn people away that want to work with me directly, or I put them through Credo, so it’s nice to have that for sure. And that’s why I started the business in its first incarnation as well five and a half years ago.
It’s all about time management. But one thing that I’ve learned is it’s also really hard – once your business gets to a certain point, once your side project – let’s say like Credo was when I first started working on it, when I first went out on my own a couple years ago, it was kind of a side project that was like, “All right, let’s see if this can get going and be a bigger part of my business’s revenue.” So it was all about managing time.
But at some point, the time that you put into consulting or something like that almost becomes a liability because you have so much to do with your other business. Because okay, it’s working quite well, but maybe it’s not quite profitable. And so you cut back on consulting a little bit and revenue goes up, but then it’s not quite up enough that you’re profitable. And so you have to pick up more consulting and then business slows.
So Brian Casel of Productize & Scale talks about this quite a bit as well. And the way he kind of frames – he was at MicroConf. The way he frames it has really helped me think about it as well.
So it’s all about that time-management part there, and I pretty quickly realized I didn’t want to do just consulting. I could have easily done that. I could have easily started a traditional agency, and that’s just not the kind of business I wanted to build.
You mentioned being pretty well-known in the SEO world. A lot of other people here listening in are trying to build an audience and trying to become well-known in whatever area in which they’re an expert.
What are some of the mechanics behind how you became well-known? And is that something you fostered intentionally, or did it just sort of happen?
I wouldn’t say I really fostered it intentionally. I basically set out to make friends, and I ended up making friends with a lot of pretty influential people in the SEO world. And a lot of them are still friends of mine and people that I interact on almost a daily basis, and some of them I’ve done business with.
And business, I would say, is all about relationships but also not going into them and being like, “I’m going to meet so and so that I can become a celebrity in the SEO world or in the jQuery.” That’s not what it is. It’s actually being an interesting and nice person and looking to provide value where you can.
But I would say one of the biggest things – I mentioned that I blogged twice a week for almost three years on my personal site. And I literally just set out to teach everything that I know or that I was learning. So I gave away free tools and I wrote about different trends in the industry and wrote very specific things about link building and (inaudible) and what have you. This was 2011 to 2013. It was a very different kind of environment then in the digital-marketing world. Things have changed a lot over the last five years.
But I wrote a ton and I promoted it and people started linking to me, and so my site kind of grew over time.  The following is not that big anymore, but gained a big following on Twitter, and that enabled me to launch and kind of build Credo in its initial stages, get initial traction. So building an audience – I still think one of the best ways to do it is to teach everything that you know.
It’s perfect that you’ve got a blog and your skillset lies in SEO and marketing, because those are two of the best skills that you can use to grow a blog and build your online presence.
You mentioned that a lot of it comes down to teaching everything that you know, and I think a blog is great for that as well because it’s going to be frequented by people who don’t know what you do and are coming to learn.
But how do you flip that around and reach out to people who know more than you? How do you approach somebody who is famous or influential or someone who’s extremely knowledgeable and provide value in a way that they can appreciate?
I’d say it’s just a matter of engaging with them. Twitter is one of the best things that’s happened to me as a business. I wouldn’t say it’s one of the best things that happened to the world, but it’s been good to me. I would basically just see who’s writing interesting things, follow them on Twitter, engage with them, ask them questions, share it, ask them deeper questions, eventually take it to email. If you’re at a conference, make sure to say “hi” to them and just engage in conversation there. People can tell if you’re trying to meet them because they’re someone, or if you’re genuinely adding value across the board.
And it’s hard in the internet world. There is so much noise. And one kind of mantra that I try to live by, and I don’t always succeed in it, but basically, trying to be a real and a nice person.  But instead actually not calling someone a “jerk” or not putting personal zings into a tweet to someone when you disagree with something that they wrote in a blogpost.
And maybe that’s very soft, but I think it actually does help you to connect with people, being a nice and helpful person to them.
Totally. And I know a lot of people who get a lot of email. I get a lot of email. And I think one of the things that I’ve noticed is that people, when they reach out to others, aren’t the best at understanding how to provide value and be useful. It’s almost always like, “Can you help me do my thing?”
And one of my good friends now, Julian – he was actually on the podcast. I think he was episode number 17 or something. But he’s one of the few people who reached out to me early on when I was working on Indie Hackers. And he was like, “Hey, I see that you are starting a podcast, and I see that you’ve got sponsors. I’ve worked a lot with sponsors. Let me just give you some free tips on the best way to go about getting sponsorships and talk about how they look at things from their perspective.”
And it was so useful and valuable to me, because he actually understood what challenges I was going through and anticipated those, and then gave me all this useful information that I wouldn’t have been able to find other otherwise. And it made me really want to help him however I could as well.
So going back to what you said, being able to provide value to somebody is such a great way to build a connection. And it’s pretty rare. It’s surprisingly rare that people take the effort to do that.
Yeah, totally. And I think another thing there is emailing someone, basically asking them for their advice and not making a huge ask and expecting a huge thing back. But one thing that I like to do is email someone and be like, “Hey, I saw that you were talking about someone that’s pretty influential,” saying, “Hey, I saw that you were talking about such and such. I’ve been thinking about that for my business. Can I ask you a couple questions?”
So then they’re basically opting into it. They’re like, “Yeah, sure. Send them over.” So you send them two, three questions that don’t require a super-long answer or a long-winded answer. People are super happy to do that. I’m always amazed at how helpful some of the most influential people I know are, just because they’re like “I’ve been through it. I’m happy to share, happy to help you get to the next level and learn from my own learnings.” Then that establishes a relationship right there.
Then you can email them in the future. You can ping them interesting - something you saw or – there’s one CEO of a well-known company that, a couple years ago, I helped him out with something. From time to time I’ll see his name pop up in the news. I’d see them and be like, “Hey, I saw this. Good work,” and he’ll respond with a smiley face or something like that. It doesn’t even have to be a super deep connection. It’s not someone you’re emailing with on a daily basis or – he’s not a mentor of mine, but these are good relationships to have and they’re good, interesting people.  Because anyone worth emailing is probably somebody who’s very busy. If you can provide the necessary context for them to understand, and you can keep your email short, and you can ask questions that don’t require gigantic time investment on their part, then they’re much more likely to actually get back to you.
I think this skill set is also the skill set that you need to run a company. You need to be able to empathize with your customers and the costs that they’re going to have to pay to use your product. Similarly if you’re going to email somebody, you need to empathize with their situation and the costs it’s going to take them to answer and respond to your email.
Absolutely.
Let’s talk about how you started Credo. What gave you the initial idea to start working on this particular product? John Doherty [00:24:30] The initial idea – gosh, Courtland, this was end of 2012, so it’s been six years.
Ancient history
Yeah, ancient history. In Internet years, it’s basically a teenager now. It feels like it some days. I was working at an agency in New York City and I was doing some consulting on the side. And had gotten a promotion and my boss had left the company, so I had taken over some of those responsibilities. I had started doing some consulting while I was working at the agency because I needed a little bit of extra income. So I picked it up and was doing that evenings and weekends, and got to the point where I didn’t need that work. So decided that I wanted more time in my life.
I wanted more margin in my life. I was living in Brooklyn and was 28 years old, living in Brooklyn. I was single and spending a couple of weekends a month in my apartment by myself, doing work for clients for money that I didn’t need. So I was like, “You know what? I’m going to stop doing this.” Told my clients. They were like, “Who should we work with?” I was like, “Oh, I don’t know.”
So I had other people coming to me wanting to work with me. “Hey, I’m not taking on consulting.” “Well, who should we work with?” “I don’t know.” So I literally built out a Google Sheet of people that I knew in the industry that I trusted, and started referring work to them. I’d just email and be like, “I’m getting in all these leads. Can I refer work to you?” They were like, “Yeah, great. What do you need?” I just put together the budget levels they worked with, the size of their team, the types of services they offered, and then would introduce people to them. Then I realized that lead generation, it turns out, is a big business.
So I got in a lead that was perfect for a buddy that runs an agency in Utah, that they’d just started up about six, eight, ten months before, something like that. I emailed him and was like, “Hey, man, I just got in this lead that I think is a great fit for you. Would you be willing to pay 50 bucks for it?” He was like, “Yeah, what’s your PayPal?”
So three minutes later I had 50 bucks in my personal PayPal account. I sent him the intro and I went and bought a domain name and threw it up on some shared hosting that I had. It’s been bootstrapped and in the black since day one. But it was literally built out of a need where I wanted more time in my life, and had to solve the problem of I had people coming to me wanting me to do work for them, and I’m not doing work for them. So I didn’t just want to say “No,” I wanted to provide value there.
Why did you feel so strongly about providing value there? I think most people in your situation would have just told these people, “No.” Or they would have said, “OK, here’s a few recommendations.” But you took the time to build up this entire spreadsheet. What made you feel so strongly about helping?
It’s a great question. I honestly don’t know that I have a great answer for it. I’ve always, I think, been a helpful person and saw that these businesses had a very real need. They needed someone good.
A couple of the people that came to me had been burned by bad SEO agencies. If you know anything about the SEO world, there are obviously the more visible people and there’s the Rand Fishkins and those people that are – even though Rand is not as in the SEO world as he used to be – but there are a lot of people that are quite well known.
But there’s also this super-seedy underbelly of the industry, which you get in some industries, but others you don’t. So I was tired of people hiring a bad agency, overseas or even domestically, that at best didn’t grow their traffic and their business kind of stayed steady, and at worst, hurt their traffic. They actually ended up wasting money and also their business got smaller and all of that. I kind of wanted to solve that problem.
I think it’s fascinating, as well, to be in an industry where trust and quality are big issues. It counts so much more to be a genuinely helpful, trustworthy person. It vastly increases the number of people who want to work with you, and increases sort of the surface area of your luck as well. Because when you have these people who you help, they want to help you. That’s in a lot of ways the essence of luck. People coming out of nowhere to help you out.
Exactly. If you’re in an industry that isn’t super trusted, being someone that can be, then that’s definitely a way to set yourself apart. I wish it wasn’t. I wish there weren’t people that were doing bad work for clients. But we deal with the reality that we’re given.
I hear a lot about consulting businesses turning into product businesses. You mentioned Rand Fishkin. He’s one of the canonical examples of him creating Moz out of his consulting business. I think this happens in part because people spend so much time as consultants interacting with their clients and customers and companies that they end up unearthing these valuable problems that are worth solving.
Obviously, things don’t work out this way for everybody and some people end up never stumbling onto a good idea. So what do you think are some of the levers that people can pull on to unearth good ideas in the course of doing their normal job or their consulting work?
That’s a great, great question. The advice that’s often given is to solve your own problem. So that starts with identifying the problems that you have, and figuring out scalable ways to solve those. So let me talk about that a little bit more in detail.
What I do and what I like to tell people to do is, look at the things that you’re doing constantly. What are the things that you’re doing manually that you don’t have to do manually? Maybe this is – I think about it this way because I have a web development background and you probably think about it this way, where you’re like, “Wait, why am I doing this thing manually here?” I can store all of this information in this one place and click this one button and all of this information gets combined and gets emailed out to someone. I don’t have to copy-paste and put it into a compose window within my email and send it out. I can automate that stuff.
Basically what I’ve done is look for areas where I can streamline solutions to problems that I have. Making it more scalable that way. Then also seeing, is there a problem that somebody else has? So for me when I started Credo it was, I have all these leads coming to me and I need somewhere to send them. I also know that agencies are always looking to get not just more but also better and better-qualified leads. There was a need there and it’s something that people are willing to pay for.
I’ve come across so many – this is what most task (ph) businesses are, right? It’s something that people have been doing themselves, they’ve been doing manually and now there’s this tool, this company they can subscribe to or whatever, that’s going to help them do something better. It’s going to solve a problem that they have there. That’s one way that a lot of consultants and consulting companies can go into products, whether that’s info products or SaaS products or what have you.
But I will say that there’s a very, very real difference between running a consulting company and running a product company. It is night and day. There are things like customer support and development and sprint planning and whatever it is, all the things that go into building a product. You don’t do those in a consultancy or working directly with clients. It’s a very different sort of touch.
You have to figure out which one you’re better at and which one you enjoy more as well. Some people really enjoy going deep with clients and going on site with them, that sort of life. Other people enjoy the more scalable, having a lot of customers, all of them paying you a few dollars as opposed to having a few customers, everyone paying you a lot of money. They’re very, very different approaches.
I like what you said about solving your own problem and, in combination, making sure that other people have that problem as well, which was definitely the case for you. You had people asking for these referrals, and you also had to manage the spreadsheet yourself. That was also the case for Indie Hackers. I started Indie Hackers because I wanted to find examples of people starting these profitable businesses, and I was scouring the Internet trying to do it. Then I realized, other people are scouring the Internet too. I could see them leaving comments and see them talking about it online. So it was a problem that I had, and a problem that other people had. So I think that’s great advice and other people should follow it as well.
Let’s talk about you getting Credo off the ground, because another thing people struggle with is taking those first few steps. It’s very easy to overshoot and bite off way more than you can chew, at which point, you never really get version one of your product out the door. But with Credo you had the spreadsheet. You started off with the minimum viable product, and you charged your friend over PayPal without building much infrastructure at all. Where did you go from there? And were you ever worried about biting off more than you can chew and building some big, complex product?
I’ve definitely bitten off more than I can chew, so let’s not get confused about that. There’s definitely a lot that goes into it. Anyone that knows me will tell you that I put in a lot of hours. I don’t have to work the 90, 100 hour weeks now that I did at the beginning, but there were definitely those weeks at the beginning.
The way the narrative goes is, I got laid off end of September 2015 and said, “OK, I’m going to pick up some consulting to cover my bills.” I started working on the site. As you said, I had the Excel spreadsheet and had a web site up that was like, “Are you looking to hire an SEO agency? Get in touch with us and we’ll help you find one.” There were no public profiles or anything like that.
So the first thing I did was clean up the site, dusted off my code chops and got it back to at least something I wasn’t embarrassed to share, then figured out how to do public profiles on the site. Then did a launch on product time actually, in November of 2015. Got an initial spike in traffic and had some people coming in looking to hire.
At that point, my business model was, I listed agencies and consultants on the site for free. I vetted them out by speaking with them on the phone and asking them for a couple of their clients. I could go look at SEMrush and tools like that to make sure the numbers were going in the right direction. Then I’d list them. Didn’t really have a monetization model that way.
Once they signed contracts, then I got paid a commission for a few months on that. It wasn’t a super – it’s not a scalable business model. It’s not one that I would recommend that anyone invest in long term, unless you’re the one actually selling the work, in which case you can take a cut. You’d also have more control over actually closing projects. But it got me started.
Then from there I invested down in content marketing and started generating more leads. Then took a couple of months off of consulting to build out the first version of the Credo product, which was a marketplace where someone could come in and list their project. Eventually we built in an email system that would send the lead out, send the project out to consultants and agencies that were paying to be listed on the platform after they were vetted out, once again.
So no one’s listed unless they’ve been vetted out by me seeing a couple of their clients. Most of them I spoke with them on the phone. Even to this day, that’s how it is. I moved to this pure subscription model, simply because I was like, the lure of recurring revenue, which we all love in the Indie Hackers world. It worked and I went from – so in September of 2015, I did about $80 in revenue with the lead business. In December of that year, I did about $5,000. It had gone down to about $3,500 by that next April when I launched the membership site. I hit six figures in annual revenue, so $8,300-ish a month that September, so five months later. Then as I said, right now we’re around 20 to 25k.
You mentioned working 80, 90, 100 hour weeks in those early days. Why were you working so much? What was top of mind and what took so long? And if you could go back in time, is there anything you could do to work less? Or do you think it was necessary for you to get what you were trying to do off the ground?
I think it was necessary. I don’t know that I could have done it in another way. There were so many different things to figure out. I think I probably could have done some more research and spoken with some more people that had tried to do this sort of business in the past, and learned from them and set myself up for success better. If I could go back, I would do that. I didn’t do a lot of it at the beginning.
But as I said, I was doing a lot of consulting and I was trying to get this business going. It was kind of necessary for me. If I could go back, yeah, the things I would change would be talking to a lot more mentors, doing a lot more research on the industry and on the business models that I should have had from the start. But sometimes you really do have to dig in, and it teaches you a lot.
You’re doing a lot of things manually. I’m still a big fan of Paul Graham’s “do things that don’t scale.” But you can also only do things that don’t scale to an extent, right? Doing things that don’t scale gets you to a start, then you realize where the problems are and then you have to think creatively and build the solutions to those. So that’s how it went.
Would I do anything differently? In retrospect, hindsight is 20/20, right?  Probably would have a co-founder. Would have started building a team earlier. But I don’t regret any of it.
There’s this interesting dichotomy between learning from your own experiences and learning from other people. You mention that you would go back and talk to more mentors and talk to people who’ve done what you were trying to do, before you did it so you could learn from their mistakes. How have you shifted that balance as Credo has grown?
I do have a business coach that I’ve been working with for about a year and a half. I pay him monthly and we do a few calls a month. He’s helped me out a lot with revenue model optimization and product launches and that sort of thing. That’s something I would have prioritized earlier, though I didn’t necessarily have the revenue to hire a coach at that point. So it was mentors.
There’s definitely a difference between coaches and mentors.  So I also have those, and those have been intros through friends.
Once again, just engaging with them online. I’m always super grateful when they give me some of their time and some of their direction. Those have been some of the more influential things. But then it’s also good to have someone there, in it with you, a coach. Those people that have co-founders, I think that’s really nice as well. Just someone else to be going through it with you and – four hands is better than two.
That’s definitely, definitely changed as the business has grown. I’ve been a lot better at reaching out to people and asking for help.
Walk me through this process of finding mentors and finding a business coach. A lot of entrepreneurs neglect to do either one of these things. How did you go about finding a business coach, and what are some of the decisions that you’ve made that are better as a result of having these other people helping you out?
That’s a really good question. Unfortunately, I’m not sure I have an awesome answer. I think for a lot of people it’s a stroke of luck, and luck is hard to replicate.
The mentors I have were mostly introductions through friends. I was struggling with growing my business and, as I said, revenue was like 5K four months after launch, and then three months after that it was down, hadn’t grown at all and was actually down about 30%. I was just talking to a buddy. He was like, “You should talk to my friend Chris. I can do an email intro if he’s willing, and I bet he’d be willing to help on a call.” We did, and within about five minutes, Chris was like, “Wait, so you’re doing this and your business model is this? That’s completely wrong. This is how you should do it.” That’s why I launched the membership site and the subscription business model.
It was through talking to friends, talking to people that I trusted, and then they were willing to help me out. That’s how I got connected up with my mentors, just through connections like that. Then with a business coach, I’m running a bootstrapped business and came across this company called the Foundation, which helps people start and scale profitable businesses. One of the co-founders of that, Andy Drish, who is still my coach, he did the Bootstrapped Software Summit.
It was three days, eight interviews a day. The first one was like, people doing zero to 100k a year, people doing 100k to a million a year, then people that were doing seven figures a year in revenue. So he had it broken up like that. I discovered it one way and was like, “This is all I’m doing today.” Just watched all those interviews.  Some of them were Foundation students. A lot of them weren’t. I learned a ton. He provided a ton of value there. So I followed Andy, went to his blog and found some of the stuff he had been writing and subscribed to his email list.
He has a smart email follow-up that I’ve implemented. It’s like, “Hey, Andy here. Curious why you subscribed. Hit reply and let me know.” Just straight-up, plain text. I responded and was like, “This is who I am and this is what I’m doing. This is why I subscribed, because I came across the Bootstrapped Web Summit.” He responds. He’s like, “I’m starting to do some consulting and really good at helping people go from 100k a year to 700k a year in revenue. Would you be interested in chatting?”
I’m like, “Yeah, absolutely.” I was open to it and didn’t know where to go with my business. He’s helped me get to the next level. I found the person that is good at doing exactly what I was trying to do that was also two, three steps ahead of me in their career, in their entrepreneurship journey. Then just connected with them. Subscribed to their email list and started interacting with them and it led to him being my coach for the last 18 months.
Obviously you have a lot of knowledge as a marketer and an SEO expert. That’s played into how you’ve grown your company. What are some of the bigger milestones and some of the inflection points in how Credo’s revenue has grown and how you’ve improved your business? You mentioned one being talking to your first mentor, who suggests that you switch business models. Are there any more like that?
There are a couple. First one was when I first launched the membership site, it’s still a membership on the site to be listed and to receive work from me. Once again, after they’re vetted out. I initially had a self-serve model, and I had three different pricing models and people could sign up and – whenever you launch something, you get a couple early adopters and then it troughs and dies out a bit. It had done that, and I was getting people applying that weren’t necessarily a good fit.
So I was like, “I should add some friction into here and make them apply. Then I’ll hop on the phone with them, and if you’re approved then I can send them how it works and send them a link to sign up.” I did that and the number of people applying jumped immediately. I actually got to have conversations with people, could figure out if someone was going to be a good fit. Then I also had their information and that relationship. I could follow up with them if they didn’t sign up, and make sure everything was going well.
So that was weirdly an inflection point. I added friction to the process of signing up and paying me. And it worked really well. Your mileage may vary with that tactic or with that strategy.
The other one was, I realized that jobs were not closing, jobs being submitted to the marketplace functionality weren’t really working. Those jobs weren’t closing with agencies. I decided to go back to the high-touch model of talking to people that are looking to hire someone and going deeper with them. “What are your needs? What’s important to you in an agency or consultant?” and that sort of thing. That’s also been another inflection point. With that, I raised my prices as well.
So I have fewer customers that I’m sending leads to actively, sending projects to actively. But they’re all much happier and my business is more profitable. And it doesn’t take a ton of time. I don’t have a hundred people paying me, expecting x number of leads or x amount of budget in new leads per month. It’s much fewer and I’m able to provide them a better service.
In both of those cases, you weren’t afraid to add friction. You weren’t obsessed with scalability until you injected yourself into this process. In a way, it made you a bottleneck for sure. But also, because you’re charging a high enough price point, it didn’t really matter. You could still run a profitable operation.
A lot of us, especially developers and product people, we’ve become obsessed with scalability. We end up adding feature after feature and lowering the price to something crazy, like $5 a month in hopes that we’ll make it up in numbers. That leads to all sort of customer support nightmares and scalability headaches. Often it’s better to charge more and then you don’t have to worry so much about scalability and you can provide better service to customers by being part of the experience yourself.
Totally. It definitely does help. I’m definitely still a bottleneck, but I think all founders are. When you create that margin in your business, it enables you to do great things like hire people that are better at things than you are. I think that’s a great point.
No one ever built a million dollar company or a multi-million dollar company by charging people five dollars a month. Even the ones that might have that cheap starting tier, like Buffer. I think theirs is ten bucks a month, something like that. They may have raised that. But they have enterprise levels that I’m sure they charge a lot more.
There’s more friction there, but it’s also because I’m adding a lot more value and people are willing to pay for that. Because of that, I don’t experience the churn that a low price SAS business that’s kind of a utility and something that’s not necessary for them to grow their business.
I mentioned that developers have this weakness of focusing too much on the product, too much on the code. Do you think that coming from a marketing background, you have an analogous weakness or bias that you need to counteract as a founder?
Absolutely. Credo is definitely a marketing first company, which is good in one way, in that you generate the audience, then you’re like, “What needs am I solving? What needs am I not solving?” Then you can move to that. But I will de-prioritize product development and that sort of thing. I de-prioritize design and all of that. That’s probably hurt my company. Like all founders, it’s your baby and you have hard time trusting people and hiring good people. That’s something that founders all deal with, and definitely something that I’ve dealt with as well. Hopefully gotten a bit better at it in the last year or so.
Prioritization is tough. You talked about this when you talked about starting your consulting business, about how much better you needed to get at prioritizing in order to be able to run your business efficiently.
A lot of people when they hear terms like time management, they think about how do they maximize the amount of time they spend working and minimize the amount of time they don’t spend working, the amount of time they spend distracted. But in reality they should be thinking about how to be more efficient with the time they do spend working, because there’s in any given time, an infinite number of things you can choose to do. Most of them aren’t that helpful.
Even among the things you can do for your business that are helpful, some of them are ten or a hundred or a thousand times more helpful than other things. So it’s not just about working more. More important than that, it’s working on the right things. How do you decide what the right things are to work on for Credo?
Things that I like to work on? I wish I could spend all day writing. You (inaudible) learn marketing, but there’s a lot of operations stuff that has to happen. I’ve had different people in those roles, trying to backfill some of them so that I can focus on the things that I’m better at, doing better at customer development or persona development, figuring out what are the true needs of the people coming to the site. Who is our audience actually and what are they looking for?
As you said, it’s very easy to get bogged down. One thing I’ve learned from, I believe it was the 4-Hour Workweek, or maybe something else that Tim Ferriss wrote, was I have a three times a day reminder on my calendar. It says, “Are you being productive or just busy?” Are you actually doing things that are going to move the business forward, or are you just doing things that you can do? Not that there’s anything wrong – you have to do those things, right? If your business isn’t going to go anywhere without doing them, you have to do it.
But it reminds me to think, “Where do I want this business to go? Are the things that I’m working on the highest leverage things?” If not, and I’m not able to stop doing the things, and we can’t just overall as a business stop doing the things I’m currently working on, how do I hire someone else to do that so I can focus on the productive things? I can focus on the things that are going to move the business forward. It’s a constant sense check there.
I think about things similarly with Indie Hackers. I’ve got all these tasks for maintaining the status quo and keeping the business running, just staying afloat. Then I’ve got these impactful tasks, which rather than just moving me along the same trajectory, have the potential to shift me onto an entirely better trajectory.
What are the impactful tasks that you are considering for Credo, and what’s going to have to change to shift you from making several hundred thousand dollars a year to making a million dollars or more per year?
I need to hire a good team. I need to hire people that are really good at sales and sales development and that sort of thing, so that I can focus on audience development and the things that I’m really good at. That’s the number one thing that’s keeping me from being able to grow at this point. So it’s something that I’m actively working on, working on becoming a better manager and defining the roles that I’ll need to have.
It’s that and it’s also, as I’ve alluded to, meeting the needs of the customers or the audience. Whether that’s – by the time this comes out, this will be launched. I’m launching a full time digital marketing jobs board, because people are always like, “Can you help me find a full time SEO manager?” I’m like, “I’m not a recruiter, right?” But people want to be able to advertise to an audience, like the 20,000 plus marketers I have coming to my site every month. So I’ll provide that.
There are other things like that. There’s education stuff and that sort of thing that’s still expanding revenue channels as well.
We are approaching the end of our time here. I have so much more I want to ask you, but why don’t I close out by asking what your advice is for other people who might not have taken the plunge yet but who want to be a founder in the same way that you are? How can they learn how to hire and manage people? How can they learn how to prioritize well and wear all the hats that come with being a founder?
I kind of alluded to this earlier with mentors and such. Find the person that has done this before and read everything they’ve put out. If they’ve put out YouTube videos, watch those YouTube videos. If they write blog posts, read those blog posts. Learn as much as you can, then reach out to them with specific questions. That’s how you get better at it.
Then you have to go out and implement it. There’s no substitute for hard work, unfortunately. It’s all about going out and chipping, as Peter Lovels likes to say, what are the five things that are going to move your business forward the best? Chipping, chipping, chipping, chipping and chipping. You have to keep on shipping. You have to keep on learning and getting new things out there and getting that feedback.
Thanks so much, John, for joining me on the show. Can you tell listeners where they can go to learn more about you and the things you’re working on at Credo and also what’s going on in your personal life if you share that stuff?
For sure. My website is getcredo.com, g-e-t-c-r-e-d-o dot com. The best place to get in touch with me personally is on Twitter. Twitter.com/dohertyjf. My personal website, which I blog about once a month right now, more entrepreneurship related topics, is JohnFDoherty.com.
Thanks so much for coming on the show, John.
Thanks, Courtland.
If you enjoyed listening to this conversation and you want a really easy way to support the podcast, why don’t you head over to iTunes and leave us a quick rating or even a review? If you’re looking for an easy way to get there, just go to IndieHackers.com/review and that should open up iTunes on your computer. I read pretty much all the reviews that you guys leave over there, and it really helps other people to discover the show, so your support is very much appreciated.
 It’s a great place to get feedback on pretty much any problem or question that you might have while running your business.
If you listen to the show, you know that I am a huge proponent of getting help from other founders rather than trying to build your business all by yourself. So you’ll see me on the forum for sure as well as more than a handful of some of the guests that I’ve had on the podcast.
If you’re looking for inspiration, we’ve also got a huge directory full of hundreds of products built by other Indie Hackers, every one of which includes revenue numbers and some of the behind-the-scenes strategies for how they grew their products from nothing.
As always, thanks so much for listening and I’ll see you next time.


Linear Programming - Simplex method
Slide URL: ?
Wei Zhong
Introduction
Dantzig's simplex algorithm (not to be confused with Nelder–Mead' simplex method) is a popular algorithm for linear programming.
It was developed by George Dantzig when he solved two open statistics problems listed by his advisor on the blackboard, at that time he had mistaken the unsolved problems for homework after arriving late to the lecture.
Problem definition
In optimization problems, linear programming is a special case of convex optimization where the objective function is linear and the constraints consist of linear equalities and inequalities.
$$ \left\{ \begin{array}{llr} \min & z = c^T x & \\ s.t. & Ax \le b & (\text{standard form}) \\ & x \ge \zeros \end{array} \right. $$Example
Every week it is suggested to consume at least 16800KJ energy and 75g protein, you want to stay one week at home just eating snacks, what to buy in order to minimize the price?
| Snacks | Energy (KJ) | Protein (g) | Price |
|---|---|---|---|
| Potato chips | 668 | 1.5 | 6.8 |
| Cherry pie | 883 | 1.2 | 2.7 |
| Snacks | Energy (KJ) | Protein (g) | Price |
|---|---|---|---|
| Potato chips | 668 | 1.5 | 6.8 |
| Cherry pie | 883 | 1.2 | 2.7 |
$$ \left\{ \begin{array}{llr} \min & z = 6.8x_1+2.7x_2 & \\ s.t. & 668x_1+883x_2 \ge 16800 \\ & 1.5x_1+1.2x_2 \ge 525 \\ & x \ge \zeros \end{array} \right. $$
Geometry point of view
$$ \left\{ \begin{array}{llr} \min & z = 6.8x_1+2.7x_2 & \\ s.t. & 668x_1+883x_2 \ge 16800 \\ & 1.5x_1+1.2x_2 \ge 525 \\ & x \ge \zeros \end{array} \right. $$
What if you have more choices?
(rather than chips and pie)
Everything starts from Canonical form
$$ \left\{ \begin{array}{llr} \min & z = c^T x & \\ s.t. & Ax \color{red}{=} b & (\text{canonical form}) \\ & x \ge \zeros \end{array} \right. $$
The matrix $A_{m \x n}$ is full-rank, and we can write $A$ in a form such that it separates its basis and non-basis: $A = \mat{B & N}$, similarly $c^T = \mat{c_B^T & c_N^T}$ and $x = \mat{x_B \\ x_N}$.
Reformulate
$$ \begin{align} && \mat{B & N} \mat{x_B \\ x_N} &= b \\ \Leftrightarrow && x_B + B^{-1} N x_N &= B^{-1} b \\ \tag{1} \end{align} $$
$$ \begin{align} && z &= c^T x = c_B^T x_B + c_N^T x_N \\ \Leftrightarrow && &= c_B^T (B^{-1} b - B^{-1} N x_N) + c_N^T x_N \\ \Leftrightarrow && &= c_B^T B^{-1} b - c_B^T B^{-1} N x_N + c_N^T x_N \\ \Leftrightarrow && &= c_B^T B^{-1} b - (c_B^T B^{-1} N - c_N^T) x_N \\ \tag{2} \end{align} $$
Reformulate
To make the form pretty, introduce new notations $\bar{A}$ and $\bar{b}$:
$$ \left\{ \begin{align} \bar{A}_{m \x n} &= B^{-1} A = B^{-1} \mat{B & N} = \mat{E & B^{-1} N} \\ \bar{b}_{m \x 1} &= B^{-1} b \end{align} \right. $$
Using this notation, we can rewrite equation (1) and (2)
$$ \begin{align} \tag{3} z &= c_B^T \bar{b} - \big( c_B^T (B^{-1} N) - c_N^T \big) x_N = c_B^T \bar{b} - \sum_{j=m+1}^n \left( c_B^T \bar{A_j} - c_j \right) x_j \\ \tag{4} \bar{A} x &= \mat{E & B^{-1} N} \mat{x_B \\ x_N} = \bar{b} \end{align} $$
Reformulate
To simplify (3) a little bit, imagine a vector $\xi^T$
$$ \mat{0 & \dots & \underbrace{0}_{\text{#m element}} & \overbrace{c_B^T \bar{A}_{m+1} - c_{m+1}}^{\text{#m+1 element}} & c_B^T \bar{A}_{m+2} - c_{m+2} & \dots & c_B^T \bar{A_{n}} - c_{n}} _ {1 \x n} $$
so that (3) can be rewritten as
$$ z = c_B^T \bar{b} - \xi^T x \tag{5} $$
Reformulated form - Simplex algorithm input
$$ \left\{ \begin{array}{llr} \min & z = c_B^T \bar{b} - \xi^T x & \\ s.t. & \bar{A} x = \mat{E & B^{-1} N} \mat{x_B \\ x_N} = \bar{b} \\ & x \ge \zeros \end{array} \right. $$
After selecting a "basis", the we can solve a $x_B = \bar{b}$ and $x_N = \zeros$ (uniquely) so it satisfy above constraints as long as $\bar{b} \ge \mathbf{0}$ (i.e. "feasible").
We call this solution $\bar{x}$ a basic feasible solution (BFS) $$ \tag{6} \bar{x} = \mat{\bar{b} \\ \mathbf{0}} \text{ and we may assume } \bar{b} \ge \zeros $$
What is the benefit of this reformulated form? (we are done if $\xi^T \le \zeros$)
Convert to reformulated form (an example)
$$ \left\{ \begin{array}{ll} \min & z = x_1 + x_2 - 3x_3 \\ s.t. & x_1 - 2x_2 + x_3 \le 11 \\ & 2x_1 + x_2 -4x_3 \ge 3 \\ & x_1 - 2 x_3 = 1 \\ & x \ge \zeros \end{array} \right. $$
introduce slack variables $s_4, s_5$ and artificial variables $a_6, a_7$,
$$ \left\{ \begin{array}{lrll} \min & z = x_1 + x_2 - 3x_3 &+ M(\color{red}{a_6 + a_7}) \\ s.t. & x_1 - 2x_2 + x_3 & & \color{red}{+ s_4} && &= 11 \\ & 2x_1 + x_2 -4x_3 &- \color{red}{s_5} && \color{red}{+ a_6} & &= 3 \\ & x_1 - 2 x_3 & &&& \color{red}{+ a_7} &= 1 \\ & x, \color{red}{a, s} \ge \zeros \end{array} \right. $$
If for some $k$, there is $\xi_k > 0$
Find a scalar $\theta > 0$ and a vector $\Delta$, we are hoping $c^T(\bar{x} + \theta\Delta) < c^T \bar{x}$, which implies $c^T \Delta < 0$
$$ \begin{array}{lrl} \tag{8} \text{how about} & c^T \Delta &= - \xi_k \\ \Rightarrow & \mat{c^T_B & c^T_N} \Delta &= - (c_B^T \bar{A}_{k} - c_{k}) \\ \Rightarrow & \Delta &= \mat{-\bar{A}_{k} \\ 0 \\ \vdots \\ 0 \\1 \\0 \\ \vdots } = \mat{- \bar{A}_{k} \\ \zeros} + e_k \end{array} $$
Is $(\bar{x} + \theta\Delta)$ a BFS?
For equality constraints
$$ \begin{align} & A(\bar{x} + \theta \Delta) \\ =& A\bar{x} + \theta \mat{B & N} (\mat{- \bar{A}_{k} \\ \zeros} + e_k) \\ =& A\bar{x} + \theta \mat{B & N} (\mat{- B^{-1} {A}_{k} \\ \zeros} + e_k) \\ =& A\bar{x} + 0 = b \end{align} $$
Is $(\bar{x} + \theta\Delta)$ a BFS?
For inequality constraints (feasibility), it requires
$$ \bar{x} + \theta \Delta = \mat{ \bar{b} \\ \zeros} + \theta\mat{- \bar{A}_{k} \\ \zeros} + \theta e_k = \mat{\bar{b} - \theta \bar{A}_{k} \\ \zeros} + \theta e_k \ge \zeros $$
Is $(\bar{x} + \theta\Delta)$ a BFS?
For still being corresponding to a basis (linear independent), if we assume the resulting $A_1, A_2, ... A_{r-1}, \color{red}{A_k}, A_{r+1}, ... A_m$ is linearly dependent, then there exits some coefficients $y_i$ such that $A_k = \sum_{i=1, i\neq r}^m y_i A_i $.
On the other hand, because
$A_k = B(B^{-1}A_k) = \mat{A_1 & A_2 ... A_m} \mat{\bar{A}_{k,1} \\ \bar{A}_{k,2} \\ ... \\ \bar{A}_{k,m}}$.
Subtract two equations above, we get
$ 0 = \bar{A}_{k,r} A_r + \sum_{i=1, i\neq r}^m (\bar{A}_{k,i} - y_i)A_i $.
Since $\bar{A}_{k,r} > 0$, it follows $A_1, A_2 ... A_m$ are linearly dependent, we see contradiction.
Simplex Tableau
We will show the iteration of step into lower solution can be represented and done using only elementary row operations in a table called "Simplex Tableau"
$$ \begin{array}{c|c} \qquad \xi^T \qquad & z_0 = c_B^T \bar{b} \\ \hline \bar{A} & x_B = \bar{b} \\ \end{array} $$
The first row is called "objective row". Notice the $\xi^T_B = \{c_B^T \bar{A_{j}} - c_{j} \}_j = \{ -c_j \}_j$ if we manage to get a basis where $c_B^T = \zeros$ by using artificial variable.
Simplex Tableau - Pivoting in $\bar{A} | \bar{b}$
At some iteration, we have fixed on pivot point $k, r$, and $t$ represents the other rows in $\bar{A} | \bar b$.
Perform elementary row operations to make $\bar{A}_{k,r} \leftarrow 1$ and $\forall t \neq r, \bar{A}_{k,t} \leftarrow 0$:
$$ \begin{array}{c|c} \ldots \xi^T_k \ldots & z_0 \\ \hline \vdots & \vdots \\ \bar{A}_{k,r} \leftarrow \bar{A}_{k,r} \times \frac 1 {\bar{A}_{k,r}} = 1 & \bar b_r \leftarrow \bar b_r \times \frac 1 {\bar{A}_{k,r}} = \theta \\ \vdots & \vdots \\ \bar{A}_{k,t} \leftarrow \bar{A}_{k,t} -\bar{A}_{k,r} \frac {\bar{A}_{k,t}} {\bar{A}_{k,r}} = 0 & \bar b_t \leftarrow \bar b_t - \bar b_r \frac {\bar{A}_{k,t}} {\bar{A}_{k,r}} = \bar b_t - \theta \bar{A}_{k,t} \\ \vdots & \vdots \\ \end{array} $$
The updated RHS becomes $\bar{x} + \theta\Delta$ (notice at r-th row in RHS, the exiting variable gets dropped and replaced by the entering variable).
Simplex Tableau - Pivoting in objective row
Perform a column swap to move identity matrix to the left-most (notice that, column swaps produces a new simplex tableau that is equivalent to the original problem)
$$ \begin{array}{cccccccccc|c} 0 & ... & \xi_k & \dots & 0 & \xi_m & ... & \xi_j & ... & \xi_n & z_0 \\ \hline 1 & & & & & &&&&& \\ & \ddots & & & & \bar{A}\new_m & ... & \bar{A}\new_j & ... & \bar{A}\new_n & \bar b\new \\ & & 1 & & & &&&&& \\ & & & \ddots & & &&&&& \\ & & & & 1 & &&&&& \\ \end{array} $$
Apply row operation again, this time we want to zero the objective row elements who are on top of the identity matrix, i.e., we multiply $-\xi_k$ and add onto the objective row... $$ \left\{ \begin{array}{lrlr} \xi_j &\leftarrow &\xi_j - \mat{0 & ... & 0 & \xi_k & 0 & ... & 0} \bar{A}\new_j &= \xi_j - \xi^T_B \bar{A}\new_j & j > m\\ z_0 &\leftarrow &z_0 - \mat{0 & ... & 0 & \xi_k & 0 & ... & 0} \bar{b}\new &= z_0 - \xi^T_B \bar{b}\new & \\ \end{array} \right. $$
Simplex Tableau - Pivoting in objective row (2)
In order to know if the updates in previous slide would work to the next iteration, let us think $z$ as a variable, since initially $z + \xi^T = z_0$, we can think the tableau is actually representing: $$ \mat{ 1 & \qquad \xi^T \qquad \\ \hline \zeros &\bar{A} } \cdot \mat{ z \\ \mathbf{x} } = \mat{ z_0 \\ \mathbf{\bar{b}} } $$ thus the previous row operations would not stop the equation $ z + \xi^T x = z_0 $ holding true.
Now apply the same derivation in (1) and (2): $$ \begin{align} && z + \xi^T x &= z_0 \\ \Rightarrow && z + \xi_B^T (\bar{b}\new - \bar{A}_N\new x_N) + \xi^T_N x_N &= z_0 \\ \Rightarrow && z + (\xi_N^T - \xi_B^T \bar{A}_N\new) x_N &= z_0 - \xi_B^T \bar{b}\new \\ \Rightarrow && z + \mat{\zeros & \xi_N^T - \xi_B^T \bar{A}_N\new} \mat{x_B \\ x_N} &= z_0 - \xi_B^T \bar{b}\new \end{align} $$
You might find $\xi_N^T - \xi_B^T \bar{A_N}$ is exactly updated $\xi^T$, and $ z_0 - \xi_B^T$ is the updated minimal value, and this similar form will keep previous method still working in the next iteration.
Implementation
URL: https://github.com/t-k-/simplex-method
Program run
Example
$$ \left\{ \begin{array}{lrll} \min & z = & -x_2 & +2 x_3 & & & \\ s.t. & x_1 +& -2 x_2 & + x_3 & & &= 2 \\ & & x_2 & -3 x_3 & +x_4 & &= 1 \\ & & x_2 & - x_3 & & +x_5 &= 2 \\ &&&&& \vec x &\ge \zeros \end{array} \right. $$
[ x1 x4 x5 x2 x3] [[ -0.000 -0.000 -0.000 1.000 -2.000]] [[ 0.000]] [[ 1.000 0.000 0.000 -2.000 1.000]] [[ 2.000]] [[ 0.000 1.000 0.000 1.000 -3.000]] [[ 1.000]] [[ 0.000 0.000 1.000 1.000 -1.000]] [[ 2.000]] k = 3 (entering), r = 1 (exiting), theta = 1.000000
Example (Cont.)
## Iteration 1 [ x1 x2 x5 x4 x3] [[ 0 0 0 -1 1]] [[ -1]] [[ 1 0 0 2 -5]] [[ 4]] [[ 0 1 0 1 -3]] [[ 1]] [[ 0 0 1 -1 2]] [[ 1]] k = 4 (entering), r = 2 (exiting), theta = 0.500000
## Iteration 2 [ x1 x2 x3 x4 x5] [[ 0 0 0 -1/2 -1/2]] [[ -3/2]] [[ 1 0 0 -1/2 5/2]] [[ 13/2]] [[ 0 1 0 -1/2 3/2]] [[ 5/2]] [[ 0 0 1 -1/2 1/2]] [[ 1/2]] optimal!
Unbounded example
\begin{alignat}{2} \min\quad &-x_1 – x_2& \\ \mbox{s.t.}\quad & x_1 – x_2 &\leq{1} \\ -&x_1 + x_2 & \leq{1}\\ & x_1, x_2 &\geq{0} \\ \end{alignat}
Unbounded example (Cont.)
## Iteration 0 [ x3 x4 x1 x2] [[ 0 0 1 1]] [[ 0]] [[ 1 0 1 -1]] [[ 1]] [[ 0 1 -1 1]] [[ 1]] k = 2 (entering), r = 0 (exiting), theta = 1.000000
## Iteration 1 [ x1 x4 x3 x2] [[ 0 0 -1 2]] [[ -1]] [[ 1 0 1 -1]] [[ 1]] [[ 0 1 1 0]] [[ 2]] k = 3 (entering), no lower bound!
Complexity
In each iteration, since $A_{m \times p}B_{p \times n}$ takes $O(mpn)$, and $A^{-1}$ takes $O(m^3)$, the dominate part is line#38 (last line) where the complexity is $O(m^3 + m^2n)$.
In terms of number of iterations, the worst-case complexity is exponential. Because the number of vertices is equal to choosing $m$ basis from $n$ variables, $n \choose m$ reaches maximum if $m = \lceil \frac n2 \rceil \text{ or } \lfloor \frac n2 \rfloor$ depending on even or odd, it is exponential because $2^{n/2} < \binom{n}{n/2} < 2^{n}$ holds.
Nevertheless, the simplex method is very efficient in practice, generally taking small constants polynomial time with regarding to the number of equality constraints, and converging in expected polynomial time for certain distributions of random inputs (Nocedal and Wright 1999, Forsgren 2002).