Median of a Vector assignment
#include "../../std_lib_facilities.h"


While PPP is structured around using this header, you will eventually be including only what you really need to make your code self-sufficiently compilable.  So instead of including a bunch of libraries you don't need, just include what you use.

#include &lt;iostream&gt;
#include &lt;vector&gt;


The header Stroustrup provides also imports all visible symbols in namespace std into the global namespace.  The global namespace is then polluted with a bunch of names that could lead to collisions.  The compiler could resolve function overloads in unexpected ways.  Essentially, using namespace std; is considered bad practice.  If you must use using directives, keep the use in the narrowest scope possible.  Otherwise, qualify names with their namespace as the namespace will help the reader understand what is being called and from where.



    double median_value;


Avoid declaring variables before you need them.  This technique is an artifact of older programming languages that didn't allow initialization of variables and constants after a statement.  Errors commonly associated with this technique include use-before-set, incorrectly initialized variables, and possibly non-contextual reuse due to programmer laziness.

The simplest solution is to declare the variable as close to its initialization point.

    double median_value;
    if (temps.size() % 2 == 0)
        median_value = ...;


Even better, directly initialize the variable with a value.

    const auto median_value = median(temps);


This reduces the chance of errors happening as well as reducing the cognitive load for readers.  Directly initializing variables also allows you to take advance of const/constexpr.



    sort(temps);


Do you need to sort the entire container? When we're looking to find the median, we're only interested in picking out either the middle value or the middle two values.  Rather than sort, we would rather select.  C++ implementations typically provide introselect for its selection algorithm (std::nth_element).  

As you learn more about &lt;algorithm&gt; and iterators, keep this in mind.



        median_value = (/* ... */ + temps[temps.size() / 2 - 1]) / 2;


It's really important to keep in mind the possible states a variable can represent.  In the case of temps, that std::vector&lt;double&gt; could represent any number of doubles as well as nothing.  When temps is empty, temps.size() / 2 - 1 evaluates to 0 / 2 - 1. It's important to note that temps.size() returns size_type, an alias for an unsigned value.  Thus, subtracting one from unsigned zero results in the maximum value held by std::vector&lt;double&gt;::size_type. It's essentially a really large value almost guaranteed to be out of bounds when used in your context.  Out of bound index access is a common case of undefined behavior.

If the user doesn't provide you with values, you can't calculate a median.  temps having at least one value is a precondition for calculating the median.  Check your preconditions and notify the user if they mess up.  How you notify the user is up to you, but keep this in mind as you go over chapters on error and exception handling.



    for (int i = 0; i &lt; temps.size(); ++i) cout &lt;&lt; temps[i] &lt;&lt; ", ";


As stated before, temps.size() returns an unsigned value.  The comparison i &lt; temps.size() is a signed-unsigned mismatch.  If temps contains more values than i can represent, you'll have a bug.

If you are simply accessing the elements and don't need to apply transformations on the index, use the range-based for loop.

    for (auto temp : temps) std::cout &lt;&lt; temp &lt;&lt; ", ";