Here's the basic version, using str.isdigit
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
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:
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]
.
passwd
a valid password?¶This is mostly an exercise in finding the right string methods
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.
>>> check_password(’I<3csc108’)
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
#c.isupper() == True instead
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
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
.
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
Let's try something concise, using str.islower and the in
operator
def is_vowel(c):
return c.lower() in "aeiou"
Let's build up the disemvowelled version of a string by first initializing the result to ""
, and then adding in all the non-vowels
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
def reverse_str(s):
'''return the reversed version of s
reverse_str("abc") -> "cba"
'''
res = ""
for c in s:
res = c + res
return res