#100DaysOfCode - Day 5

#100DaysOfCode - Day 5

Loops

·

8 min read

Something I am comfortable with today. Although, I have to stick to the constraints of the lessons. There are certain tasks within today's lessons that could have done with some built-in methods but to expand on the previous lessons these were to be avoided.

Add the Evens From a range of integers get the sum of the even numbers within the range. range always excludes the last value within the range, and a solution to include that value had to be added to the code. Again I used functions, so that I could reuse the function with a number of different ranges to assess my work better. Rather than keep manually pumping in values for the range.

def even_adder(a,b):
    ''' 
        Add all the even numbers between two values inclusive, using range method
    '''
    if a > b: # Error catch
        c = b 
        b = a 
        a = c 
    total = 0
    b +=1 # This negates the exclusion of the second value
    for i in range (a,b):
        if i%2 == 0:
            total += i
    print(total)

Note: I added in error management in case the first parameter were to be higher than the first. As I wanted the sequence to increase not decrease.

The second part of this lesson was to use the step feature of the range method. A slightly different piece of code, as I had to ensure the steps didn't focus on the odd values in the range if the initial value in the range was an odd number.

def even_stepper(a,b):
    '''
        This is version using the step method in range.
    '''
    total = 0
    if a%2 != 0:
        a +=1
    b +=1  # This negates the exclusion of the second value
    for i in range(a,b,2):
        if i%2 == 0:
            total += i
    print(total)

Average from a List
Taking a list of heights, deduct the average height of all the entries. This was the lesson that was not to use len or sum. With the output to be a whole number. I have left the remarked code that I used in my testing.

# average_height.py
'''
    Input a number of height into a list.
    Do not use LEN or SUM, but calulate the number of items in the list, 
    and the total sum of these values.
    This will allow for the calculation of the average, as an integer, not float.

'''

student_heights = input('Input heights here: \n').split()
# student_heights = ['125', '125', '125', '125']
number_of_students = 0
total_of_heights = 0

for i in student_heights:
    number_of_students +=1
    i = int(i)
    total_of_heights += i

# average_height_i = int(total_of_heights/number_of_students)
average_height = round(total_of_heights/number_of_students)
# print(number_of_students)
# print(total_of_heights)
# print(f'The Average height is {average_height_i}')
print(f'The Average height is {average_height}')

Highest Value in a List Following on from the previous lessons, the simplest solution is to compared each value with the previous value in the list and if the second one is higher, change the variable labelled highest_score to that second value. On completing the iteration of the list the remaining highest_score value would be the highest value in that list.
I added in the average to my code as an extra.

# highest_score.py
'''
    Getting the highest score from a list.
    This is very similar to the previous task of the average height.
    I have included the average score and used the same prinicipal here.
    GEtting the highest score is based on whether the next iterate from the list is
    higher that highest_score and if it is then change the highest_score to that value,
    otherwise ignore and iterate to the next score in the list.
'''

student_scores = input('Input scores here: \n').split()
# student_scores = ['125', '125', '125', '130']
number_of_scores = 0
total_of_scores = 0
highest_score = 0
for i in student_scores:
    number_of_scores +=1
    i = int(i)
    total_of_scores += i
    if i > highest_score:
        highest_score = i

average_score = round(total_of_scores/number_of_scores)

print(f'The highest score is {highest_score}')
print(f'The average score is {average_score}')

Fizz Buzz
The 'interview' question. In a range of numbers, if the number is divisible by 3, with no remainder, print Fizz. If the number in the range is divisible by 5, with no remainder, print Buzz. If the number in the range is divisble by both 3 and 5, with no remainder, then print Fizzbuzz. Otherwise just print the number.
Construction of a For loop to check each value in the range is the starting point of the interesting code. Followed by an if/elif/else method to determine which output is required for each value.
The clue to getting this right when you construct the if/elif/else method. Don't follow the language of the question, as the if/elif/else method looks for the first True requirement and ends there.
If you started the method with value modulo 3 you wouldn't get any FizzBuzz, as each value that were divisible by both 3 and 5 would show True at modulo 3 and not reach modulo3 and 5.
I could have written the below a lot simpler but there is a reason I wrote it the way I did.

# fizzbuzz.py
'''
    Count a sequence of numbers.
    If the number is divisbke by three say 'Fizz'
    If the number is divisble by five say 'Buzz'.
    If the number is divisble by both three and five say 'FizzBuzz'

    I am creating a list initially. This is a step that is not needed just
    to solve the problem as the range (0,101) could have replaced the variable
    name in the for loop of the fizzbuzz.
    I just like to break out variables, that can be changed, from the main code to prevent
    errors in the future.
'''
# Create list of numbers
number_list = []
for i in range (0,101):
    number_list.append(i)

for i in number_list:
    if i %3 ==0 and i %5 ==0:
        print('FizzBuzz')
    elif i %3 ==0:
        print('Fizz')
    elif i %5 ==0:
        print('Buzz')
    else:
        print(i)

Password Generator
This was the project of the day. From the lesson I understood there were a few ways to write this. I wanted to explore a couple of ways. After reading up the python doc on random and I wanted to see what I could do.
The first version was the creation of the password from a list. As the list is iterable I was able to use the random.shuffle method in creating the password. I removed the list of letters as the formatting of the code gave each character a single line. just remember to quote and comma the list ['a','A',....]

# password_generator_easy.py
"""
    The generator should ask for:
        The number of letters, number of integers and special characters.
    A pretty basic list of random characters.
    The lesson for the easy generator, creates a list, something
    that is easy to shuffle and convert into than a string. 
"""
from random import randint, shuffle
from typing import final


def password_generator():
    # Number of letters
    letters = [ ** Add characters lower/upper case here**    ]
    # Number of integers
    integers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    # Number of specials
    specials = ["!", "#", "$", "%", "&", "(", ")", "*", "+"]
    password = []

    number_of_letters = int(input("How many letters do you want in the password? \n"))
    number_of_integers = int(input("How many numbers do you want in the password? \n"))
    number_of_special = int(
        input("How many special characters do you want in the password? \n")
    )

    # number_of_letters = 3
    # number_of_integers = 3
    # number_of_special = 3

    for i in range(0, number_of_letters + 1):
        x = randint(0, (len(letters) - 1))
        password.append(letters[x])

    for i in range(0, number_of_special + 1):
        x = randint(0, (len(specials) - 1))
        password.append(specials[x])

    for i in range(0, number_of_integers + 1):
        x = randint(0, (len(integers) - 1))
        password.append(str(integers[x]))

    # for i in range (0, number_of_letters):
    #     x = randint(0, (len(letters)-1))
    #     password = password + letters[x]

    #     x = randint(0, (len(integers)-1))
    #     password = password + str(integers[x])

    #     x = randint(0, (len(specials)-1))
    #     password = password + specials[x]

    shuffle(password)
    final_password = ''
    for i in password:
        final_password += i
    print(final_password)

if __name__ == "__main__":
    password_generator()

I wanted to try using random.sample, with the password characters being stored in a string. Yes, I know this would be memory heavy, adding each character to a string creates a new string object in memory, and would rely on the garbage cleaner to mop up. It's a small code, so I am not concerned about this, this time. It did although me a way to managed a string in a new way for me, and that was my goal as I worked through the errors to get to the correct solution.

# password_generator.py
"""
    The generator should ask for:
        The number of letters, number of integers and special characters.
        Add in a method to shuffle up the characters in the password.
        When using the string to hold the characters,random.shuffle gives an error, 
        but random.sample can be used to split and join the characters into a new string. 
        The offical doc, directs the coder from using shuffle to sample.
        https://docs.python.org/3/library/random.html
"""
from random import randint, sample


def password_generator():
    # Number of letters
    letters = [ ** Add characters lower/upper case here**    ]
    # Number of integers
    integers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    # Number of specials
    specials = ["!", "#", "$", "%", "&", "(", ")", "*", "+"]
    password = ""

    # number_of_letters = int(input("How many letters do you want in the password? \n"))
    # number_of_integers = int(input("How many numbers do you want in the password? \n"))
    # number_of_special = int(
    #     input("How many special characters do you want in the password? \n")
    # )

    number_of_letters = 3
    number_of_integers = 3
    number_of_special = 3

    for i in range(0, number_of_letters):
        x = randint(0, (len(letters) - 1))
        password = password + letters[x]

    for i in range(0, number_of_integers):
        x = randint(0, (len(integers) - 1))
        password = password + str(integers[x])

    for i in range(0, number_of_special):
        x = randint(0, (len(specials) - 1))
        password = password + specials[x]

    print(f"Before the shuffle {password}")
    sample_password = "".join(sample(password, len(password)))
    print(f"After the shuffle original is still accessible {password}")
    print(f"After the shuffle the new string {sample_password}")


if __name__ == "__main__":
    password_generator()

Now that's me done for Day 5.
GitHub