Welcome to Introduction To Programming. My
name is Steven
And my name is Sean.
Over the next 90 minutes, we’ll be taking
you through this series consisting of 21 different
segments that hope to cover the basics of
computer programming, which can apply to any
and all programming languages you might want
to learn. We’ll be starting with the simplest
question of what is programming, and from
there will be working our way up as we talk
about common features of computer science
such as loops and arrays. We’ll discuss
how to read and write code, debug code you’ve
written, some strategies to help plan out
your code, and much, much more. The complete
list of topics that are going to be covered
in this lecture-style video are shown on the
screen now. Additionally, there will be time-stamps
in the description, so feel free to skip around
if you are already proficient in some areas
of computer science, or just want to know
about a specific topic we will be covering.
Hopefully, by the end of the series, you’ll
have a basic understanding of what computer
science is, along with an armory of useful
skills that will help you unravel whichever
programming language you decide to learn first.
We’ll only be covering the major key points
that apply to all programming languages, so
we’ll be shying away from topics such as
object-oriented coding and command line navigation,
as those are things which are language-specific.
Additionally, there will be no software required
for you to download in order to follow along
with this tutorial as we won’t be writing
any code to keep things simple and concentrated.
This video is meant for those who are interested
in computer science and programming but have
no idea where to start and have little to
no background information on coding, and so
if that sounds like you, then strap Sean and
I work our way through the wacky world of
computer science, starting with the biggest
question probably on your mind, which is what
even is programming?
Well, the dictionary defines it as the process
of preparing an instructional program for
a device, but that’s a really confusing
definition, so in layman’s terms what exactly
does that mean? Essentially, it is attempting
to get a computer to complete a specific task
without making mistakes.
Imagine this, for example: you want your less-than-intelligent
friend to build a lego set, except he has
lost the instructions and can only build based
on your command. Remember though, your friend
is far from competent, and so If they are
not given very specific instructions on how
to build the set, there are many mistakes
he could make. If he thinks like a computer,
then if there is even one piece that you have
not told him specifically where to place and
how to place it, the entire lego set will
be ruined and he will be left to suffer a
complete mental breakdown causing the whole
goal of the project to be corrupted. Giving
instructions to your friend is very similar
to how programmers code. Instead of a less-than-intelligent
friend, you have a less-than-intelligent computer,
and instead of instructions on how to build
a lego set, we are feeding it information
on how to complete a program like a game or
web application. An important thing to note
is that comptuers are actually very dumb.
We build them up to be this super sophisticated
piece of technology, when in actuality, a
computer’s main functionality comes from
how we manipulate it to serve our needs.
Now, programming isn’t as simple as giving
your friend instructions since in a programmers
case, the computer doesn’t speak the same
language as you, the computer only understands
machine code, which is a numerical language
known as binary that is designed so that the
computer can quickly read it and carry out
its instructions. Every instruction fed to
the computer is converted into a string of
1’s and 0’s and then interpreted by the
computer to carry out a task.
Going back to the lego example, this process
would be like if he was not only less-than-intelligent,
but to make matters worse, he could not understand
english and only speaks in mandarin chinese.
In order to speak with him, you have to convert
the instructions that you understand in english
into the language that your friend understands.
This process is essentially what you must
do for your computer in order to make it understand
the instructions you give it.
The big difference between the two examples,
however, is that it is very difficult for
people to understand machine code and binary.
Directly translating what you want the computer
to do into machine code is extremely difficult,
in fact almost impossible, and would take
a very long time to do if you could. Each
program is composed of millions upon millions
of those 1’s and 0’s, so how, exactly,
are we supposed to translate our instructions
into machine code?
This is where programming languages come into
play. Programming languages are fundamentally
a middle man for translating a program into
machine code. These languages are much easier
for humans to learn than machine code, and
are thus very useful for programmers. Going
back to our lego example, a programming language
would be sort of like an interpreter, that’s
able to take the instructions you give them
in english, and translate them into instructions
your non-english speaking friend can understand.
This makes programming languages extremely
useful and the backbone of almost any good
program. Think of programming languages as
not english, and not machine code, but somewhere
in the middle.
There are many different programming languages
out there that each have their own unique
uses. Languages such as Python and Java act
as general purpose languages that can perform
a variety of computational tasks, while RobotC
or HTML/CSS are languages designed for more
specific purposes such as moving a robot or
constructing a website. Languages can also
vary in how powerful they are. For instance,
JavaScript is a scripting language that is
designed for smaller tasks while java or python
can carry out much more computationally taxing
processes.
We measure a programming language’s power,
or level, by how similar it is to machine
code, the series of 0’s and 1’s we talked
about earlier. Low-level programming languages
such as assembly or C are closer to binary
than a high-level programming language such
as Java or python.
The basic idea is that the lower the level
of your programming language, the more your
code will resemble what the machine can interpret
as instructions. Aside from the different
purposes that each language fulfills, choosing
a programming language typically comes down
to a matter of preference, as there are usually
many languages that accomplish similar tasks.
Try different languages, and decide which
one’s rules, interface, and level of simplification
you like best.
So now that we know what programming is, how
do we actually write code? It’s not like
we can simply type words into a text document
and automatically assume that the computer
can translate it into machine code, read it,
and carry out a task like opening up a browser.
And additionally, we can’t just write down
rubbish in certain programming languages mentioned
in the previous episode and expect the computer
to understand. So how are we supposed to write
code then?
Well, the answer is with an IDE. An IDE, which
stands for Integrated Development Environment,
allows the facilitation of code by a computer.
IDE’s provide a graphic interface on your
computer in which the programmer can easily
write, run, and debug code without having
to worry about problems with compilation or
interpretation of the program. Think of an
IDE as any other program on your computer
such as a game, a browser, or even the file
explorer, except we’ll be using it to write
code. IDE’s are able to turn your code into
machine code and run it through the computer
to produce results.
In addition to providing a place for programmers
to develop their code, IDE’s provide some
extremely useful tools for programmers to
ease the job of writing code, such as built-in
error checking because as we’ll talk about
later; code doesn’t always run correctly,
auto-fill in for frequently used words or
phrases, and project hierarchy which will
help you organize and manipulate the files
within your project. Back in the olden-days,
before IDE’s, code used to be written on
punch cards and then fed into computers which
would take hours and cause a lot of pain.
IDE’s nowadays act as a sort of fast-track
to writing code and make things a whole lot
easier for programmers. An example of a specific
IDE can be seen on your screen now. In the
center you can see the program that is currently
being written, and right below it the console,
which can print out useful information for
the programmer. This specific IDE is used
to write java code. IDE’s are extremely
powerful and will be used in almost 100% of
your programming projects.
So through these IDE’s we are finally able
to write and compile code smoothly without
worrying about the computer not being able
to understand it. The next problem we run
into then becomes how do we write this code
in the IDE, because it’s not like we can
just type random words from a certain programming
language and expect the compiler to understand
it. This is where a programming language’s
syntax comes into play.
Now, just as if you were learning a real language,
learning a computer language can be very similar.
Some have different styles that may seem odd,
some may make you use abstract or weird concepts
which may be confusing, and like all languages,
programming languages have a set of rules
that you must follow when writing code in
that language, and at the forefront of those
rules is grammar. Programming grammar is referred
to as syntax and is very similar to real-world
grammar. Each programming language has its
own syntax, or rules, that you have to follow
to a tee if you want your program to run correctly,
just as if you were speaking in real life.
These can be things such as how you type out
certain functions, what you put at the end
of a line of code, and how you set up certain
functions. Each language is unique in its
syntax, and while some may share similar rules,
all will have some quirk which makes it stand
out from the rest. Syntax is something that
catches a lot of people off guard, since many
expect every programming language to follow
the same set of rules, but as we spoke about
in the last segment, because each language
is specialized for a specific task, each needs
its own set of rules to function. Breaking
or disregarding these rules will result in
an error, just how breaking or disregarding
rules in real life will result in an unintended
message.
As an example. If we wanted to do something
simple such as initialize a variable, which
is something we haven’t covered yet but
the example is still relevant. In java, you’ll
notice we have to specify what type of variable
we are defining in this case an integer, and
also add a semi-colon after the statement.
In python, we don’t even need to define
that we are trying to create a variable and
just have to type what we want to create,
and in javascript, we just specify we are
making a variable, but do not include what
type of variable we want to make. Even in
this simple example you can see how much syntax
matters when learning a new language since
while the goal of our program remained the
same, define an integer with value three,
all the programming language shown took different
approaches. All these languages require that
you follow this syntax because remember, computers
are extremely dumb, if you forget one semicolon
or misplace a character, the entire program
will not run and send you back a syntax error,
which is something we will talk about later.
Think of this as if you forget a comma in
a sentence and the entire context of what
you are trying to say get misinterpreted.
For example, in the sentence “let’s eat,
grandma”. If you were to forget that comma,
while it may seem like a small mistake, it
changes the entire context of the sentence,
making it sound like you’re about to eat
your grandma. The same rules follow for programming,
if you forget a semicolon, the entire context
of your program could be corrupted and misinterpreted.
Now another thing which makes IDE’s so useful
is that they will let you know if and when
there are syntax errors in your code. Syntax
errors of course being parts of your code
which do not follow the rules we talked about
previously. The IDE will tell you where in
your code the error is, and also won’t let
you run your program until the error has been
fixed. Because of how important syntax is
to writing code and learning a new language,
it's recommended that you learn the rules
and syntax of a language before beginning
to write complex programs in that language.
Most of the rules are tedious to learn but
easy to master and as soon as you can do that,
you’ll be able to easily identify syntax
errors and take care of them easily.
That covers the basic gist of syntax and programming
rules, so now that we know HOW to write code,
and WHERE to write code, we next need to cover
what happens after we have typed out our program
and run our code. Because writing a piece
of code for a game or for a database is cool
and all, but after the computer interprets
the program, how will we know what’s happening,
and whether it is working or not? Well, programmers
do this by looking at the console. The console
is a text interface within the computer that
us programmers can use for a variety of different
purposes. If you remember, a short while ago
we showed a picture of a basic IDE, and one
of the main parts of that picture was the
console.
The main use of the console is to output text
from the program. This is usually done using
a print statement. A print statement is a
command that does exactly what it sounds like:
it prints text to the console. This print
statement is the first piece of ACTUAL CODE
we’ve talked about in this series, and it’s
about as simple as it gets. The print statement,
despite its simplicity, is one of the most
important functions in programming and exists
in some form in just about every programming
language.
The most basic thing you can ask the print
statement to do is just simply make it say
something. This is done by instructing the
console to print, and then include whatever
you want to be printed inside the parentheses.
For example, in python, the segment of code
print(“Hello World”) will cause a message
reading “hello world” to appear onto the
console. Pretty neat.
The print statement is also vital for viewing
and interpreting the computer’s output from
a program. For instance, if you tell a computer
to run a simple calculation, for instance
to determine what 4+3 is, it will run the
program internally and compute an answer.
However, what is the purpose of having the
computer run this program if you will not
be able to tell what the result is? Instead
of simply telling the computer to perform
this calculation, instruct the computer to
print the output of the program to the console,
and upon the program’s completion, 7 will
appear on the console. As you can see, the
console allows us to easily print information
out to the developer for a variety of uses.
It is important to note that the print statement
varies depending on the programming language
being used. For example, in Java there are
multiple versions of the print statement depending
upon whether you would like a line break after
the printed text, and specialized print statements
which make your code more efficient. Also,
the general syntax of using a print statement
and certain nuances of its function can change
between languages. However, you can generally
rely on it carrying out the same overall function,
as it is a foundational statement for programming
in general. So print statements, they print
information out to the console for the developer
to use, nice.
All of its functionality makes the print statement,
along with the console, a very useful developer
tool. However, it is important to remember
that that is all it is: a developer tool.
The console is not really meant to be viewed
by the end user of your program. It tends
to be hidden away behind the scenes, and other
methods of displaying information such as
displaying text, graphics, or images are used
to convey information to the user instead.
Think of it like this, when you’re using
your phone, you see the console in none of
the programs you use. So while you can use
the console to give yourself information about
how your program is performing, don’t try
to implement it in the final product because
it fundamentally just isn’t meant for that.
Overall, remember to use the console to its
fullest extent when writing and fixing problems
in your programs, as it is a great tool to
use to tell how your program is performing
behind the scenes.
So now that we know a whole bunch of information
about programming languages and how and where
to write them, along with the print statement
under our belts, let’s go over some intuitive
things the computer can do all by itself,
without you having to tell it how to. More
specifically, we’ll be covering basic number
mathematics as well as string math
Starting off with basic mathematics, the computer
already knows how to do simple arithmetic.
This includes addition, subtraction, multiplication,
and division, all of which are represented
by the symbols shown on the screen now. In
any IDE that you may install, you’ll be
able to print out the answer to simple math
problems using the print statement, which
may seem counter-intuitive because why would
you use the computer to do math when you have
a perfectly good calculator on your phone,
but you have to remember that computers are
dumb, and anything we want a computer to do
we have to build up from scratch. Basic arithmetic,
while simple, helps out in almost any program
you may write. For example, if we wanted to
build a basic calculator app, we’d need
to utilize this functionality in order to
correctly display the answer to an arithmetic
problem when our user tries to add, subtract,
multiply, or divide two numbers.
Now in addition to the 4 basic math equations,
most programming languages include an additional
operator known as modulus. If this is your
first time hearing this word, don’t worry,
since it's not usually taught in math classes.
Modulus allows us to get the remainder of
a divisional operation. For example, when
we take 10 modulus 3, we are essentially telling
the computer to take 10, divide it by 3, ignore
the actual answer and just give us the remainder
of that operation in this case 1, since when
we divide 10 by 3, the answer is 3 remainder
1. The 1 in this case is what gets printed
out to the console. If there is no remainder,
say in the case that we take 50 modulus 2,
since the remainder is 0, the function would
return 0 if we were to print it out.
This can be extremely useful in many cases,
the most obvious being if we want to determine
whether or not a certain integer is even or
odd. If we take a certain number modulus 2
and it returns 0, then we know it's even since
any even number divided by 2 will always result
in a full answer without a remainder, but
if the system returns 1, then we know that
the integer is odd. You will find yourself
using the basic math operators a lot more
than you think, so it's good to keep them
in mind when writing your programs.
Now our computer can work with numbers, as
well as Strings. Strings by the way are another
way to just say text. For example, “hello
world” is a string, The letter “a” is
a string, anything enclosed by quotation marks
is denoted as a String in programming language.
We’ll cover more about Strings in a bit
when we talk about variables, but for now
let’s continue. We already talked about
printing strings to the console, but let’s
say we’re making a game, and we wanted to
print out the statement”
“Game over, 4 was your final score”.
Now while we could just make a string that
says that exact phrase and print it out to
the console, in some cases it would be more
useful to print out the actual integer value,
especially in the case of a game where the
score can change each time you play, because
score definitely isn’t always going to be
4. Well, we’re also able to print multiple
strings of text, and even integers by “adding”
them together in the print statement. This
is called concatenation.
Continuing with our score example. If we wanted
to print out the statement “Game over, 4
was your final score”, using 4 as an integer
rather than a string, we could do this by
breaking down the statement into two strings
and an integer like so.
Print (“Game over, “ + 4 + “ was your
final score)
We of course begin with a print statement,
which again will be different across all languages.
Inside the print statement we start off by
printing the string “Game over, “. Now
here comes the important part, from there,
we use a plus sign and add 4 to the print
statement, just like if you were adding two
numbers. Then, we can repeat this process
with another + sign for the final string “ was
your final score” and we’re able to print
out the entirety of our statement easily.
Doing this, we can easily print out multiple
different strings and integers together in
one print statement.
We could also combine the two lessons we’ve
learned thus far and do something like “Game
over, “ + (4+4) + “ was your final score”,
in the case lets say where we have a game
which gives you a base score, then 4 points
for a certain task you completed. This demonstration
also displays another important part of programming,
which is that oftentimes to get your program
to be the most efficient, you have to combine
aspects of code.
Now it's important to note that the computer
will take whatever you put in parenthesis
and print it out character for character,
so oftentimes programmers will forget to add
a space onto the end of their strings. This
can result in an small mistake in which the
string from the previous example will be printed
out as if to say
“Game over,4was your final score” which
isn’t that appeasing when displayed on screen
to the user, so it's good practice to always
put a space after and before your strings
to make sure this doesn’t happen, and your
string doesn’t end up like this.
Another important thing to note is the difference
between “4” in quotation marks and 4 without
quotation marks. Now “4” in quotation
marks is treated as a string rather than a
4 without quotation marks which is treated
as a number. This may not seem like a big
deal, but again computers are dumb, and if
you try to do math with a number in quotation
marks it will return an error, because the
computer doesn’t understand that you’re
trying to preform the operation on a number,
and it thinks you’re trying to add an integer
to a string, which is a big no-no in programming.
So when you are programming make sure to make
a mental note of whether or not you want to
make something an integer, or a string, because
that type of stuff makes a big difference.
Alright, that concludes our segment on the
base power of computers.
Now next up we’re going to be covering one
of the most important components of computer
science, so make SURE you pay attention because
next up we are going to be covering variables,
what they are, and how we use them.
First of all, what exactly is a variable?
A variable is simply something that can store
information and can be referenced and manipulated.
Think of variables like a cardboard box. Cardboard
boxes serve as a means to store items in them
which can be changed out, replaced, and modified.
Variables are like cardboard boxes that store
information for the programmer to reference,
manipulate, and refer to. Each variable simply
has a type, a name, and a piece of information
stored inside of it. The type and piece of
information will be covered next and the name
is simply a name for the variable, think of
it as writing out a label on the cardboard
box in sharpie.
Now, there are many different types of variables
that a programmer can use, but right now we
will just be covering what are called “primitive
variables”, which include integers, booleans,
floats and doubles, strings, and chars.
We’ll start off talking about an Integer.
An integer, or int for short, is as simple
as it sounds: a variable that can store an
integer value. This includes all whole numbers
from -2,147,483,648 to 2,147,483,648. Now
notice how I said whole numbers, integer variables
CAN not and WILL not hold any decimal values,
so keep that in mind when using variables.
Secondly is a boolean. A boolean is a very
primitive variable which can store a value
of either true or false. Boolean variables
can ONLY hold these two values, and are extremely
useful for conditional statements, which we
will cover soon.
The next two types of variables are floats
and doubles. Both of these variable types
are floating point data types, which essentially
means that these variables can store numbers
with decimal places. Whereas integer values
cannot hold decimal values, floats and doubles
can. The main difference between the two is
that a float variable can store numbers of
a precision up to 32 bit, while double can
store numbers with precision up to 64-bit.
Essentially, a double can store more decimal
places than a float, so it all comes down
to how precise you want the variable to be.
Up next we have string variables, which are
like the strings we’ve actually talked about
beforehand except stored somewhere in a value.
String variables can store strings of letters,
which are just words and sentences. Strings
are useful for displaying text and storing
input information. Strings can also be concatenated
together to form combinations of string variables
and prewritten strings. This is very useful
for outputting information in a readable format
for the user. For example, imagine that we
have a string called “name”. The code
asks for input, and stores that string of
text in name. To output this information to
the user, rather than simply displaying their
name, you can add the phrase “Your name
is:” and make it into a sentence by concatenating
“Your name is:” + name + “.” This
makes it easier to read your code, while also
adding variability to your code, which always
makes things more interesting for the end
user.
Finally, we have char variables. Char stands
for character, and just as the name suggests,
they can each hold one character. This is
useful when a programmer wants to read one
button press or one character in a string
without using a string variable. A specific
example is making a game that is controlled
by the keyboard. The program needs to recognize
the character that is pressed, and translate
that into carrying out some function. Now
strings can also hold one character, but char’s
can’t hold more than one character so keep
that in mind when defining variables.
Now, why are variables so useful? Well, being
able to store information in a format that
can be easily referenced later is essential
for any good program. Oftentimes in code you’re
going to want to keep track of things such
as a user’s name or score, and so by creating
a variable called “name” or “score”
you can store this information in that variable
and then reference it, add to it, or modify
it. Also, many times, the program will have
to take input from the user, which cannot
be pre programmed into the code, and thus
a variable is required to store the information.
A program may also rely on factors that will
change as the program progresses, in which
case a variable is once again required. Also,
taking these variables and manipulating them
is quite necessary for carrying out many of
the tasks you want a program to carry out,
for instance multiplying int variables or
concatenating string variables. Overall variables
are the backbone of any good program and you’ll
find yourself using them often if you want
clean and efficient code, so it's best that
you learn what types of variables you need
to use and when.
So now that we know all about the different
variable types and we’ve talked about them
a little bit, now we’re going to delve further
into what happens when we actually define,
or create, a variable, how we reference them,
and how we can manipulate them for our programs.
To start, let's go over what happens when
we define a variable. Now when we write a
line of code which initializes a variable,
and that code is executed, the computer essentially
creates a little space in memory that stores
your variable name and its contents so that
it can be referenced later. Going back to
our cardboard box example. Think of this as
if you have a storage facility, and you make
a new cardboard box, labeled “Name” and
inside of it you put a piece of paper with
the word “NullPointerException” on it.
Now, anytime you want to know the contents
of your name box, you could simply look inside
and see that it has the contents “NullPointerException”.
This is what the computer does, except the
storage facility is memory, the box is a variable,
and the contents of the box are whatever the
variable is set to be equal to. Any time you
want to know the contents of the name variable,
you can simply call it and the computer will
pull the information that is stored in that
variable out and use it how the user sees
fit.
Another thing to note really quickly is that
you can actually make a variable without putting
information inside of it. This would be like
if you built up a new cardboard box, gave
it a label with a sharpie, but just didn’t
put information inside of it. You’re simply
saving that space in your warehouse for later.
This can be because you want to store information
in it later down the road, or if you’re
going to use it to store information given
to you by the user, in which case you CAN’T
give it information since you don’t know
what the user will input. Just note that if
you try to reference, or point, to a variable
which does not have any information in it,
you’ll get what’s known as a NullPointerException,
which despite being an awesome name for a
YouTube channel, is something you generally
want to avoid when programming.
Now, programming languages allow us to do
some pretty cool things with these “boxes”
that we’ve created. For example, let’s
say we created a second variable “channelName”
and instead of setting it equal to “NullPointerException”,
we instead set it equal to our already created
“Name” variable. This doesn’t create
a space in memory for this new variable; however,
it simply points to the same location of memory
we have already created for the “Name”
variable. Going back to our storage facility
example, this would like if instead of creating
a whole new box labeled “channelName”
and storing a sheet of paper with the word
“NullPointerException” on it, we instead
simply added another label below the “Name”
box, entitled “channelName”. Now, we have
two variables but both point towards the same
contents, that being the string “NullPointerException”.
We usually do this to save space in our code
for things that we know are going to have
the same value.
Variables can also be updated throughout your
code. For example, let's say you had an “Age”
variable, and inside it was the integer 17.
Then you celebrated a birthday and wanted
to update your age. All you have to do is
reference the variable, and set it equal to
whatever new integer you want the variable
to hold, in this case 18. This would be the
same as having a box labeled age, with a sheet
of paper reading 17 inside of it, and then
taking that piece of paper out, erasing 17,
replacing it with 18, and then placing it
back into the box. Doing this, we are able
to easily update the contents of our variables
throughout the code as things dynamically
shift. As another example, if you were making
an RPG, your character will likely have stats
such as attack, defense, mana, etc. As the
game progressed you could continuously update
the variables so that the player could get
more powerful the further along that they
went through the game, and you wouldn’t
have to create new variables. You would just
simply need to keep grabbing that box from
your storage facility, erasing and replacing
the numbers on the piece of paper, and then
continue along with your code. Just keep in
mind that these variables are nothing more
than places in memory in which a certain value
is stored, so we can easily update the numbers,
and their place will remain constant. After
a code has run its course, the place in memory
is deleted until you run the code again and
the program dedicates space for the variable
again. Each time you run the code, you're
making new boxes in your storage facility,
and at the end of your code, you destroy them
all to make room for new boxes next time.
Another cool thing you can do with variables
is add them, subtract them, multiply them,
divide them, and even modulus them. Now this
mostly only works for integer variables as
multiplying and dividing strings doesn’t
make too much sense. But if you were making
a calculator app and you stored the first
number the user entered as num1, and the second
as num2. You could then multiply num1 and
num2 together, and either print them, or store
them in a new variable entitled result. Then,
each time you run the program, the user could
input new numbers into the num1 and num2 variables,
and they would simply be set to those new
integers and return the result that corresponds
to those specific numbers. This allows for
you to keep easy track of which numbers are
which and what’s going on in your program
which is extremely useful. Also, while you
cannot subtract, multiply, divide, or take
the modulus of strings, you are able to add
them. Let’s say you had a string Str1 with
the contents “Hello “ and a Str2 with
the contents “there”. You could add Str1
and Str2 to create a string that had the contents
“Hello there”, either storing it in a
third variable or printing it out to the console.
The last topic we’ll be covering on the
topic of variables is the naming conventions
of a variable, which albeit may seem odd,
but it's extremely important when trying to
read your code so we will be covering it now.
Now, variables have to be one continuous string,
and so if you wanted to make a variable that
stored the player score, you’d have to find
some way to combine the words player and score,
since you can’t have the phrase “player
score” be the name of a variable. All programmers
have their own personal preference when it
comes to naming variables, but the one we
will be using on this lecture is called CamelCase,
which is the process of not capitalizing the
first word, but capitalizing every word that
follows it. Going back to the player score
example, using the camelCase method, the variable
would be called playerScore. This allows us
to easily identify each word and becomes really
useful for long variable names like thePlayersScoreBeforeFinalBoss”,
whereas if we just type it out without capitalization,
it would be really confusing. This will help
a ton when you start to find bugs in your
code and need to quickly scan your program
to figure out whats wrong, and adds to the
overall readability of the program. Other
programmers might use different naming conventions
like using underscores to separate the words
in a phrase, but for now we’ll be sticking
with camelCase.
Next, we’ll be moving on to conditional
statements, which at their core, are statements
that change the path of our code depending
on certain conditions. For the sake of keeping
things simple, for this section, red lines
will connote that our code will NOT be following
that specific path, and green lines will mean
that our code IS following that path.
The main type of conditional statement that
programmers use is the if statement, and this
will show up countless amounts of times in
any program you write. It is as simple as
it sounds: if some condition is true, and
usually the condition will be enclosed by
braces, then carry out the instructions located
within the if statement’s brackets. Else,
do another thing.
Now, brackets are used in most programming
languages to indicate a segment of code which
will run. It works like this, if the condition
in parentheses is true, then all of the code
contained within the brackets will run, and
if the condition in the parenthesis is NOT
true, then it will skip over all of the statements
within the brackets. A quick note is that
while this is the case with most programming
languages, some; like Python, use colons and
white space to determine where a piece of
code starts and ends, but for the sake of
this series, we’ll be using curly braces.
Now, the condition within the parenthesis
can take on thousands of different forms such
as if the value the string variable Name is
equal to “Steven” or if the player's score,
stored in an int variable, is greater than
5, the list goes on and on. Each of these
statements is evaluated as a boolean, which
you will remember from when we talked about
variables is either true or false. If the
boolean is true, we run the code inside the
curly braces, if it’s not, we pretend everything
inside the curly braces never existed and
move on with our code.
The if statement comes with two more additional
statements that can go with it: else if and
else. Else if is a conditional statement used
directly after an if statement, and carries
out mainly the same function as an if statement.
However, the else if statement will only be
evaluated if the preceding if (or else if)
statement is bypassed due to its condition
being false. So we would run through it like
so, if something is true, we would run the
code inside of that statement’s curly braces.
Else, if that something is not true, BUT another
statement inside of parentheses is true, we
would then run THAT code segment. And if neither
of them are true, we would skip both segments
of code and move on in our program.
This is a hard concept to wrap heads around
so let’s do an example. If we had a program
that evaluated the if statement if (age = 10),
we could then have a statement under that
which stated else if (age = 12). Now, if the
age variable was 10, which we can see from
the example it is, then the code immediately
following that conditional statement in the
brackets would run. The else if statement
we made would not even be tested since we
know it is going to be false, and thus the
print statement inside of THAT conditional
statement’s brackets will be ignored, and
the code will move on to the rest of the program.
Now, for example, let’s say we changed the
age variable to be 12 instead of 10. Now,
instead of the first conditional statement
being, true, it actually evaluates as false,
since age no longer equals 10. So what we
do now, is first skip over the print statement
which prints out that the age is 10, since
it’s not. And now we evaluate the else if
statement. We check if age is equal to 12,
which again it does, and so now we run all
the code inside of that conditional statement
before finally moving on to the rest of the
program.
So as a review, we check the initial if statement,
if it’s good we run all code within that
if statement’s curly brackets and move on
with our program, if the initial if statement
is NOT true, we then move on to any else if
statement’s and evaluate if THOSE conditional
statements are true. We can have as many else
if statements as we want, although this could
lead to clutter amongst your code so we’ll
talk about some alternatives later on to help
this out. Now that takes care of the if-else
statement, so now we’ll move on to the else
statement.
The else statement once again comes after
an if or an else if statement, and will carry
out its instructions no matter what, as long
as the preceding statement/statements are
evaluated as false. If we went back to our
previous program, we could add an else statement
which would only have the code in its brackets
run if the age variable wasn’t “10”
or “12”. This would catch all cases of
the program that didn’t fit our parameters.
It’s good practice to ALWAYS have an else
statement at the end of your conditional statements
to catch any weird cases that may come up
in your program.
Now remember back to the fact that we can
have thousands of else if statements, after
a while that can get pretty cluttered, and
so another very useful conditional statement
which helps circumnavigate this problem is
the switch statement. A switch statement is
functionally similar to many if and else if
statements together. You write a switch statement
in the form of switch (variable), and then
below that you write how many cases that the
variable could be. For instance, if we wrote
switch(var), then under it we could write
out 5 cases that the variable var could be,
and then the instructions listed under that
case to be carried out if the var variable
is equal to that case.
Now switch statements are different since
instead of using brackets, they use a colon
to signify the start of a set of instructions,
and a break statement to end it. This is very
useful because you are able to essentially
use many if and else if statements without
having to write nearly as much. In switch
statements, you just always have to remember
to include a default case at the bottom of
the expression to denote any and all cases
that don’t meet the above requirements.
This simply catches all of the inputs that
don’t fit within the programs main cases.
It’s very similar to an else case at the
end of an if-else chain.
Now, why are these statements so useful? Well,
many times, programmers want their programs
to function differently depending on different
conditions. For instance, a program could
function differently depending on the information
that the user inputs, such as allowing a user
to use a program or not use a program if they
are above or below 18 years old respectively.
Or in say a video game, if a user’s experience
level is above a certain threshold we might
want to give them harder opponents to battle.
Another example could be a program which changes
the color scheme depending on the time of
day. Or even more simply, if a user presses
a button that is meant to move on to another
screen in an app, the programmer would only
want the app to change screens if the user
clicks that button. A program without conditional
statements would do the same thing every time,
and would be very primitive compared to one
that can change depending on its conditions.
So now that we know how to make and use variables,
how to compare them, and what we can do with
those comparisons, let’s move on to another
foundational concept of computer science:
arrays.
Now we’ve already talked about variables,
and how great they are for storing singular
bits information for making our code more
simplistic, but one of the biggest drawbacks
that come with variables is their inability
to hold more than one piece of differing information.
For example, let’s say you’re making an
app which allows users to create a grocery
list. Well there’s no real easy way to create
lists using variables, because it's not like
you can have one variable store the names
of 7 or 8 different food items. Remember,
we can only put one piece of paper in our
cardboard box; no more. And besides, even
if you were to add multiple items to one string
variable, you still would have a lot of trouble
doing simple tasks you might want from a list
like searching through it or splitting it
or even deleting items from the list when
you’re done with them. This is the problem
that using arrays solves for us.
An array is, as you may have guessed by now,
a list. You can have an array of integers,
an array of strings, and even an array of
other arrays which is something we’ll cover
in a minute. Programmers use arrays when they
want to store a lot of variables containing
information that is all related to each other,
such as a grocery list or a high score list
in a game. Think of arrays as a column in
excel or google sheets. You have the title
at the top and then below it are a bunch of
bits of information which all relate to the
title. Arrays are super useful when programmers
want to store a lot of information that can
be easily searched through because programmers
have developed methods of breaking down and
using arrays to find specific information
in arrays full of thousands of different variables.
As an example to show just how useful arrays
are, let's say you’re a startup company
that owns an app that has 100,000 users. Every
time a user wants to create a new account,
they input the username they want and then
your program will have to check to make sure
the account name hasn’t already been taken.
Doing this requires you to search through
the information of all 100,000 of your users
to see if that username has an account with
your service. An array would be able to contain
all of this information and make it easy to
search through and find out if the account
name has been taken with little to no delay.
Now the single most important thing to note
about arrays is how you reference each element
of the array within them. Let’s create a
basic array called numbers, and inside of
it put the digits 1-10. Now when we want to
refer to each cell in this array, we call
upon its “index”. An index is just a fancy
way of saying that numbers are placed within
the array. Now you would think that the first
integer in this array would be the first index,
the second would be the second index and so
on, but that’s not the case. In computer
science, programming languages refer to the
first cell as the 0th element in the array.
This means that if we were talking about our
array of numbers we just made, the number
4 would actually be in the 3rd index, 5 would
be in the 4th and so on, so instead of starting
our count from 1, we start from 0. It’s
extremely weird and confusing but it's one
of those programming quirks you are going
to have to memorize and commit to memory.
If you were to not follow this nomenclature
and you refer to the last element in this
array as the 10th, you get what is referred
to as an “out of bounds” error, since
you are trying to reference the 10th element,
but there is no 10th element. What you’re
actually trying to do is reference the 9th.
Another extremely important thing to note
about arrays has to do with their size. When
you initialize an array, you can do it either
one of two ways. You can either populate it
with the elements that you want contained
in the array right then and there, creating
and filling the array at the same time, or
you can define how many elements you want
in the array-essentially the arrays size-
and then populate it with elements later.
This is because when we initialize an array,
it creates a space in memory that has a size
of exactly what you give it, no more no less.
This is great for when we want to access elements
in the array because we can do so instantaneously,
but the one downside is that we can’t increase
the size of the array later on, all array
sizes are final. Think of it like setting
up a bookshelf with books. By populating a
bookshelf with a certain number of books and
then moving on and filling the next shelf
with different books. We have no way to go
BACK and add books to that first shelf without
shifting everything. Once we decide how much
space to dedicate space for an array in this
case, there’s no way to ADD more space.
Once again because this is extremely important
to remember, this means that once an array
has been defined, there is NO WAY to change
the size of it. If you have an array titled
“Names” with a size of 8, and you try
to add another name to the array you will
receive an error, so be careful when messing
around with array sizes. Of course, you can
always go back at the start of the code when
you initially MAKE the array and allocate
more space to it if you find out you need
more space to hold items, but once it’s
defined, you CANNOT change its size.
Another small thing I want to touch upon really
quickly is that when you initialize an array,
you must determine which type of array it
is right then and there. For example you have
to specifically say it will be an array of
strings or integers when defining it, and
also you’re not allowed to mix and match,
meaning you can’t have an array full of
integers with a few strings and some doubles
thrown into the mix. They have to be all the
same type.
Now the last thing we’re going to cover
on arrays is a little funky, and that is the
practice of putting arrays inside of arrays.
If you make an array of arrays it's referred
to as a 2D, or 2 dimensional array. Think
of these as matrices if any of you have taken
algebra classes. Now If you haven’t, think
back to our google sheets example but instead
of just columns, we would add rows as well.
So now, each element in our array wouldn’t
simply be just a String variable or an Integer
variable, but an entirely new array with its
own set of values and elements.
The way we index these is mostly the same,
except we would have 2 numbers to index instead
of 1. We start with the row and then the column.
So a number in the position (0,2) would be
in the first row three columns down, in this
case the name Clint. A number in the position
(1,1) would be two rows down and 2 columns
across, in this case the name Chris. You get
the idea. Now you can also make 3-dimensional
arrays by putting an array inside an array
inside an array, but that's a little above
what we’re going to be covering so I’m
gonna cut it off there.
Next up we’re going to be talking about
loops, so what exactly are loops?
Next up we’re going to be talking about
loops, so what exactly are loops?
Next up we’re going to be talking about
loops, so what exactly are loops?
Next up we’re going to be talking about
loops, so what exactly are loops?
Next up we’re going to be talking about
loops, so what exactly are loops?
Well as you could probably tell by that statement
right there, a programming loop is a statement
that is used to run certain instructions repeatedly,
just like how the opening statement of this
topic was repeated 5 times. Loops are very
useful for a variety of reasons. For instance,
imagine you want to print something 15 times.
Sure, you could just copy and paste the print
statement 15 times. But this is really annoying
to have to do, and becomes even more unrealistic
when that number goes up to, say, 100 or so.
Now what if instead of rewriting the same
instructions over and over again, you could
simply place the print statement inside of
a loop, and it will occur as many times as
you would like, that’s the power of loops
baby. With loops we’re able to repeat parts
of code multiple times. Now there are three
different types of loops that we will be discussing
today. And up first is the for loop.
A for loop is very useful for situations described
above, where you would like to carry out a
certain set of instructions numerous times.
The syntax for a for loop varies depending
on the language, however it usually consists
of three parts. An integer value, a condition
which the integer value must meet in order
to exit the loop, and an operation to modify
the integer value after the instructions inside
of the loop are completed. Each time the for
loop runs, the operation you set will be performed
on the integer, and as long as that integer
still meets the condition you set, usually
being greater than or less than a constant
value, the for loop will continue to run.
Eventually, when the integer has been modified
by either increasing or decreasing it to the
point where it no longer meets the condition,
the for loop will terminate and the code will
continue to run. For example, let’s say
our integer value was i and we set it equal
to 0, then we set the conditional statement
as i being less than 3, so basically we’re
saying that as long as i - the variable we
just created - is less than 3, continue running
the instructions contained within the loop.
Finally, we make the operation i + +, meaning
each time the loop runs we will increase it
by one, and inside the loop let’s just put
a simple print statement.
Now let’s run through the loop. We start
with i = 0, 0 is less then 3 so we enter the
loop and print out Hello World. Now that the
instructions are done we add 1 to i making
it 1. Moving on, 1 in less than 3 again, so
we once again enter the loop and print out
Hello World. Again, we add 1 to i, making
it 2 now. 2 is still less than 3 so we enter
the loop again and print out hello world.
Finally, we add 1 to i once again and it becomes
three. 3 is not less than 3 though, it is
equal to 3, and so we don’t enter the loop
and it terminates, moving on to the next segment
of code. This is a simple example, but you
can extrapolate it across programming to fit
your needs.
Now when using a for loop you have to make
sure to set up a condition that, given the
initial integer value and the operation, will
at some point not be met, to avoid creating
an infinite loop and crashing your program.
An infinite loop occurs when you give a for
loop a condition which will always be met
given the parameters of the program, and so
the software crashes. For example, a for loop
beginning at 10 and checking if i is ever
less than 0, and then adding 1 to i at the
end of the loop will never terminate, since
i will just increase infinitely.
After the for loop is the very similar for
each loop. A for each loop (or a for-in-list
loop, in python) is used for iterating through
arrays or lists. Essentially the loop will
go through each element in the array and carry
out some set of instructions for each value.
If you would like to read all of the elements
in an array and compare them to some value,
or perform some operation on them, a for each
loop is extremely useful. So for example,
we could have a for each loop which iterated
across an array and simply printed out the
value of each array location.
Next up, we have the while loop. A while loop
will continually carry out its instructions
while a conditional statement given to it
is true. This can be as long as a certain
variable is true, as long as a number is less
than another number, or while a value is still
equal to another value. While loops are different
than for loops in that the loop is not contained
within one statement, but stretched out and
will continue to run so long as its condition
is true.
Like a for loop, you can make the condition
such that it will eventually return false
and exit the loop, however while loops will
not crash your computer should you create
an infinite loop. In fact, it is very common
for while loops to run infinitely, as, for
certain programs, you would like the program
to continually be iterated through instead
of running once, all the way through until
you exit out of the program.
When programming a game, for instance, a while
loop would be used to iterate through your
code, continually refreshing the screen as
the game runs. From there you could perform
operations on the screen to make the game
playable. Creating an infinite while loop
would simply be done using the syntax while(true),
as the condition true will always be evaluated
as true.
Finally, I’d quickly like to cover an extension
of the while loop, the do-while loop. Do-while
loops are very similar to while loops, except
they will carry out their instructions at
least once, even if the condition is false,
and then will carry on like a basic while
loop. Essentially, the conditions inside the
loop will run AT LEAST once, and then if the
condition is still met they will run again
and function as a normal while loop.
As you can see, loops and their many varieties
have some extremely useful functions. Using
them, you are able to perform an operation
many times in a row, you can iterate through
arrays and lists, and overall decrease the
clutter of your code.
Next up, we’re going to take a break from
learning about common programming statements,
and dive into what happens when the code we
write doesn’t work. More specifically, we’ll
be covering the different types of errors
that can occur when you’re programming,
and what causes them.
Now when you’re writing code, you have to
understand that things aren’t always going
to go the way you expected them, and sometimes
the program doesn’t always work as you had
intended it to. We programmers call these
errors and while annoying, they are always
going to come up in computer science and so
it's best to learn what they are and how to
deal with them. Often referred to as “bugs”,
errors in scripting languages can be narrowed
down to one of three “types”: syntax,
runtime, and logic, all three of which we
will be covering in today’s video.
To kick things off, let’s talk about syntax
errors. These are usually the easiest of the
3 to solve since they are oftentimes something
that can be fixed within seconds. If you remember
back to earlier in the video when we talked
about syntax and programming rules, we said
that if you were to break the programming
rules, or syntax, that it would result in
an error. Well that’s what syntax errors
are, parts in your program where you fail
to meet the programming rules and so the computer
doesn’t know how to interpret your code.
This can be anything, from forgetting a semicolon
at the end of a statement in java, accidentally
defining a variable with two words instead
of one, or even just misspelling the word
String when you’re trying to define a string
variable. Lucky for you guys, these errors
are extremely easy to fix since you just need
to figure out where the error occurred and
what the syntax rule you broke was. Now thinking
back to IDE’s, we mentioned that IDE’s
are so useful because they do precisely that,
they underline syntax errors and usually provide
helpful hints as to how to fix them. Think
of syntax errors as small misspellings or
grammatical errors in an essay you’re writing,
annoying; yes, but not the most infuriating
things. Another useful thing about IDE’s
when it comes to syntax errors is that the
program will actually restrict you from running
the code unless all syntax errors are cleared,
making them even easier to identify and fix.
The second type of error we will be covering
is the runtime error. These errors don’t
show until you actually “run” the code,
hence the name “runtime” error. Runtime
errors are caused by a statement in your code
that SEEMS seems logically sound, but the
computer physically has no way of computing
it in a reasonable amount of time. The most
common of these errors is one which we’ve
already talked about; the infinite loop. As
a refresher/example, think of an infinite
loop like this. Say you sat your friend down
in front of the TV, put on the Office on repeat,
and told him he could leave as soon as Michael
made a “That’s what she said” joke.
Seems pretty simple right? WRONG, because
instead of putting in the Office, you put
in FRIENDS on blu ray. No michael, no inappropriate
joke, meaning your friend would be sitting
there for the rest of his life probably confused
as to why Dunder Mifflin looks so much like
a coffee shop. This is essentially what happens
with the computer, you give it some condition
that it has to complete before the program
can terminate; however, you give it no feasible
way to finish that task. This puts the computer
in error mode and most likely will crash your
program, as the computer desperately tries
to complete the condition you gave it. As
a computer example, if we try to have a program
terminate when an integer i is no longer greater
than 99, but i is initially 100 and only increases,
the loop will never terminate and the program
will crash. To avoid these, you generally
want to think through the flow of your code
before running it -especially with loops-
to make sure that all of your statements can
be completed by the computer. Carefully planning
out your code before you begin writing it
is an extremely useful practice, and something
we’ll be covering towards the later part
of this video.
The final type of error that we will be covering
is a logic error. This error is also pretty
self-explanatory. A logic error occurs when
the code runs smoothly without any runtime
or syntax errors, but the result that you
get isn’t what you wanted. For example,
let’s say you had a calculator app, and
you wanted to instruct the program to add
two numbers, except it multiplied them instead
because you used the multiplication symbol
on accident. This leads the sum to be 36 instead
of 13. Nothing went wrong with the code syntax
or runtime wise, the code runs just fine,
it just doesn't work as you intended it to.
These are often the hardest types of errors
to debug since most of the time, you’ll
have no idea why the code isn’t working,
and certainly not any idea of how to fix it.
This is why it's a good idea to test your
code incrementally, don’t wait until you’ve
been programming for an hour before testing
your application, or else you’ll run into
a lot of logic errors. Logic errors can be
extremely frustrating and could cost you a
lot of time, making them a huge pain, but
if you know how to effectively debug your
code, you’ll be just fine.
Speaking of debugging your code, that brings
us straight into our next topic, which is
how to debug your program.
Now, let’s say you have written a program.
You think it's ready, and you’re ready to
test it. You’ve been working hard on this,
and you’re excited to see it in action.
You run the program, and wait for it to run
smoothly and efficiently. Only, it doesn’t
work. You have encountered one of the three
errors we just mentioned. You really want
this code to work, but how? This is where
debugging comes into play.
If the code is giving you an error, then the
first thing you should do is read the error.
Oftentimes, for syntax and runtime errors
the IDE will print an error message out to
the console. See what line or lines it points
to- since those will be the lines in which
the error occurred- and see if you can understand
and fix what it says the problem is. If the
error isn’t clear, or you’ve never heard
of it, then try googling it, there are many
websites out there such as stackoverflow which
serve as forums to ask and answer problems
with code. Chances are, if you’ve had a
problem, someone else has had the same issue
and there is likely a tested solution. Usually,
when a syntax or runtime error pops up, you
should be able to find a fix for it fairly
easily; however, as I said before, the issue
may arise from some loophole or oversight
in the code you hadn’t planned for beforehand.
Maybe you did something as simple as multiply
two variables instead of adding them. These
are the logic errors we talked about previously.
These problems usually won’t have red text
show up to explain to you what went wrong.
You’ll have to figure it out yourself.
Now there are a few different strategies you
can use in order to track down and fix a logic
error. First, you can use print statements
and the console in order to determine where
the code is going wrong.
Imagine you have a conditional statement that
will run one segment of code if an integer
x, is greater than 5, and will run another
segment of code if not.
If, in your program, x is supposed to be greater
than 5 when the program reaches this conditional
but for some reason the program is still printing
out “X is small” you could use a print
statement to help.
For this problem specifically you could place
said print statement before the branch of
the conditional that would print the value
of x. Now when you run the program you know
exactly what the computer is thinking. Printing
out the value of x just before the if/else
statement will let you know if the variable
has the value you want it to have, and if
it doesn’t you know that somewhere above
that conditional something went wrong and
x was set to a value you didn’t want it
to. In this case, x is equal to 2, which is
why x is small is being printed out.
Now we know what the problem is we can track
down where and when in the code we modify
x to figure out the problem. Use print statements
to determine where your program goes wrong,
and then try to track down the cause of these
issues and solve them. If you use this strategy,
make sure you end up deleting the print statements
afterwards to avoid clutter in the console.
The situation described above could also be
solved using a breakpoint. A breakpoint pauses
your program when the line you placed the
breakpoint at is reached in your program.
If, say, you would like the program to run
through a certain conditional and set a variable
based on that conditional, but you are unsure
if this actually happens correctly in your
code, you can place a breakpoint inside the
conditional path you want to run.
Upon the breakpoint being reached, the program
will pause, and wait for you to continue it
through a button press. This signals that
the spot in the code where the breakpoint
was placed, in this case the correct conditional
path, has been reached by the program. You
can then continue the program knowing that
was or wasn’t where an error in your code
occurred. Breakpoints can be used in conjunction
with print statements in order to both pause
the program, and perhaps view the values of
your variables at the moment in time to give
yourself all the information you could want.
You can also have multiple breakpoints to
help slowly work through your program and
determine where the error has occurred. A
combination of these two strategies will help
you easily determine where in your code you
have incurred a logic error.
Next, let’s go over what to do if you think
you have tracked down the section of code
that causes the problem. You may think you
should delete it, but it’s likely you put
it there for a reason, and you don’t want
to lose that work if you don’t have to.
Firstly, try commenting it out. Comments are
used to markup code and explain their surrounding
sections, but they can also be used to debug.
Anything that is designated as a comment will
not be read by the program as code, and will
be skipped over. Essentially, it becomes something
that is only there for YOU the programmer
to read. The syntax varies from language to
language, but it usually involves placing
some symbols before or around the code you
would like to be commented. Examples of how
to comment in different languages can be seen
on the screen now. Also, when you comment
something, the IDE will grayscale the line
of code, making it extremely easy to determine
what’s commented and what is not. Commenting
code ‘deletes’ it in the computer’s
eyes without actually deleting it. If a problem
is present before you comment a section of
code but it is gone afterward, then that section
of code is the culprit. If you comment part
of a code out and there are still issues,
then move onto another section until you find
the culprit. Once you do, you can tweak it
until it works as intended or delete it entirely
and you will have a fully functioning program
once again. Hurrah!
Now that we’ve talked about what to do IF
you’ve encountered an error and a strategy
on how to find and fix it, I’d like to talk
about some strategies you can use to AVOID
errors in the first place. Firstly, backup
your code frequently. In the event of the
code completely bugging out and you being
unable to fix it, you will want the ability
to revert to a previous version where the
code was still working. If you save frequently
enough, then you will probably not lose too
much work. Version managers like Github or
Subversion can help with this, as they backup
code to an online cloud service in which you
can easily pull previous versions of the program
at any point.
Also, on top of saving, run your program frequently
to ensure that the current version works as
intended. This accomplishes two things. First
of all, it prevents you from saving a backup
that doesn’t work. Secondly, if you encounter
a problem, it will be easier to find if you
have only made a small number of changes since
the last time you ran it and it worked, and
thus you will only have to look through the
new code for problems. If you’ve spent 5
hours coding and hadn’t run it during that
time period, it’s going to be extremely
likely that at some point during that 5 hour
code sesh you messed up, and it’s going
to be even harder to figure out where you
went wrong. Errors, while annoying and extremely
frustrating, are a fundamental part of making
you a better programmer.
Alright, now that we’ve covered errors for
a bit, let’s hop on back to programming
statements and talk about one of the most
important concepts in computer science, the
function.
Now, you may not know it, but we’ve actually
been talking about a few functions this entire
series. Print statements, for loops, and even
basic math operations are all examples of
functions, which of course begs the question
of what actually defines a function. Well,
a function is a segment of code that can be
easily run “calling” the function name
and depending on the type of function, will
do something in return. Functions can be called
numerous times, and in numerous places. Essentially
they are like wrapping up a segment of code
into a nice present and giving it a name which;
when called, will unwrap the present and go
through the code you wrapped up.
For example, the print statements we have
been using this series allow us to print something
to the console any time we want are functions.
You see, we just “call” the print function
and enter in what we want to be printed to
the console, and the computer does it for
us. Behind the scenes, there is actually even
more complex code that is in charge of taking
your text and translating it to the console
to be printed. The developers of almost all
programming languages realize that you don’t
want to program something that manually has
to print something to the console through
the use of complex programming, and so they
implemented the print statement to reduce
the stress and complexity of code on the user,
abstracting it down to a simple line of code.
All of that code that is used to print something
to the console is wrapped up like a present
and given to us in the form of one line, “print()”.
This is actually the main theme of all functions
and the backbone of any good program. Oftentimes
in your program there are going to be sections
of code which are repeated and serve the same
purpose, or equations which you want to allow
differing inputs of. And so you can use functions
in order to condense these down into singular
lines of code to save both time and reduce
clutter on your code. As you will see soon,
functions are EXTREMELY powerful and will
definitely be something you utilize all the
time in your computer science journey.
The print statement is just one example of
functions in everyday code. There are thousands
of functions that are available to you through
IDE’s. However; because you won’t always
use all of the thousands of functions that
are open to you in a single program you have
to import these functions from packages found
in the IDE, which is something we will cover
later on.
Now, there are four main types of functions
in most programming languages, and they are
separated by two defining features: whether
or not they take in arguments, and whether
or not they return values. Let’s start by
separating them by whether or not they take
arguments, but first we have to cover what
arguments are.
Arguments are essentially variables that we
pass into the function in order to be manipulated
and then either returned back to us, printed
to the console, or used in another operation.
Think of functions with arguments like ordering
food at a restaurant. If you walked up to
your local five guys and told them you wanted
to get food without supplying a type of food,
they would probably look at you confused.
You need to tell them what exactly you want
to order so that they can give it to you.
In this case getting food is the function
and what you order is being passed in as the
argument. Based on what you tell them, or
the argument, they will do something different.
You also should note that the argument can
be many different things, it could be fries,
burgers, soda, anything really on the menu,
and such is the case with arguments in programming.
This is essentially what happens with the
computer, for example, the max function which
takes two integers as arguments and returns
the maximum number between the two. Now, for
this function if you don’t input two numbers
or variables for it to compare, it's going
to throw you an error just like the five guys
employee, he doesn’t know what you want
to eat since you didn’t provide him any
arguments, and the computer doesn’t know
what two numbers you want it to compare and
return since you didn’t provide it with
two integers. Arguments are a way for programmers
to have one function that can do many different
things depending on whichever variables can
be passed through. Arguments add variability
to programming and can help diversify your
code. Thinking back to our five guys example,
a restaurant that only allows one type of
food to be made regardless of what you order
isn’t going to be very useful or diversified,
but if we’re able to pass in arguments and
tell them what food we want, our experience
can be heightened and more options become
available, which is exactly what happens when
you accept arguments in your functions.
Now that we’ve talked about functions that
take in arguments, let’s move on to functions
which do not take in arguments, because functions
can also be created and used without taking
in arguments and still be incredibly useful.
For example, let’s say you were making a
text based RPG game and one of the options
you give your player is the ability to view
their stats at various points throughout the
game. Now every time you come upon an option
and they choose the “View Stats” button,
you don’t want to have to type out 6 different
print statements for every statistic they
may have, your code would get cluttered and
messy very quickly. Instead, what you could
do is package the 6 different print statements
in a simple function called printStats().
You don’t need to pass any arguments into
the functions since the function will do the
same thing no matter what the statistics on
the player are. Now, everytime the user wants
to view their stats, you simply call the printStats()
function and voila, the user’s stats are
printed for them to view. This allows you
to save a lot of time writing out code, but
also a lot of space which is extremely important
when your programs begin getting into hundreds
and thousands of lines and you want to easily
search through it.
Okay, now that we’ve separated functions
into those that take arguments and those that
do not, let’s again split these up into
those that return values and those that don’t.
Now the thing you have to understand is that
when you’re making your own functions, which
is something we will be covering soon, you
have to choose what your function will return,
if anything at all. Functions are able to
return values back to the user whether they
be String variables, integer variables, or
even arrays. Now the thing to note about returning
values is that calling the function alone
won’t do anything. You have to return the
value into something. As an example, the Max
function we talked about previously would
return an integer, but in order to do something
with it we would have to either set a new
integer variable equal to the result of that
Max function, or we can print out the result
of a function, which in this case would just
print out the maximum value between the two
integers. Using functions which return values
don’t do much on their own, you have to
pair it with something in order to gain use
out of it.
Let’s do another example, let’s say you
had created a function which took in two string
variables as arguments, combined them using
that fancy String math we talked about earlier,
and then returned them as a single string.
This combineString function could then be
used to create new String variables since
what it is returning is technically a string.
The variable would simply be set to whatever
is returned from the combineString.
The last type of function is one that does
not return anything, and these are known as
“void” functions. Oftentimes these are
like the printStats function we created earlier,
simply used to condense large amounts of print
statements that appear often in your code.
These cannot be set to variables since they
don’t return anything and just get the code
within them run through.
So there you have it, the 4 types of functions.
Ones that take in arguments and return things,
ones that take in arguments and don’t return
something, ones that don’t take in arguments
but still return values, and the ones that
take in arguments and don’t return anything.
Each of these 4 types of functions are useful
and unique in their own way and you will probably
find yourself using them all throughout your
programming journey, so get used to the different
types of functions and know how to make the
most of them, as they are all extremely powerful.
Finally, I’d like to talk about one of the
major benefits of functions, which is that
it makes it super useful to make large changes
to your code without having to go through
the entire program. Each function call is
just a copy of that function's original code,
and so it’s very easy to make changes to
the function and have it translate to across
your code. Let’s go back to our printStats()
function and say that you wanted to go back
and add in a new stat that the player can
level up through experience in the game. Without
functions, you would have to go back into
your code, find every instance that you had
printed out the users stats, and create another
print statement to display the new statistic.
However, if you had created a printStats()
function like we did a little while ago, all
you would need to do is find where you defined
that function and add in a print statement
which displays the new statistic and you’re
done, bam. Now, every place which had called
the printStats function previously will now
also print the new statistic as well. You
can see how powerful functions can be if used
properly, and we haven’t even scratched
the surface yet.
Now, up next we’re going to cover how we
can import other people’s functions that
they’ve written and use them in our code.
Now before we get technical, close your eyes
and imagine you are trying to build a house.
Sure, you could grow your own trees, chop
down your own wood, make your own tools and
nails, and build it up from scratch. But why
do that, when you can simply go to your local
Home Depot and buy these materials that others
have already made ready for you. That’s
the main idea behind importing functions into
your code. Importing functions allows you
to gain access to libraries of functions that
other people have already made for you. This
is just as useful as it sounds. There are
so many functions that are super useful for
any given program that it would take you forever
to write them all yourself. Luckily, other
people have already done most of this for
you.
In each programming language, you are able
to use an import statement to import libraries
of functions into your program that you can
use as you write it.
A library is simply a collection of functions
that all have the same theme. It may be a
math library, a data analysis library, a library
which translates text, or anything that you
can think of really. There is such a variety
of libraries for any given language that most
functions you require that are not hyper-specific
to your program can likely be found in some
library. In fact, a good portion of any programmer's
job is looking online for packages which can
make his or her job easier instead of handwriting
functions. Now, I can hear you saying, “Wow,
that’s sick, how do I do it?” Well, it’s
quite simple: an import statement.
In most languages, an import statement consists
of 3 parts. The library you would like to
import from, the package you would like to
import from that library, and then which class
from that package you would like to use. For
example, we could load up the Java library,
and from there import the util package, short
for utilities, and then from that utilities
package import the scanner class, a class
which allows us to read information from the
user. A package is simply a smaller sect of
functions and methods to help differentiate
between the thousands of methods contained
in a library, and class is even more specialized
than that.
Now if you don’t know what specific classes
you’re going to want to pull methods from,
you can use a star * to import all classes
within the package you’d like. However,
it can be beneficial to be more specific,
and only import the classes you would like,
as it helps with efficiency of the program
in the long run. For instance, in python,
the syntax to import a library is import followed
by the library name. However, importing an
entire library is more computationally taxing
than importing specific functions from a library.
Imagine you would only be using the factorial
function from the python math library.
It would be a waste of computing power to
import the entire library, and would increase
the load time for your program. For smaller
programs, this isn’t a big deal, but it
really starts to add up when dealing with
larger projects. Therefore, you would instead
use “from math import factorial” or the
java equivalent “import java.math.factorial”,
and now have access to that one math command
only. This limits the functions that you can
use, however it saves programming runtime.
If you decide you want to use another function
that you hadn’t planned for, you can always
go back and import that too. Many times, if
you try to use a function from a common package
and you have not yet imported it yet, the
IDE will prompt you to do so.
If you’re trying to figure out which libraries
you want to import, think of the functions
you’re going to need in your program. Perform
a simple google search, and you will probably
run into a package or library that already
exists in your IDE that you can use. And if
you can’t, there are ways to download and
import additional projects to fit your needs.
But if after all of that you still can’t
find a library that contains the function
you are looking for? Well that’s a perfect
segway into what we’re going to talk about
next, which is the basic structure for writing
your own functions.
So at this point we’ve talked about both
what functions are and how we can get some
very useful functions by importing functions
through packages. But there are definitely
going to be moments in your programming journey
where you’re going to want to make your
own functions because you want to make one
specific to your program and code. Luckily,
making your own functions is extremely simple,
there are just some basic rules I want to
cover. Now while we’ve previously used making
functions as an example for other topics such
as the playerStats function from a little
bit ago, they were extremely abstract and
didn’t go in depth into what is needed for
an actual function to operate. So right now
we’re going to be covering a skeletal system
of everything that needs to be included in
a function to get it to work.
Now think back to the 4 different types of
functions that we talked about previously.
Functions that do and don’t return values
and functions that both do and don’t take
in arguments. For creating your own functions,
we’re just going to go down the list and
talk about how to approach creating them,
starting with the most basic of the bunch,
one which takes no arguments and returns no
values, but before we start that, there are
a few small things I want to note about function
naming conventions. The variable naming conventions
we talked about previously also translate
over to function names. So you can’t have
two word functions and you can’t use special
characters like periods or commas. Generally
you’re going to want to follow the same
camelCase style which we talked about in the
variables video.
Alright, so in general for making functions,
each language differentiates how you tell
the computer that it's a function. In java
you have to define the functions scope, which
is something you don’t really need to know
unless you’re going to become more invested
in java, but basically it tells the computer
which parts of code can use the function and
which type can’t. For this series all of
our functions are going to be public. From
there you then determine which type of function
it is, so in this case since it won’t be
returning any variables we’ll just put void
to signify this type of function will not
be returning anything. Finally, you put the
function name after those two identifiers
along with a set of parentheses after it like
so. The parenthesis are where your arguments
would go if you were making a function that
took in arguments, but since for our first
type of function we’re not incorporating
arguments into this function, let's just leave
that blank. All of that is just for Java;
Python on the other hand all you do is put
def, short for define, and then the function
name with a set of parenthesis. So as you
can see, each language is going to be different,
but the main thing we want to remember is
to always add parentheses. From there, we
just type what we want our void function to
do within the confines of the function and
then close off the loop and we’re done,
easy peasy. In Java, the confines of the loop
would be whatever is contained within the
curly brackets, and in python it would be
until you are no longer indented. At its core,
this is the most primitive type of function
we’ve just made. Something which takes in
no arguments and returns no values, quite
similar to the printStats function from earlier
on.
Moving on to the next type of function, creating
a void function that takes in arguments. Now
this process is going to seem very similar
to the previous except for one small adjustment.
Remember the parenthesis that I mentioned
like 30 seconds ago, well we put any variables
we want the user to pass into the function
into these parenthesis, and then when we “call”
that specific function, it will be required
to have those variables passed into it. For
example, in Java, let’s make a function
that takes in 2 numbers and prints out the
product of those numbers. We start with the
public void plus name of function setup since
again, we won’t be returning any values.
And now comes the new part. Inside the parenthesis,
you define which type of variables you want
to pass in as arguments, in this case an integer,
and then a name for that variable. This name
is what you will use to refer to the integer
the user passed in. For this example let’s
just call it num1. Then if we want to add
another argument, we simply add a comma in
between the two and we can make another integer
variable num2 to hold the second number. We
could do this for however many variables we
want to pass into the function, but for now
let’s close off the parenthesis and just
print the product of num1 and num2. As you
can see, we refer to the two numbers the user
will input to the function as num1 and num2.
Now, whenever we want to call the multiplyNumbers
function, we just have to make sure that we
are putting 2 numbers in as arguments. In
this case the number 5 becomes num1, and the
number 8 becomes num2. From there we simply
run the code and the number 40 is printed
to the console. It’s important to note that
you can also mix and match variables when
making arguments. So you can have someFunction
which takes in a char, an integer, and two
strings all within one function. Pretty neat
in my opinion. The last thing I want to mention
about arguments is that when you call a function
you have to follow the variables you defined
when making the function. So for our multiplyNumbers
function you couldn’t put in a string and
then an int. It HAS to be two integers because
that’s what the computer is expecting to
be passed into the function.
So now that we’ve gone over how to make
functions that don’t return variables, we
have to cover those that do, and we’ll start
with ones that don’t take in arguments.
Now the main difference between defining functions
that return variables and defining ones that
do not is that in some cases you have to specify
that you want this function to return an integer
variable, this is most commonly used in Java,
where you would replace “void” with “int”
to tell the computer that you want this function
to give something back to you in the form
of an integer. This works the same as if you
wanted to return a string, char, or even an
array. You simply replace the word after public
with whatever variable you want to be returned
by the function.
The most important thing to remember about
making functions that return variables is
that no matter what path your code takes,
it MUST return a variable NO MATTER WHAT.
What does this mean? Well let’s say you
had some String function in a game and inside
of it there was an if statement where if the
player score was above a 10, you returned
a congratulatory message. This works fine
if you print the result of this function and
the player’s score is above 10. But, if
the playerScore was less than 10 then you
don’t enter the if statement and then you
don’t have something prepared to be returned
to the user and so the function is going to
throw you an error. You HAVE to have all your
paths covered which may seem simple, but if
you’re making a function with a switch statement
in it containing high amounts of cases, this
can get out of hand quickly. Something I like
to do just to make sure this doesn’t happen
is put a return statement at the bottom of
the function with a string or an integer so
unique that I’m able to tell that the code
is not running properly and can fix it. The
main point I’m trying to get across however,
is always cover your exits and always have
a return statement prepared for any case the
user may throw at you.
Another small thing to note is that you can’t
return one type of variable if you have already
defined the function to return another type.
For example you can’t return a string in
an integer function or vice versa. The return
statement must always match the type of function
no matter what.
The final type of function is one that returns
variables and also takes in arguments, and
for these all you need to do is combine what
we’ve learned from the previous cases. First,
you assign your arguments in between the parenthesis,
making sure you have also defined what variable
you want to return, and then ensure that no
matter what path the code takes that you are
always returning that variable type. That
concludes our discussion on functions. As
you can probably tell, functions are an extremely
vast subject area and require a little bit
of practice to fully understand, which is
why later on we’ll recommend some websites
you can use to practice these more difficult
topics.
Now I’d like to switch gears a little bit
and continue our discussion from earlier on
arrays. Arrays, while useful, aren’t the
only way to store and manipulate information.
In fact, there are a multitude of different
ways to store data in computer science including
LinkedLists, Stacks, Queue’s, Maps, Trees,
and many others too.
Right now; though, I’d like to talk about
2 cool, wacky and zany ways to store data
that we haven’t previously covered: ArrayLists
and dictionaries. But before we get into those,
let’s get a little review/reinforcement
of array’s.
As you may remember, arrays are basically
lists of values that are stored together.
When you initialize an array, you give it
a size, and this size is fixed. You won’t
be able to increase the size of the array,
so when you make an array, it’s length is
final. To access the values in an array, you
reference them using an index which starts
at 0. What this means is that the first item
of an array is not at position 1, it is at
position 0, and it’s position is commonly
referred to as it’s index location. So,
to find the nth item in an array, you would
refer to it as index location [n-1]. However,
as the size of an array is fixed, you have
to be careful to not reference a position
that is beyond the total size of the array,
or append too many items to it, as this will
return an error. We also have what are known
as two-dimensional arrays,
which is an array containing an array at each
of its indexes. Or, you could have an array
containing arrays containing arrays containing
arrays containing arrays, depending one what
you’re trying to do. Multidimensional arrays
can be useful in more advanced programs for
organizing a wide volume of related values.
If that’s confusing at all, skip back to
earlier for our full discussion on Array’s,
the time-stamp will be in the description.
Now that we’ve reviewed array’s, let's
go over array lists. Array lists (or just
lists, in Python) can be thought of as a growing
array.
Earlier, we mentioned how you have to be careful
to set an appropriate size of your array and
make sure to only reference and append values
such that you remain within the size of the
array. However, with array lists, this isn’t
a problem. After you initialize an arrayList,
it instinctively has a size of 10, but if
you append a values such that the size of
the arrayList goes beyond 10 elements, an
arrayList will “grow” itself, meaning
that the computer will allocate more memory
to the array to increase its total size so
that the new values can be appended. This
is quite useful when you don’t know the
exact number of values that the array will
need to store, or want the ability to store
values to your heart’s content, such as
making a database with an unknown amount of
user’s that will sign up.
There is a lot more to uncover when regarding
arrayLists, but for this surface-level series,
that is all you pretty much need to know,
so let’s move on to dictionaries.
Now when we talk about dictionaries, we’re
not referencing that thick book you probably
have lying around your house which has thousands
of definitions. In computer science, dictionaries
are like arrays, in that they store multiple
values, however their values are stored very
differently. Rather than being referenced
by their position within the dictionary linearly,
each value is tied to another value that is
used to reference it, or its “key”. Because
of this, we need to throw away all conceptions
of dictionaries as a linear way of looking
at data, since in actuality it is much more
fluid and interchanging. Basically, we say
that each position in a dictionary holds a
key/value pair. When referencing a value in
a dictionary, you will use it’s unique key,
and the dictionary will tell you the value
that is tied to it. Think of it like this,
each time you add an item to your dictionary,
your computer creates a handcrafted box to
store the data, and also custom-makes a jeweled
key, one of a kind, no other like it in the
world. This way, there is only one key that
goes to the box that stores a certain bit
of information. Because each key must be unique,
reusing a key in a dictionary will result
in an error being thrown because having two
keys that are exactly the same would confuse
the computer as to what box, or bit of information,
that key leads to. However, you can store
the same value in multiple key/value pairs,
since the keys would all be different.
Now like I said, dictionaries are more fluid,
making them easier to organize than arrays,
as everything is set up in a more logical
manner. That is to say, it is easier to find
the value you are looking for when you are
using keys rather than simply referencing
their positions. Let me explain what I mean.
Imagine you have a dictionary of prices at
a store where the key is the name of the product
and the value is the price of the item. Maybe
apples cost 1 dollars, milk costs 2 dollars,
and bread costs 3 dollars. You can see that
in the dictionary, each key is the name of
a product, and each key corresponds to the
price of each product. So to find the price
of bread, all you need to do is simply call
the dictionary using the key “bread”,
and the dictionary would return the value
1. This makes it extremely easy to track values
through your code since you’re working with
tangible values rather than numbers which
don’t mean anything to you.
You can also manipulate dictionaries in many
the same ways you can manipulate arrays and
array lists. You can iterate through a dictionary
and perform many operations and comparisons
on the values. If you want to find the product
with the highest price, for example, you can
iterate through the dictionary to find the
value that is the highest amongst the grocery
store items.
Arrays, arraylists, and dictionaries are useful
in their own right, as are the mass amounts
of other ways to store data, and each boast
certain advantages over one another. We already
covered the basics of 3, but since there are
so many, we don’t have time to go in-depth
into each and every one of them, and so in
order to help you grasp the basics of storing
information, we’re now going to talk about
one of the most important functions needed
to understand arrays, which are searching
algorithms.
Now, just as there are many ways to store
information in computer science, there are
even more ways of searching through lists.
Searching algorithms at their core are ways
in which we can look through a list of values
stored in an array, say a patient name list
or a high score list, and find a particular
piece of data. The goal of a searching algorithm
is to simply give the algorithm a string or
object you want it to find and return the
index of the array that contains that string
or object as fast as possible. Now this may
seem simple, but lots of software runs on
the backbone of being able to search through
lists extremely quickly, making searching
algorithms, and in particular efficient searching
algorithms, an important topic to cover. Additionally,
this is the main functionality that arrays
are used for and is the backbone of many of
the methods used with arrayLists as well as
many other storage methods, so knowing them
will take you a very long way.
Typically searching algorithms are used to
return the index of a particular data point
so that it can be used, modified, updated
or checked on. For example, if you are about
to check into a hospital run on an array system
for patients, the staff must search for your
name in the database and by returning the
index of where your name is, they now have
a quantifiable number that they can use to
easily check you in, rent out prescriptions,
schedule you for checkups, update your personal
information, etc. without having to search
through the list for your name every time.
You may think that there is little difference
between searching algorithms, since computers
nowadays can perform millions of calculations
per second, but when you’re a huge multi-billion
dollar corporation trying to find a certain
data point in a list containing thousands
or even millions of data points, small differences
in efficiency are going to make or break the
user experience. Even a 1% improvement in
efficiency can mean big differences in the
amount of time a user is waiting for a simple
task.
Now before we jump into different types of
searching algorithms, we must discern between
the two states that arrays or lists can be
in, either sorted or unsorted. A sorted list
of information is characterized by some sort
of rankable value, whether that be a patient
ID, credit card number, or even by alphabetical
values like username’s or legal names. An
unsorted list is just some random assortment
of related information, not sorted by any
particular order or reason. Some searching
algorithms only work for sorted lists, usually
the more efficient ones, and some work for
both sorted and unsorted lists, although these
are usually less efficient. If you end up
pursuing computer science further, you will
have to deal with both sorted and unsorted
lists, so it's good to know common searching
practices for both
Another thing to note is that we determine
the efficiency of a searching algorithm based
on both the worst case scenario and the average
number of items it must search. We call this
Big O notation, in which each searching algorithm
has an equation which takes in the size of
the array as an integer n, and will output
an worst-case scenario efficiency value that
we can use to compare with other searching
algorithms. We can then also look at how long;
on average, it takes to find an element in
a list. Using these two methods allows us
to easily compare how efficient two algorithms
are. Alright, now that we’ve got some background
on searching, let’s hop right into it.
The first type of search we’ll be talking
about is called a linear search and you’ve
honestly probably used this multiple times
throughout your life. Every time you have
to search for your name on a list of people
you probably follow the same pattern. You
start at the top, check to see if the first
name on the list is yours, if it is. Great.
If not, you move on to the next name on the
list until either you find your name, or you
don’t in which case you leave. A linear
search works the same way, you start with
the first element in the list, compare it
to the value that you’re trying to find,
and if they’re the same you’ve found your
match and return the index of that element,
and if not you move on to the next element
in the list until you either find the thing
you’re searching for or you run out of list
to check. Seems pretty simple right? This
is because linear searches are pretty bad
when it comes to efficiency, especially in
the worst case scenario. If the item you’re
searching for in the list is the last element,
you’re going to have to check the entire
list of items before you find the one you’re
searching for. On average; however, you’re
going to get it about halfway through the
list. This makes the linear search O(n) worst-case
scenario, since in the worst possible case
it will take the entire length of the array,
or n, to find the correct value. The linear
search on average will return the correct
index in O(n/2) or halfway through the list.
The linear search is great; however, since
it can work with both sorted and unsorted
lists, because of the fact that it will eventually
cover every element in the list. The other
search we’ll cover requires the list to
be sorted which may seem like a drawback,
but having a sorted list allows you to use
algorithms that are far more efficient than
the linear search. So overall, the linear
search is a good basic searching algorithm
for if you have an unsorted list, but if your
list is sorted, there are way more efficient
options out there for you, such as the binary
search which we’ll be talking about now.
The binary search uses a recursive process
to break the data in your list down into more
and more manageable bytes, taking advantage
of the fact that it’s sorted, in order to
find the item you’re looking for faster.
This one is much harder to wrap your head
around so let’s start with an example. Let’s
say you have a list of 10 names sorted alphabetically,
like shown on the screen now, and you wanted
to find your name within that list. In binary
search you would first look for the middle-most
name, in this case the one at the 4th index.
Just a quick aside, since there is no “true”
middle, the computer automatically uses the
next one down as the “middle” value. Now,
once you find your middle value, you first
check to see if the name you’re searching
for at the index you’ve chosen, if it is
you simply return that index, but 99.9% of
the time it’s not including right now, so
let’s keep going. If the value at the middle
index is NOT equal to the one you’re searching
for, you check to see if the value you’re
searching comes before or after the middle
index. For example, if you were looking for
the name Brendan and the value at the middle
index was Carl; Brendan obviously comes before
matthew alphabetically and since we know the
list is sorted, what we can do now is ignore
the entire bottom half of the list and just
focus on the top, since we know that if Brendan
is even in the list, it’s going to be in
that top half. Now, we simply treat the top
half of the list as an entirely new entity
and repeat the process over again. Again,
we would find the middle-most element of this
new list of names and again compare it to
the name you’re trying to find. If it’s
the name we’re trying to find, we return
that index, but if not we compare to see if
it comes before or after the middle index.
Going back to our example, let’s say the
middle index of this new list is AJ. Now,
we know that Brendan comes AFTER AJ alphabetically
so we can now ignore the top half of the list
since we know that Brendan is going to be
in the top of our list. Now we repeat this
process again and again until we find the
name we are looking for. So for our example,
the middle index this time is Brendan, and
that’s what we’re searching for so we
finally would return index 2. In binary search,
eventually the index we compare to our search
term will be the same and once it is, we can
return the index and move on. Now if we don’t
find it, which happens after we have eliminated
the entirety of the list without finding our
search term, the algorithm will simply return
a null value to let you know that the item
you’re searching for cannot be found in
the list. The binary search is way faster
and more efficient than the linear search
since we are drastically cutting down the
amount of elements we have to look at, making
the program run faster. In almost 99.9% of
cases in which your list is sorted, the binary
search is going to return a result faster
than the linear search, so if you have a sorted
list, your best option is to go binary. As
for efficiency, the binary search is O(log
n) for the worst case scenario which can be
confusing if you don’t fully understand
logarithms, but all you need to know is that
it is way more efficient than the linear search.
It’s average scenario is actually also O(log
n) as well, which again is infinitely times
more efficient than linear.
Now, while there are other types of searching
algorithms you can use, these two are the
most common for both unsorted and sorted lists,
so we will stop there for now. Up next, we’re
going to be covering one of the most confusing
and important topics in computer science,
recursion.
Let’s start with the most important question:
what exactly does recursion mean? In programming,
recursion refers to functions that repeatedly
call themselves. Meaning, that in the instructions
that occur within a function, one of the instructions
will be a call to that same function you’re
already in.In the extremely primitive example
on your screen now, you can see we have some
function which, in the confines of itself,
calls itself. A recursive function will usually
take into account some integer as an argument,
and will use this to carry out some instructions,
modifying the integer that was entered, before
calling itself again with that new integer
as its argument.
To better understand these functions, let’s
discuss the basics of how we go about programming
one of these recursive functions and create
one ourselves. A really good easy example
of a recursive function is one which sums
all numbers from 1 to n, so let’s make a
recursive function that does just that. The
first thing we need is the actual function,
and we’re going to make it an integer function
which takes in an integer n as an argument.
The reason we do this will be explained later
but for now let’s move on to the base case.
A base case is simply a definite value which
all recursive statements, the ones that are
being repeatedly called as we go through the
function, try to get towards. At the beginning
of the function, we test the value that was
passed in by the argument against the base
case to see if it is satisfied. Usually, these
base cases are some requirements, like if
n, as I described before, reaches a certain
value or is equal to a certain value.
It is extremely important that the base case
is set to some requirement that n will eventually
meet for the same reason that it is important
to avoid infinite loop: we do not want a stack
overflow error to occur. For example, if our
base case was to stop calling the recursive
function when n was greater than 100, and
if it is not, we call the function again but
with n-1, and we started with n as 99, we
would never reach the base case and the recursive
function will repeatedly call itself over
and over and over again, subtracting 1 from
n and hoping that somehow it will eventually
be greater than 100 until your computer crashes,
not fun. So anyways back to our recursive
sum example, let’s make our base case when
n is less than or equal to 1. This way, we
can start at some positive integer n
and subtract from it until it hits at or equal
1, in which case we can exit the recursive
statement. Cool. Now, if n is not less than
or equal to 1, what we want to do is return
the SUM of both n and then the returning value
of our recursiveSum method minus 1. Why do
we add n + the function call? Well let’s
actually go through the function as if we
were the computer and see why. We start with
a call of recursiveSum with n = 3. We know
that 3 is not less than or equal to 1 so now
we try to return a recursive sum of n (which
is 3) and the returning value of recursiveSum
with an n of 2.
We don’t KNOW what the returning value of
recursiveSum with an n of 2 is so we have
to go through the function again, only this
time n is 2.Again n is not less than or equal
to 1, and so this function will go into the
else statement and return…2 plus ANOTHER
recursive statement, in this case the returning
value of recursiveSum with an n of 1. So once
again we have to go through the recursiveSum
function to get the value that will be added
to 2 and then returned and added to 3 and
then returned. Hang in there we’re close.
Now in this function, n IS less than or equal
to 1 and so we return n, which is 1.
Now we take that n, which is 1, and that is
what gets added to 2 in the previous function
call and then returned, so this would return
3. Now this 3 is what gets added to the first
function call, which is three, and so it becomes
three plus three which is 6. And FINALLY after
all that time, we get 6 returned from the
function. Which, if you’ve been following
along at home, 3 + 2 + 1 is indeed 6. Now
this may seem like a waste of time since 1
+ 2 +3 is not a hard operation. But to those
of you saying that I ask you to please give
me the sum of all numbers from 1 to 3,567.
Godspeed. Now recursion is a VERY difficult
concept to wrap your head around, so if you’re
not 100% comfortable with it at the moment,
please rewatch this section of the lecture
to better familiarize yourself with it.
Alright cool, now that we have a little background
on recursion, let’s talk about why it works
so well. Now to understand why and how recursion
works, we must first understand what a stack
is. A stack is a data structure that contains
all of the tasks you instruct your program
to complete. Based on a certain method, your
program will then carry out the tasks you
give it.
It’s called a stack because if we call start
another process before the previous one completes,
the process is “stacked” on top of the
other one such as the animation on your screen
is showing now.
Programs we write will follow the LIFO structure.
For those unfamiliar with accounting, LIFO
means last in first out, or the last item
put on the stack will be the first one removed
from it. Essentially, every time you ask your
computer to complete a task, that task is
added to the stack, and will be the first
one to be resolved. Think of it like a stack
of stones, you can keep adding stones on top
of your pile, but in order to get to one near
the bottom, you first have to remove all the
rocks on top of it. Now when your function
continually calls itself without end; without
a base case, like in our infinite loop example
then the stack will never be resolved, as
items will be continually added to the stack
without any of them ever being completed.
In this case, the memory allocated to the
stack is exceeded, and a stack overflow error
occurs, resulting in your program crashing.
Think of this as if you’re doing chores
and before you complete one chore, you get
called to do another chore, and then before
you can complete that one you get called to
do another one.
Since you keep stacking tasks or chores on
top of each other, the stack of tasks will
never be completed and you will probably die
before ever finishing any of your chores.
This is the same logic that makes infinite
loops crash your program. Recursion works
on these same principles. The initial call
makes a second call which is added to the
stack, and now that one must be taken care
of first, but in that one another function
is called which gets added to the stack, and
so on, until you reach the base case in which
you slowly start going back down the stack.
In conclusion, recursion in general is extremely
useful because by calling the same functions
repeatedly it breaks down the problem into
smaller sections, and results in the program
being more efficient. Small parts of problems
are easier to solve and less taxing to compute
than the entire problem at once, and the computer
can combine these small solutions into the
main solution in the end.
Now as we wind down our introduction to programming
series, we want to take some time and go over
some of the soft skills needed to be a successful
computer scientist since it’s not all about
writing code. In fact, many professional computer
scientists will tell you that the majority
of their job is spent thinking about code
rather than actually writing it. This is because
much of programming boils down to problem
solving. How do we optimize this system, how
can we make this feature for our app? What
type of movement do we want for our game and
how can we program it?
The harsh truth is that no good program has
ever been written simply from the programmer
getting the prompt or idea, sitting down,
hopping on an IDE, and starting to write code.
There are many tasks we should go through
beforehand in order to plan out our code so
we ensure that when the time comes to program,
it’s a clean and easy process, and not riddled
with mistakes and bugs. This is where pseudocode
comes into play.
Think of pseudocode like this, if you wanted
to take a family trip to the grand canyon,
would you simply hop in your car and drive
off and figure things out later? No, because
that would be ridiculous. Instead, you would
spend some time planning out the trip, what
sites or places do you want to visit? What
hotel reservations are you going to have to
make? What kind of things are you going to
do when you get there? What routes or highways
are you going to take and why? All of these
things must be determined out before you can
even think about hopping in your ford explorer.
So how does this translate to pseudocode?
Well, think of our family trip to the Grand
Canyon as a program. Programmers use pseudocode,
pseudo meaning not real, and code meaning,
well, code, as a means to plan out their programs
before they write them, just like how we planned
our trip before going. They throw away syntax
and naming conventions for variables and just
focus on what they want the program to accomplish,
and how they plan on doing that. Pseudocode
is very similar to constructing an outline
for a paper you’re writing. You write down
the main topics of the essay and plan out
your major talking points, but you don’t
worry about the nitty gritty details of it
all such as word choice, grammar conventions,
and proper formatting. By doing this, we allow
ourselves to think freely and not worry about
stressing the small stuff. At least not yet.
Alright, so now that we know WHAT pseudocode
is, let's talk about HOW we write pseudocode.
You see, the best part about pseudocode is
that it can take the form of many different
things for many different people. Each computer
scientist probably has their own methodology
for planning out their code, and since there
are probably hundreds of different methods
of writing pseudocode that are out there,
today I’d like to focus on 3 popular ones
that I think you might find to be extremely
useful.
The first of these are known as flowcharts,
and mainly they can be used to think through
the process of a particular function. A flowchart
is fundamentally a graphical representation
of a function and how it might flow. Many
programmers do this, and lay out the conditional
statements and loops they want as different
blocks in the flow chart, connected by arrows
and charting out every path of their function.
From there, it’s extremely easy to create
test cases and follow them throughout the
flow of the function through the different
blocks and arrows. For example, we could have
a flowchart that goes something like this.
A user enters a number, and if this number
is 8, I want the program to return True; however,
if the number is not 8 then I want to return
false. It’s a great way to visualize what
the function’s overall purpose is and also
look for any errors that you may have missed
when thinking about the function, such as
a missing path. It also abstracts the programming
statements up to simple blocks, making it
easier to modify or change completely. The
best part is, that when you have finished
testing cases you can simply convert the blocks
into statements and you have a well-written
function without any debugging.
Another popular pseudocode technique that
is used often is to simply write out what
you want your code to do chronologically.
Don’t necessarily think about what programming
statements and functions you want to use,
just jot down, from start to finish, what
it is the program you are writing is going
to do step by step. For example, let’s say
you’re making an app that takes in two numbers
and divides them. The pseudocode for that
would look a little something like this. First
I want to prompt the user to enter a number,
then I want to wait for the user to input
the first number. After I get the first number,
I want to again prompt the user to input a
second number. Once they do, I complete the
operation by dividing the two numbers entered
and return the result back to the user. This
all seems like it would be common sense, but
remember that oftentimes we’re not going
to be working with simple multiplication functions,
we may be working with full-scale games, algorithms,
or user interfaces with many different options.
This method allows you the programmer to not
get bogged down with the syntax and conventions
you have to follow, you’re simply making
a note of what the program's ultimate goal
should be, as if you were explaining it to
a friend of yours. This method really lets
you plan out everything that needs to happen
in your program in order for it to run smoothly.
It also ensures you don’t forget about a
piece of an algorithm, or a certain function
that you need to write in afterwards.
And the final pseudocode strategy that I’d
like to talk about today is writing out the
main features you want the user to have when
using your program, and what functions or
smaller programs you’re going to need to
complete those features. Let’s do another
example, say you’re making a banking interface
and on start-up, you want the user to initially
have 2 different options. They can set up
a new account or log into an existing account.
From there, if they log into their account
you then want them to have the functionality
to withdraw money, deposit money, take out
a loan, or pay back a loan. If they decide
to set up a new account, you want them to
be able to create an account, store their
information in a database, and then access
all of the features that a returning member
would have. This may look very similar to
the flowchart, the only difference being this
is abstracted one level higher, over an entire
program rather than just a single function.
If you really wanted to, you could also create
a flowchart that would go through the functionality
of all 4 methods described above. Setting
up the hierarchy like seen on your screen
now makes it clear to see every function and
interface you’re going to have to make.
This prevents you from having to try and shoehorn
a function or feature into an almost finished
program at the last second is not a very fun
experience in the slightest.
So there you have it, 3 pseudocode strategies
you can use to plan out your code before you
even start writing any. The flowchart method,
which is good for thinking through the flow
of a certain function. The write-up method,
which is good for getting the general idea
down for a program, or the functionality planning
method, good for listing out the functions
of a certain program. You can use none of
them, all of them, a mix of them, or even
disregard these and find or create your own.
The main goal here is to drastically minimize
the amount of errors that occur during your
programming and relieve a lot of stress on
your head. The importance of pseudocode cannot
be stressed enough, and if you don’t believe
me, I urge you to try and complete a large
project without it.
Ok, so if you’ve watched the series up until
this point, you have gotten a pretty good
understanding of many aspects of programming,
and also how to plan out your programs. Now
it's time to go out into the real world, and
write some actual code.
But what kind of program? I can hear you asking
me. And the answer is truly whatever you want,
really. As I’m sure you know by now, you
can program just about anything that you have
on your mind, anything from simple games to
complex software. We’ve equipped you with
the basics that are going to be used in pretty
much any program you do decide to write. But
that doesn’t mean every programming language
is perfect for every application. Each language
has its own strengths and weaknesses, and
choosing the right one is very important for
making it easier, or sometimes even just possible,
for you to program what you want. So that’s
what we are going to talk about now: choosing
the best language for what you want to accomplish.
Now, we talked earlier about low level versus
high level programming languages. In case
you forgot, let’s do a quick refresher.
Higher level programming languages have a
high level of abstraction from machine language,
that series of 0’s and 1’s from way back
when, while lower level programming languages
have a low level of abstraction from machine
language. For example, block programming where
you drag and drop programming statements together
like 2d legos would be a high level language,
as it does not take a high level of understanding
of the inner workings of a computer to program
it. The theoretical highest level of a programming
language would be if I could just write down
what I wanted the computer to do in simple
english and it would just work. But, sadly,
that doesn’t exist yet. On the other side
of the spectrum, the lowest level programming
language would be just feeding 0’s and 1’s
into the computer at supersonic speed, which
would be almost impossible and extremely absurd.
So, how do you choose what type of language
is best for your needs? Well, it depends what
you are trying to do, as sometimes you need
very specialized languages to get done what
you want. The world of computer science is
vast and contains many fields, so trying to
cover everything in one language would be
impossible. This has led to the creation of
thousands of different programming languages
each designed for a specific task. Right now
though, we’ll cover some of the most popular
languages and their uses.
Now, if you are trying to design a website,
and delve into that career path, using HTML
and CSS is probably your best bet. HTML is
a markup language that is designed for writing
the content of a website, while CSS is great
for designing the style of the website. You
interact with HTML code every day and you
can even see it right now if you right click
and hit inspect element, this will truly show
you how complex HTML and CSS can be.
Maybe it would be best for you to use a scripting
language. A scripting language is a language
that has many commands for you to use and
that can also be run without needing to be
compiled. Scripts can be faster to write than
actual programs, and tend to be easier to
port between operating systems allowing for
cross-platform support. Scripts can also be
used with websites, oftentimes adding to the
overall user experience of the site. If you
want to go into web design, this might also
be a path for you to go down. Examples of
scripting languages are Perl, PHP, Ajax, and
Javascript.
If you just want to make a general purpose
program, you should probably use a general
purpose language. General purpose languages,
as they sound, have a wide range of applications.
Usually these should be your go-to languages.
Examples of general purpose languages are
Java, C++, and Python. They each have their
own different benefits over one another. Java
is best at developing games and interactive
web pages, Python can act as a scripting language
for web programming as well as writing applications
and data analysis. And C++ is best for writing
applications and system programs. They all
have a variety of packages that you can import
and use to achieve the functionality you need
from them. While selecting the right general
purpose language for your big projects is
very important, for most of your programs
any one of them will work. It really comes
down to preference. Get to know each language,
and decide which one’s syntax rules you
like best and find most comfortable. If you
get to know one general purpose language really
well and enjoy programming with it, you can
apply it to just about any of the programs
you plan on writing. Personally, I tend to
use Python for most of my projects. This is
mostly not due to any functional difference
between Python and any other general purpose
language, though there are a decent amount,
but it is mainly because I find its syntax
rules most convenient and easiest to write
programs with. Overall, either you can consider
the project you plan on doing, and research
and see which language boasts the most advantages
for your purposes, or you can simply become
comfortable with a language and use it for
most of the projects you decide to write.
We’ll now be looking at our final topic
of this introduction to programming mini-series.
You now have the knowledge of basic programming
which will take you far in any language you
decide to learn, you know some good pre-programming
pseudocode strategies to help you design your
code from the ground up, and you might already
have a good idea as to the type of programming
language you might want to start with, so
what’s the next step? How can I learn that
language and what applications can it be used
for? Well that’s what we’re going to be
covering now, so let’s jump right into it.
Starting with the biggest question which is
what’s the next step. Well, now that you
might know which type of language you might
be interested in, research that language and
find out whether or not you truly want to
pursue that programming language. Most languages
like python or C++ will have either an official
website where you can read up on, or a wikipedia
page which will provide you with useful information
in deciding whether or not you want to pursue
that path. From there, the next step is to
actually learn the language, which can be
done right here on YouTube. While we have
taught you the basics of any programming language,
each specific language is going to expand
upon the basic concepts and so watching tutorial
videos on a certain language is going to be
very beneficial. Many websites will try to
get you to purchase paid courses or take classes
which cost money, but you can find extremely
good courses here on YouTube for absolutely
0 cost to yourself. I would start with an
introduction series like the one you’re
currently watching, but for the language you
have chosen and work your way through that
series, picking up on the syntax and rules
of that language until you become comfortable
with it.
Once you do that, you come to a crossroads.
You know how to program in a certain language,
but you may be completely clueless as to what
to make in that language. Programmer’s block
can leave you uninspired and not want to continue
programming so I’d like to give you a few
sites to help out.
First is codingbat, a completely free website
which has hundreds of coding challenges in
Java and Python to help you refine your programming
skills and even learn some programming short-cuts
and tips. This is great if you want to get
better at improving your efficiency and need
something to hone your skills as a developer.
The next is CoderByte, which offers over 200+
challenges that you can complete in over 10
different languages, something that is sure
to help you improve. The final website I’d
like to talk about is hackerRank, which not
only provides programming challenges to keep
you on your toes, but also provides support
for using you programming skills to find jobs
or internships, something you’ve probably
definitely thought about if you are taking
programming up as a skill. These and many
more websites exist solely to keep you interested
in code and work on refining your skills to
become better, you just have to find them
because they’re certainly out there.
Now if you’re a teenager watching this series,
I also encourage you to take the programming
classes in your high school. AP Computer Science
Principles and AP Computer Science A are both
amazing courses which will help you greatly
in the future, and are also incredibly informative
and important to colleges. Your school might
also offer other classes in the field of computer
science, including ones on data structures,
game design, and data science. Any and all
classes you can take to help expand your knowledge
of programming and help you find your niche
is going to help tremendously.
As you can see, the world of code has now
been opened up to you. These are just a few
examples of where you can go from here but
there are many more we didn’t talk about.
You can get into GitHub and start contributing
to projects, you can work on your own projects
and collaborate with others, the possibilities
are endless. The next step is up to you.
This concludes our introduction to programming
mine-series, we hope you enjoyed watching
it as much as we enjoyed making it. If you
enjoyed the series as a whole, consider subscribing
to our channel NullPointerException, which
will be linked in the description, for more
content coming soon. Thanks for watching.
