Search

Coding Python ATM Machine That Gives Only $5 And $8

 

I recently went to the bank to withdraw some money. The attendant at the ATM told me the ATM can only give out money in 1,000 naira and 500 naira notes. When he told me, I started wondering if I could be able to code a machine that gives out money based on a specified denomination. So, I told myself, what if the machine can only give out $5 and $8 change. How can I code that?

 I nearly got knocked over on my way home thinking about the problem. But since problems are to be solved, I came up with a nice solution in my head that I want to describe.

How not to go about it.

Initially, I starting thinking of using the modulo 5 or modulo 8. That was nice and easy. But I came to a caveat, if I used modulo 8, I could only get change for amounts that were definitely multiples of 8 and not of 5. If I used modulo 5, I could only get amounts that were definitely modulo 5 and not 8. That would not work out. I started thinking of the nature of the problem before going down to the solution.

The nature of the problem.

What if the machine gives out change only in $5 and then has an internal memory that keeps track of how much change it could be able to give in $8 from what remains based on the amount already given out in $5? For example. It could not give out change for $12 because after taking out $5 what remains is $7. But it could give out change for $13, or $15.

Another aspect of the problem is that if your amount is below $5, it cannot give you any change because it only has $5 and $8. So, you have to forfeit it. Too bad!

Then, I had to start giving out change based on the smaller amount which is $5. First of all, I first check if the amount is a multiple of $5. If it is, that is easy, just give out change based on the number of $5 that is required by doing integer division. But if the amount is not a multiple of $5, then we need to do a little arithmetic here.

Let’s say we can give out $21 in change. What combinations of $5 and $8 do we use? Since we are starting out with $5 as the smaller amount. We first check if $21 is a multiple of $5. No, it’s not, so the change will include $8. Let’s give 0 $5. Is the remainder a multiple of $8? No because the remainder is $21 and it is not a multiple of $8. Then let’s give out the first $5. The remainder becomes $16. Is the remainder a multiple of $8? Yes, because 2 $8s give $16. So, we have our change.

Let’s take another example. Suppose we have $28. Is $28 a multiple of $5? No. So the change will include $8. Let’s give out 0 $5. Is the remainder, the original $28 a multiple of $8? No, it is not. So we know our change will include both $5 and $8. So, let’s give out 1 $5. After giving out a single $5, we remains is $23 which is not divisible by $8. So we give out the second $5, that is, $10. The remainder is now $18 which is not divisible by $8. So we give out the next $5 which makes it 3 of $5 or $15. The remainder is $13 which is not divisible by $8. But we have not exhausted the number of $5 we can give out, so we will keep giving out $5 until we exhaust our supply. So now we give out our 4th $5, which is $20. The remainder is now $8 and it is divisible by $8. So, we have our answer. If we have $28 the change we can give using just $5 and $8 is 4 $5 and 1 $8.

Now, let’s take an example of an amount we cannot give change for you to see how the code works. Let’s take $27. First we ask if it is divisible by $5? Not it cannot, so we will also give $8. So, giving just no $5, is $26 divisible by $8? No, it is not, so if we can give out change, then it will include both $5 and $8. But can we? I said we cannot. Let’s prove it. So, we’ll calculate the number of $5 iterations we can go through in the code. That is, the maximum number of $5 we can give since we are starting with $5 and that is 5 five dollars. So, we will keep giving out $5 and comparing the remainder with $8 until we exhaust our supply of $5. $27 divided by $5 without remainder is 5. So, we will give out $5 five times. Let’s give out the first $5. The remainder is $22 and it is not divisible by $8. So we give out the second $5 to make it $10. The remainder is $17 which is not divisible by $8. So we give out the third $5 making it $15 and the remainder, $12, is not divisible by $8. So we give out our fourth $5 to make it $20. The remainder after that is $7 which is not divisible by $8. We could stop here and say that since the remainder is lesser than $7 there is not way. But the code will check one more time for the fifth $5 and that is $25 to give a remainder of $1 which is not divisible by $8 without remainder. So, we cannot give out accurate change using just $5 and $8 when the amount is $27.

Here is the code snippet which you can run from here:

There is a handy function I have included, print_change. It takes the number of $5 and $8 along with the amount we can give change in and prints out the result on the screen. It makes the printing look elegant and beautiful.

And in case you did not notice, you could see from the printed result that our $5 and $8 ATM machine can give change for any amount above $27. It can give you change for all amounts from $28 to infinity. Just lovely machine that doesn’t like the poor.

You can download the script from this link if you desire and run it on your machine.

Email Validity Check Using A Python Filter

I encountered a problem recently of how to check for email validity. When doing web scraping or handling data sets, you get to play with emails a lot and having a handy function that does this check in an efficient way would be useful. So, I decided to come up with a function that does it.

 

In this article, I will be using a filter and a list of emails to do the check. I decided on using a list of emails because it would better help you understand what I am doing. Most times, if you are scraping data, you might have to implement a file handler for it. But not to worry, converting from one to the other is easy.

What are valid emails?

Valid emails have the form: username@websitename.extension. Each of the elements have their different rules. For example, username can usually contain letters, digits, dashes or underscores. Website name can only have letters and digits while the extension is usually at least 2 and maximum 3 letters in length. So, having that we will use regular expressions, or regex, to match for valid emails. Remember earlier posts, finding a match with regular expressions and also understanding python search and match regex methods where I told you that when you have to search strings think regex first? This is a handy application.

So, this is the regex we will be using. I have modularized it in a handy function called fun.


def fun(s):
    # return True if s is a valid email, else return False
    pattern = r'^[\w-]+@[a-zA-Z0-9]+\.[a-z]{2,3}$'   
    m = re.match(pattern,s)
    if m:
        return True
    else:
        return False 

Now let me explain the regex above in case you have not read the earlier posts on regex. Just look at the value for the variable, pattern. I will be explaining each of the strings in the pattern. "^[\w-]+" is the pattern to match the username. It says start from the beginning of the string. That is why we are using match in the next line. Match one or more letters, digits, or underscores (as \w), or match one or more dashes (as -). That’s for the username validation. The next string is "@". Just match @ after the earlier username match. Now comes the website name matching string. "[a-zA-Z0-9]" states that after the @ symbol, we should look for a website name as one or more letters or digits. That’s that. Next comes "\.". What I want to match here is the single period, ., after the website name, but I have to backslash it. Without a backslash the "." symbol says match any character but with a backslash it means to match the period, ., character. Then, lastly is the end of the pattern, the extension match. I denoted this with "[a-z]{2,3}$" and what this means is that match at least 2 or at most 3 lowercase letters which are at the end of the string. Note that this must be at the end of the string. Sometimes we could get an extension like .server and that would not be a match unless it is a .com, .co, .io, .net etc.

So, that’s for validating the email. Now how does a filter come in handy to do this.

What the filter function does.

The syntax of the filter function is filter(function, iterable). What it does is to take a sequence and filters it with the help of the given function. Each item in the sequence is filtered against the function and then a list is returned of the filtered sequence. So, what we are doing here is taking each email and filtering it against the fun function using the regex pattern match. The filter code is just a one liner – just filter it using the given function.


def filter_mail(emails):
    ''' input a sequence of email string 
    returns the elements in the sequence that returns True
    when filtered for email validity.'''
    return list(filter(fun, emails))  

In the complete code, I also included a print_email function. What the print_email function does is take an email, call the filter function which returns a list of the filtered emails, sort the list and then print the list. I wanted to make the print_email function a helper function to the filter_email function but decided it might not be readable that way, so had to leave it as is.


def print_email(emails):
    filtered_emails = filter_mail(emails)
    filtered_emails.sort()
    print(filtered_emails)

So, that is it – validating emails using a filter function with regular expressions. I have included two lists, a list containing invalid email and one containing valid emails for you to run and see how it was done.

You can download the script if you want to run it on your machine.

If you have any questions, you can leave it in the comments. Also, be sure to subscribe to my blog so you can receive new articles as they are posted.

Matched content