Python: trying to check for a valid phone number - python

I am trying to write a program that accepts a phone number in the format XXX-XXX-XXXX and translates any letters in the entry to their corresponding numbers.
Now I have this, and it will allow you to reenter the correct number if its not correct to start, but then it translates the original number entered. how do i fix this?
def main():
phone_number= input('Please enter a phone number in the format XXX-XXX-XXXX: ')
validNumber(phone_number)
translateNumber(phone_number)
def validNumber(phone_number):
for i,c in enumerate(phone_number):
if i in [3,7]:
if c != '-':
phone_number=input('Please enter a valid phone number: ')
return phone_number
elif not c.isalnum():
phone_number=input('Please enter a valid phone number: ')
return phone_number
return phone_number
def translateNumber(phone_number):
s=""
for char in phone_number:
if char is '1':
x1='1'
s= s + x1
elif char is '-':
x2='-'
s= s + x2
elif char in 'ABCabc':
x3='2'
s= s + x3
elif char in 'DEFdef':
x4='3'
s= s + x4
elif char in 'GHIghi':
x5='4'
s= s + x5
elif char in 'JKLjkl':
x6='5'
s= s + x6
elif char in 'MNOmno':
x7='6'
s= s + x7
elif char in 'PQRSpqrs':
x8='7'
s= s + x8
elif char in 'TUVtuv':
x9='8'
s= s + x9
elif char in 'WXYZwxyz':
x10='9'
s= s + x10
print(s)

import re
def validNumber(phone_nuber):
pattern = re.compile("^[\dA-Z]{3}-[\dA-Z]{3}-[\dA-Z]{4}$", re.IGNORECASE)
return pattern.match(phone_nuber) is not None

If you don't want to use regular expressions: You can use isalnum to check if something is a number or letter. You can access the nth character in a string using mystr[n] so, you could try:
def validNumber(phone_number):
if len(phone_number) != 12:
return False
for i in range(12):
if i in [3,7]:
if phone_number[i] != '-':
return False
elif not phone_number[i].isalnum():
return False
return True
To see what phone_number[i] is doing, try this:
for i in range(len(phone_number)):
print i, phone_number[i]
Using enumerate:
def validNumber(phone_number):
for i,c in enumerate(phone_number):
if i in [3,7]:
if c != '-':
return False
elif not c.isalnum():
return False
return True
Once you have it working, you should use it later (inside of main) like:
def main():
phone_number = '' # an invalid number to initiate while loop
while not validNumber(phone_number):
phone_number = input('Please enter a phone number in the format XXX-XXX-XXXX: ')
translated_number = translateNumber(phone_number)

You should use a regex to match the text.
the string module has a translate function that will replace most of your logic
code example below. note how i cast everything into lowercase to simplify the regex and translation.
import string
import re
RE_phone = re.compile("^[a-z0-9]{3}-[a-z0-9]{3}-[a-z0-9]{4}$")
map_in = 'abcdefghijklmnprstuvwxyz'
map_out = '222333444555667778889999'
mapped = string.maketrans( map_in , map_out )
def main():
while True:
phone_number= raw_input('Please enter a phone number in the format XXX-XXX-XXXX: ')
phone_number = phone_number.lower()
if RE_phone.match(phone_number):
break
print "Error. Please try again"
print translateNumber(phone_number)
def translateNumber(phone_number):
return phone_number.translate( mapped )
main()

you can go for:-
def contact_validate(s):
try:
int(s)
return True
except ValueError:
return False
>>> print contact_validate("+12345")
True
>>> print contact_validate("75.0")
False
>>> print contact_validate("hello")
False

I think this can be helpful
def checkvalidNumber(phone_number):
T={"-":0,"+":0,"_":0}
for i in str(phone_number):
if i in list(T.keys()):
if (i=="_" or i=="-") and (T["-"]>=1 or T['_']>=1):
return False
elif i=="+" and T[i]>=1:
return False
else:
T[i]+=1
elif not i.isdigit():
return False
return True

This is a fairly pythonic way to do it in my opinion
def validNumber(phone_number):
return all([x.isdigit() for x in phone_number.split("-")])
It splits the input at "-", checks that each remaining item is a number and returns a single True or False value.
all() - returns True if bool(x) is True for all x in iterable

Related

FOR loop in function exists before ending

I know there are already countless clones of Wordle. Nevertheless I try to program my own version.
In the function is_real_word it should be checked whether the entered word of the user occurs in the word list. If so, the variable check = True.
However, the FOR loop is always exited when the counter is at 1.
The file "5_letter_words.txt" contains 3 entries: wetter, wolle, watte
And last but not least also the return value for eingabewort is sometimes NONE. And I don't know why?
import random
def word_list():
wordle = []
with open("5_letter_words.txt", "r") as file:
for line in file:
myTuple = line.strip()
wordle.append(myTuple)
return wordle
def random_word(wordlist):
return random.choice(wordlist)
def is_real_word(guess, wordlist):
for word in wordlist:
if guess == word:
return True
return False
def check_guess(guess, randomword):
randomword_tuple = []
guess_tuple = []
length = len(randomword)
output = ["-"] * length
for index in range(length):
if guess[index] == randomword[index]:
output[index] = "X"
randomword = randomword.replace(guess[index], "-", 1)
for index in range(length):
if guess[index] in randomword and output[index] == "-":
output[index] = "O"
randomword = randomword.replace(guess[index], "-", 1)
return ''.join(output)
def next_guess(wordlist):
guess = input('Please enter a guess: ')
guess = guess.lower()
valid = is_real_word(guess, wordlist)
if valid == False:
print('Thats not a real word!')
next_guess(wordlist)
else:
return guess
def play():
target = []
target = word_list()
zufallswort = str()
zufallswort = random_word(target)
eingabewort = next_guess(target)
print('Eingabewort: ', eingabewort)
print('Zielwort: ', zufallswort)
play()
Could you check if your function word_list returns the list?
You dont give a clear path, only the file name.
If it works, try:
def is_real_word(guess, wordlist):
for word in wordlist:
if guess == word:
check = 1
break
return check

Python code doesn't execute on first run

Using Spyder Python 3.6 this code does not execute, says that the method ispal is not defined. However when I run it and put in an integer first (say my string input = 0), then it will run after and recognize the method. It seems like I have to go through a branch other than the call to the method first. Thanks for the critique.
s = input('enter a string: ')
s1 = s
s1 = s1.lower()
s1 = s1.replace(',', '')
s1 = s1.replace(' ', '')
if s1.isalpha():
if ispal(s1) == True:
print(s,' is a palindrome')
else:
print(s,' is not a palindrome')
else:
print('you entered illegal chars')
def ispal(s1):
if len(s1) <= 1:
return True
else:
#if the first and last char are the same
#and if all
return s1[0] == s1[-1] and ispal(s1[1:])
First, as pointed out by TGKL you're calling ispal before it's defined. So define it before calling, i.e:
def ispal(s1):
if len(s1) <= 1:
return True
else:
#if the first and last char are the same
#and if all
return s1[0] == s1[-1] and ispal(s1[1:])
if s1.isalpha():
if ispal(s1) == True:
print(s,' is a palindrome')
else:
print(s,' is not a palindrome')
else:
print('you entered illegal chars')
Second your palindrome recursive function is right except when you call ispal inside itself. Instead of ispal(s1[1:]) you should do ispal(s1[1:-1]) which will remove both the first and the last character, which has been just tested.
You have to define your method first, then call it:
s = raw_input('enter a string: ') #use raw_input so the text it takes will give to you directly a string without ""
s1 = s
s1 = s1.lower()
s1 = s1.replace(',', '')
s1 = s1.replace(' ', '')
def ispal(s1):
if len(s1) <= 1:
return True
else:
#if the first and last char are the same
#and if all
return s1[0] == s1[-1] and ispal(s1[2:]) # here you put ispal(s1[1:]) it doesn't work properly :/
if s1.isalpha():
if ispal(s1) == True:
print(s,' is a palindrome')
else:
print(s,' is not a palindrome')
else:
print('you entered illegal chars')

python - password must contain at least one upper or lower case and a number

as a school work, I am trying to make a password encryption/decryption program.
I need consider the following rules:
Ensure that every password contains at least one letter (A-Z) or (a-z), one nonalphabetic character (from #, #, %), and at least one digit. The program must reject passwords that violate this rule.
Restrict the characters that are allowed in a password to letters (A-Z) and (a-z), digits (0-9) and the three characters (#, #, %). The program must reject passwords that violate this rule.
If the password violates those conditions, I will terminate the program with:
print('Invalid password!')
sys.exit()
I've been stuck for hours trying to add these conditions... I don't get where to add these conditions, wherever I add them, my program just terminates even though I've input a valid password T-T
Here is what I have so far (I've removed the part for decryption so that I can try to figure out that part for myself afterwards):
# import sys module for termination
import sys
# init
password_out = ''
case_changer = ord('a') - ord('A')
encryption_key = (('a','m'), ('b','h'), ('c','t'), ('d','f'), ('e','g'),
('f','k'), ('g','b'), ('h','p'), ('i','j'), ('j','w'), ('k','e'),('l','r'),
('m','q'), ('n','s'), ('o','l'), ('p','n'), ('q','i'), ('r','u'), ('s','o'),
('t','x'), ('u','z'), ('v','y'), ('w','v'), ('x','d'), ('y','c'), ('z','a'),
('#', '!'), ('#', '('), ('%', ')'), ('0'), ('1'), ('2'), ('3'), ('4'), ('5'),
('6'), ('7'), ('8'), ('9'))
encrypting = True
# get password
password_in = input('Enter password: ')
# perform encryption / decryption
if encrypting:
from_index = 0
to_index = 1
else:
from_index = 1
to_index = 0
case_changer = ord('a') - ord('A')
for ch in password_in:
letter_found = False
for t in encryption_key:
if ('a' <= ch and ch <= 'z') and ch == t[from_index]:
password_out = password_out + t[to_index]
letter_found = True
elif ('A' <= ch and ch <= 'Z') and chr(ord(ch) + 32) == t[from_index]:
password_out = password_out + chr(ord(t[to_index]) - case_changer)
letter_found = True
elif (ch == '#' or ch == '#' or ch == '%') and ch == t[from_index]:
password_out = password_out + t[to_index]
elif (ch >= '0' and ch <= '9') and ch == t[from_index]:
password_out = password_out + ch
# output
if encrypting:
print('Your encrypted password is:', password_out)
else:
print('Your decrypted password is:', password_out)
No regular expressions required
import string
import sys
NON_ALPHABETIC_CHARACTERS = {'#', '#', '%'}
DIGITS_CHARACTERS = set(string.digits)
LETTERS_CHARACTERS = set(string.ascii_letters)
def validate_password_1(password,
non_alphabetic_characters=NON_ALPHABETIC_CHARACTERS,
digits_characters=DIGITS_CHARACTERS,
letters_characters=LETTERS_CHARACTERS):
if not any(character in password
for character in non_alphabetic_characters):
err_msg = ('Password should contain at least '
'one non-alphabetic character.')
print(err_msg)
print('Invalid password!')
sys.exit()
if not any(character in password
for character in digits_characters):
err_msg = ('Password should contain at least '
'one digit character.')
print(err_msg)
print('Invalid password!')
sys.exit()
if not any(character in password
for character in letters_characters):
err_msg = ('Password should contain at least '
'one letter character.')
print(err_msg)
print('Invalid password!')
sys.exit()
ALLOWED_CHARACTERS = (NON_ALPHABETIC_CHARACTERS
| DIGITS_CHARACTERS
| LETTERS_CHARACTERS)
def validate_password_2(password,
allowed_characters=ALLOWED_CHARACTERS):
if not all(character in allowed_characters
for character in password):
print('Invalid password!')
sys.exit()
Added additional messages to see what exactly is wrong with given password
This certainly won't qualify as answer for your homework, but you can test that kind of conditions easily with sets:
import string
alpha = set(string.ascii_lowercase + string.ascii_uppercase)
digits = set(string.digits)
non_alpha = set('##%')
def is_valid(password):
password_chars = set(password)
# We substract the set of letters (resp. digits, non_alpha)
# from the set of chars used in password
# If any of the letters is used in password, this should be
# smaller than the original set
all_classes_used = all([len(password_chars - char_class) != len(password_chars)
for char_class in [alpha, digits, non_alpha] ])
# We remove all letters, digits and non_alpha from the
# set of chars composing the password, nothing should be left.
all_chars_valid = len(password_chars - alpha - digits - non_alpha) == 0
return all_classes_used and all_chars_valid
for pw in ['a', 'a2', 'a2%', 'a2%!']:
print(pw, is_valid(pw))
# a False
# a2 False
# a2% True
# a2%! False
One possible way to check for both cases would be to do the following:
if password == password.lower() or password == password.upper():
# Reject password here.
We're not going to write the rest of the encryption for you, though!
I will do something like that using regexp:
import re
def test(x):
regexp = r'[##%]+[0-9]+#*[a-zA-Z]+'
sorted_x = ''.join(sorted(x))
if '#' in sorted_x:
sorted_x = '#%s' % sorted_x
p = re.compile(regexp)
return p.match(sorted_x) is not None
Then the function gives :
In [34]: test("dfj")
Out[34]: False
In [35]: test("dfj23")
Out[35]: False
In [36]: test("dfj23#")
Out[36]: True
If you need one upper AND one lower case letter you can change the regexp to:
regexp = r'[##%]+[0-9]+#*[A-Z]+[a-z]+'
The sorted function will put the # and the % first, then the numbers, then the # and finally the letters (first the uper case and then the lower case). Because the # is put in the middle, I put one first if I find one in the string.
So at the end you want a string with at least a special character : [##%]+, at least a number [0-9]+, optionally there can be a # in the middle, and finally a letter [a-zA-Z]+ (or if you want upper and lower [A-Z]+[a-z]+).

Python Palindrome

So my task is to see and check a positive integer if its a palindrome. I've done everything correctly but need help on the final piece. And that the task of generating a new a palindrome from the one given given by the user. Am i on the right track with the while loop or should i use something else? So the result is if you put 192 it would give back Generating a palindrome....
483
867
1635
6996
"""Checks if the given, positive number, is in fact a palindrome"""
def palindrome(N):
x = list(str(N))
if (x[:] == x[::-1]):
return True
else: return False
"""Reverses the given positive integer"""
def reverse_int(N):
r = str(N)
x = r[::-1]
return int(x)
def palindrome_generator():
recieve = int(input("Enter a positive integer. "))
if (palindrome(recieve) == True):
print(recieve, " is a palindrome!")
else:
print("Generating a palindrome...")
while palindrome(recieve) == False:
reverse_int(recieve) + recieve
If I understand your task correctly, the following should do the trick:
def reverse(num):
return num[::-1]
def is_pal(num):
return num == reverse(num)
inp = input("Enter a positive number:")
if is_pal(inp):
print("{} is a palindrome".format(inp))
else:
print("Generating...")
while not is_pal(inp):
inp = str(int(inp) + int(reverse(inp)))
print(inp)
The variable inp is always a string and only converted to int for the arithmetic.
I've been using this solution for many years now to check for palindromes of numbers and text strings.
def is_palindrome(s):
s = ''.join(e for e in str(s).replace(' ','').lower() if e.isalnum())
_len = len(s)
if _len % 2 == 0:
if s[:int(_len/2)] == s[int(_len/2):][::-1]:
return True
else:
if s[int(_len/2+1):][::-1] == s[:int(_len/2)]:
return True
return False
This one is using Complement bitwise and Logical AND and OR operators
_input = 'Abba' # _input = 1221
def isPalindrome(_):
in_str = str(_).casefold() # Convert number to string + case insensitive
for _ in range(int(len(in_str) / 2)): # Loop from 0 till halfway
if in_str[_] != in_str[~_]:
return False
return True
print(_input, isPalindrome(_input) and ' is palindrome' or ' is not palindrome')
Abba is palindrome

checking whether representation of number in a given base is valid

i have written this code which checks whether a number is correctly represented in a given base. for all the invalid cases it gives false but for true ones it says string index out of range.
def check(n,a,i=0):
if int(n[i])>=a :
return False
else:
return check(n,a,i+1)
n = str(input('enter no:'))
a =int(input('enter base:'))
print(check(n,a,i=0))
The pythonic way:
def is_base_x(num_string, base):
for single_char in num_string:
if int(single_char) >= int(base):
return False
return True
As #ooga pointed out, you need to check when i is larger than the length of your number, you can make it like:
def check(n,a,i=0):
if len(n) <= i:
return True
if int(n[i])>=a :
return False
else:
return check(n,a,i+1)
n = str(input('enter no:'))
a = int(input('enter base:'))
print(check(n,a,i=0))
It would be better if it could check bases above 10. Something like this:
import string
def check(num, base, i = 0):
if i >= len(num):
return True
if not num[i].isdigit():
val = string.ascii_lowercase.find(num[i].lower())
if val == -1 or val + 10 >= base:
return False
elif int(num[i]) >= base:
return False
return check(num, base, i + 1)
while True:
num = raw_input('Enter number: ')
if len(num) == 0: break # null string breaks
base = int(raw_input('Enter base: '))
print(check(num, base))

Categories