Collatz Conjecture (c++)
Good job checking the input for validity and breaking up the logic into simple functions! However, some improvements can be made.

Avoid using namespace std

This can cause name collisions because it adds every name in the std namespace to the global namespace. For a small program like this one it's unlikely that you'll run into any problems (then again, maybe not) but it's best to get into the habit of using the std:: prefix on names in the std namespace.

Alternatively, you can introduce using declarations like using std::cout; to add specific names to the global namespace.

Avoid std::endl in favor of \n

std::endl flushes the stream, which can cause a loss in performance. In some cases you can also reduce calls to operator&lt;&lt; (e.g. cout &lt;&lt; endl &lt;&lt; "Finished!" &lt;&lt; endl; becomes cout &lt;&lt; "\nFinished!\n";).

Simplify your boolean expressions

You can remove some of your explicit return true and return false statements by returning the expression in the if condition. For example, you can shorten isEven() like so:

bool isEven(int num) {
  return num % 2 == 0;
}


Similarly, you can shorten isValid().

Don't mix logic and writing to cout in calculate()

Currently calculate() is not very reusable since it writes to cout. What if you wanted to write to a different stream, or if you just wanted to calculate the next term in the sequence without writing to any stream? I suggest redefining calculate() to simply return the next term in the sequence:

int next(int prev) {
  if (isEven(prev))
    return prev / 2;
  else
    return prev * 3 + 1;
}


Then in main() you can output each number returned by next() to cout, as well as check for the condition in which the term equals 1. You would replace the calculate(input); statement in main() with something like this:

while (input != 1) {
  input = next(input);
  std::cout &lt;&lt; input &lt;&lt; " ";
}

std::cout &lt;&lt; "\nFinished!\n"