# Some Short Introductory Coding Exercises

Let’s get started on some introductory computation exercises. We will work in Python, but the general ideas are applicable to any programming language. The goal of this guide is to provide enough scaffolding to give you direction, but not to hand-hold you through the process.

It’s assumed that you’ve had some basic exposure to programming (e.g. working through a Codecademy course) and that you know about variables, functions, if statements, for loops, while statements, arrays, strings, and dictionaries. Ideally, you’ve learned some object-oriented programming (classes, attributes, methods) as well.

It’s important to understand that in coding, you should always try to do as much as you can on your own, using Google as a resource if needed. Don’t know what a word means? Google it. Don’t know how to run a python file from the command line? Google it. Don’t know how to get the second character of a string? Google it. You get the idea :)

Okay, let’s get started. First, get set up.

2. On Github, create a repository called exercises.
3. On Replit, create a Python repl named exercises, clone your Github repository, and create a file hello-world.py.
4. Commit and push your file with the commit message "Completed my first commit."

Then, write the following functions in hello-world.py. Write them from scratch, i.e. don’t use any external libraries and don’t use any built-in functions that allow you to bypass the use of for loops, while loops, or if statements. In particular, don’t use Set, Counter, or array.extend. But you can use primitives like len(array) and array.append.

• check_if_symmetric(string) - returns True if the input string is symmetric (i.e. a palindrome), and False if not. You can ignore capitalization.
• convert_to_numbers(string) - returns an array of numbers corresponding to letters in a string, where space = 0, a = 1, b = 2, and so on. For example, convert_to_numbers('a cat') should return [1,0,3,1,20].
• convert_to_letters(array) - this is the inverse of convert_to_numbers. For example, convert_to_letters([1,0,3,1,20]) should return 'a cat'.
• get_intersection(array1, array2) - returns an array consisting of the elements that are in both array1 and array2. There should be no repeated elements in the output array.
• get_union(array1, array2) - returns an array consisting of the elements that are in either array1 or array2. There should be no repeated elements in the output array.
• count_characters(string) - counts the number of each character in a string and returns the counts in a dictionary. Lowercase and uppercase letters should not be treated differently. For example, count_characters('A cat!!!') should return the dictionary { 'a': 2, 'c': 1, 't': 1, ' ': 1, '!': 3 }.
• is_prime(N) - checks whether an input integer $N>1$ is prime by checking whether there exists some $n \in \left\{ 2, 3, 4, \ldots, \lfloor N/2 \rfloor \right\}$ such that $n$ divides $N.$ (The $\lfloor \,\,\, \rfloor$ function is called the floor function -- if you're not sure what this is, Google it.)

In a file test-hello-world.py, write a variety of tests for each function. Two example tests are shown below for check_if_symmetric. You can use these, but you should also write more tests that cover all the edge-cases you can think of. (For example, an empty string is symmetric, and the string '!ab123 4 321ba!' is also symmetric.)


from hello_world import check_if_symmetric

tests = [
{
'function': check_if_symmetric,
'input': 'racecar',
'output': True
},
{
'function': check_if_symmetric,
'input': 'batman',
'output': False
}
]

num_successes = 0
num_failures = 0

for test in tests:
function = tests['function']
test_input = tests['input']
desired_output = tests['output']
actual_output = function(test_input)

if actual_output == desired_output:
num_successes += 1
else:
num_failures += 1
function_name = function.__name__
print('')
print(f'{function_name} failed on input {test_input}');
print(f'\tActual output: {actual_output})
print(f'\tDesired output: {desired_output})

print(f'Testing complete: {num_successes} successes and {num_failures} failures.')


Run your tests and fix any failures. If you struggle with anything, don’t ask for help until you’ve made a thorough effort to debug the issue on your own. Here are some debugging tips:

1. Print out everything. Within the function that you're debugging, print out every manipulation that your code makes, even if you don't think it's making a mistake there. Bugs often show up in places you don't expect. Also, don't just print out the values of variables -- rather, you should label your printouts with text descriptions of what they represent.
2. Identify the first discrepancy. Manually work out what the printouts should be, and then look for the first instance when the actual printouts deviate from what you're expecting.
3. If the discrepancy involves a helper function, then isolate the issue in a separate file and return to step 1. If the issue is occurring when you're passing inputs into a helper function, then create a separate file where all you do is pass those inputs into the helper function. Now, you need to debug the helper function, which means you go back to step 1 (print out everything) with this helper function.
4. If the discrepancy does not involve a helper function and you still can't figure out what's going wrong, then ask for help. Be sure that you can explain what you've done to debug the issue so far, including the furthest point back to which you've traced the bug. Keep your debugging print statements in your function.

Your code must be clean and work in general. If you have thorough test coverage, you can be fairly confident that your code works in general. To be confident that your code is clean, do the following:

• Run your code through a linter (like pep8online) and fix all the issues.
• Use proper cases. In Python, variables, functions, and files use snake_case (all lowercase with underscores separating words), while classes use PascalCase (no spaces with each separate word capitalized).
• Make sure that your variable names are clear and appropriate. Variables and classes should be nouns functions (including methods) should be verbs names should be descriptive. It's okay to make a name several words long if you need. For example, compute_conditional_probability() is WAY better than cp() or prob().

Tags: