## Counting non-digits in a string¶

Here's the basic version, using str.isdigit

In [1]:
def count_non_digits(s):
count = 0
for i in range(len(s)):
if not s[i].isdigit():
count = count + 1

return count



A lot of people would be tempted to implement str.isdigit themselves. This is not necessary, but it's good for practicing

In [2]:
def is_str_all_digits(s):
'''
(str->bool)
Return True iff s consists only of digits
(Note: str.digit is a little bit more complext than that)
'''
for i in range(len(s)):
if s[i] not in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']:
#if s[i] not in "0123456789" is more concise and would work as well
return False
return True


Here's a slightly more concise version, which uses a new type of loop construct:

In [3]:
def count_non_digits(s):
count = 0
for c in s:
if not c.isdigit():
count += 1
return count


Instead of looping through indices inside s (0, 1, 2, ...., len(s)-1), we can loop through the elements of s directly. This is preferable in situations where all we ever use the i in for i in range() for is to access the element s[i].

## Is passwd a valid password?¶

This is mostly an exercise in finding the right string methods

In [5]:
def password_is_valid(passwd):
""" (str) -> bool
A strong password has a length greater than or equal to 6, contains at
least one lowercase letter, at least one uppercase letter, and at least
one digit. Return True iff passwd is considered strong.
True
"""

if len(passwd) < 6:
return False

#First, set up variables that tell us whether we've encountered
#a lowercase letter, and uppercase letter, or a digit
#Initially, they are all set to False
has_lowercase = False
has_uppercase = False
has_digit = False

for c in passwd:
if c.isupper():   #Note: blah == (blah == True), so there's no point to going
has_uppercase = True
elif c.islower():
has_lowercase = True
elif c.isdigit():
has_digit = True

#Now, return True if all three are True
#(i.e., has_lowercase is True, *and* has_uppercase is True, *and* has_digit is True)
return has_lowercase and has_uppercase and has_digit


## First even number¶

Here, we just need to keep checking whether the number is even until we encounter an even number, and then return. To check whether a number n is even, we can check whether n % 2 (the remainder of the division of n by 2) is even. If we haven't returned inside the for-loop where we keep checking for evenness, we return -1.

In [6]:
def first_even(items):
""" (list of int) -> int
Return the first even number from items. Return -1 if items contains no even numbers.
>>> first_even([5, 8, 3, 2])
8
>>> first_even([7, 1])
-1
"""
for n in items:
if n % 2 == 0:
return n

return -1


## Is the letter a vowel?¶

Let's try something concise, using str.islower and the in operator

In [7]:
def is_vowel(c):
return c.lower() in "aeiou"


## Disemvowelling¶

Let's build up the disemvowelled version of a string by first initializing the result to "", and then adding in all the non-vowels

In [8]:
def disemvowel(s):
#dsmvwl = ""   #too funny of a name... Let's just go wih res
res = ""
for c in s:
if not is_vowel(c):
res += c   #the same as: res = res + c

return res


## Bonus: reversing a string¶

In [9]:
def reverse_str(s):
'''return the reversed version of s

reverse_str("abc") -> "cba"

'''

res = ""
for c in s:
res = c + res
return res