def main():
plate = input("Plate: ")
if is_valid(plate):
print("Valid")
else:
print("Invalid")
def is_valid(s):
#vanity plates may contain a maximum of 6 characters (letters or numbers) and a minimum of 2 characters.
if 2 > len(s) > 6:
return False
#All vanity plates must start with at least two letters.
if s[0].isalpha() == False or s[1].isalpha() == False:
return False
#Numbers cannot be used in the middle of a plate; they must come at the end.
#The first number cannot be 0
i = 0
while i < len(s):
if s[i].isalpha() == False:
if s[i] == '0':
return False
else:
break
i += 1
#No periods, spaces, or punctuation marks are allowed.
if s.isalpha() == False or s.isinstance() == False:
return False
#passes all requirements
return True
main()
The regular expression module provides an easy way to approach what you intend to achieve with the code provided in your question. The code below should do what you intend to achieve, so try it out:
import re # regular expressions module
# All vanity plates must start with at least two letters.
# Numbers cannot be used in the middle of a plate; they must come at the end.
# The first number cannot be 0
rexp = re.compile('^[a-zA-Z]{2,6}([1-9][0-9]*)?')
def main():
plate = input("Plate: ")
# e.g. plate = "plat01"
if is_valid(plate):
print("Valid")
else:
print("Invalid")
def is_valid(s):
l = len(s)
#vanity plates may contain a maximum of 6 chars (letters or numbers)
# and a minimum of 2 characters.
if 2 > l or l > 6:
return False
if rexp.match(s).span() == (0,l):
return True
return False
main()
P.S. Check out https://regex101.com/r/LNw2pW/1 for detailed explanations of the used regular expression pattern. The 'trick' is to check if the found match length is the same as the length of the input string. If yes, than the input string is valid.
From the code above I see that you use isinstance() incorrect.
Try changing s.isinstance() == False to isinstance(s, type) == False, and choose the type you want to check (int, str.. etc)
Reference:
https://www.w3schools.com/python/ref_func_isinstance.asp
I'm trying to create a function that will identify if 0 is the first number in an alphanumeric sequence; for example, the function should evaluate to True if given the string "J02". I came up with a for loop that would work for inputs that are alphanumeric but not strictly alpha inputs.
x = "J02"
def not_starting_zero(m):
zero_string = []
for char in m:
if char.isdigit() == True:
zero_string.append(char)
if m[len(m)-1] == char:
if zero_string[0] == "0":
return False
else:
return True
not_starting_zero(x)
I tried using an else statement that aligned with the indentation of the if char.isdigit() == True: ; but that would make the return of the function true if the first index of the string is a letter.
You could use a regular expression to find the first digit:
import re
def not_starting_zero(m):
first_digit = re.search(r"([0-9])", m)
if first_digit:
return first_digit.group(0) == "0"
else:
return False
Alternatively, you could use your looping version - I think you can just stop after you encounter the first digit:
x = "J02"
def not_starting_zero(m):
for char in m:
if char.isdigit() == True:
if char == "0":
return True
# otherwise, return False
return False
# if we get here, there weren't any numbers
return False
not_starting_zero(x)
I suppose you could use regex and extract the numeric digits into a list. Something like this -
import re
def not_starting_zero(m):
numbers = re.findall('[0-9]', m)
if numbers[0] == '0':
return false
else
return true
I'm assuming you mean the first digit you find is 0 (because otherwise it should return False for "J02" because 02 is the first number)
x = "J02"
def not_starting_zero(m):
for char in m:
if char.isdigit() == True:
if char == "0":
return True
else:
return False
return False
not_starting_zero(x)
This works because once return is executed in a function the rest of the function is not executed. Hope this clears up your doubt.
You don't need to make an array of the digits because you only need to check the first digit in the string; if its a 0 then return True else return False.
Below code can find if 0 is the first number in alphanumeric string.
import regex as re
x = "J02"
True if re.findall('[0-9]', x)[0] == '0' else False
Output:
True
Take note on type safety, how expressive the code is, and how it instills referential transparency for code correctness (accuracy). All those loops cause too many mutations, and mutations cause errors (bugs). See here for referential transparency.
import re
str1 = 'jdh487y3hef8ty483rhfeih89t4389jf0dwiefh38uth'
str2 = '0dh487y3hef8ty483rhfeih89t4389jfdwiefh38uth'
# check if a given char is first in letter in string
def check_for_char(alpha_num:str, _char) -> bool:
if re.search('0', alpha_num).span(0)[0] == _char:
return True
else:
return False
is_false = check_for_char(
alpha_num=str1,
_char=0
)
is_true = check_for_char(
alpha_num=str2,
_char=0
)
print(is_false) # False
print(is_true) # True
# search if a given char exists at all within the alphanum str
print(str1[re.search('0', str1).span(0)[0]]) # 0
Input
Indian
3
nda
dan
ndani
Output
True
True
False
Explanation
1st line is the parent string
2nd line is the number of test case
The next n lines are the queries
First and Second query substring are in same order as in parent string.
for each query, initialize a pointer at the beginning of the query string, increment it only when you match an alphabet from the parent string while looping through the parent string
start = 0
for x in parent:
if x == query[start]:
start += 1
if start == len(query):
print(True)
break
else:
print(False)
You can do this for each query.
You can do this by creating a regular expression from the substring you are trying to match. For example, for the first test case if you want to know if 'nda' can be found in 'Indian', then form the regular expression n.*d.*a and do a search for that expression in 'Indian':
import re
string = 'Indian'
substrings = [
'nda',
'dan',
'ndan1'
]
for substring in substrings:
rex = '.*'.join(re.escape(ch) for ch in substring) # 'n.*d.*a'
print('True' if re.search(rex, string) else 'False')
Prints:
True
True
False
You just need to check each char against the main string index from i to end.
You can try this:
main_str = 'Indian'
words = ['nda','dan','ndani']
for word in words:
checker = []
for i in range(len(main_str)):
if i == len(word):
break
if word[i] in main_str[i::]:
checker.append('True')
else:
checker.append('False')
if 'False' in checker:
print('False')
else:
print('True')
It's not very efficient and intuitive but it gets the jobe done (I think). You can just modify the code to fit your input
This is a very simple program. But it will work -
string = 'Indian'
words = ['3','nda','dan','ndani']
for sub in words:
if sub in the string:
return True
else:
return False
This is my approach - use iter.
def isSubsequence(sub: str, orig: str) -> bool:
it = iter(orig) #
return all(ch in orig for ch in sub)
if __name__ == '__main__':
sub = 'rice'
orig = 'practice'
assert isSubsequence(sub, orig) == True
assert isSubsequence('pace', orig) == True
assert isSubsequence('acts', orig) == False
I'm trying to check for a palindrome with Python. The code I have is very for-loop intensive.
And it seems to me the biggest mistake people do when going from C to Python is trying to implement C logic using Python, which makes things run slowly, and it's just not making the most of the language.
I see on this website. Search for "C-style for", that Python doesn't have C-style for loops. Might be outdated, but I interpret it to mean Python has its own methods for this.
I've tried looking around, I can't find much up to date (Python 3) advice for this. How can I solve a palindrome challenge in Python, without using the for loop?
I've done this in C in class, but I want to do it in Python, on a personal basis. The problem is from the Euler Project, great site By the way,.
def isPalindrome(n):
lst = [int(n) for n in str(n)]
l=len(lst)
if l==0 || l==1:
return True
elif len(lst)%2==0:
for k in range (l)
#####
else:
while (k<=((l-1)/2)):
if (list[]):
#####
for i in range (999, 100, -1):
for j in range (999,100, -1):
if isPalindrome(i*j):
print(i*j)
break
I'm missing a lot of code here. The five hashes are just reminders for myself.
Concrete questions:
In C, I would make a for loop comparing index 0 to index max, and then index 0+1 with max-1, until something something. How to best do this in Python?
My for loop (in in range (999, 100, -1), is this a bad way to do it in Python?
Does anybody have any good advice, or good websites, or resources for people in my position? I'm not a programmer, I don't aspire to be one, I just want to learn enough so that when I write my bachelor's degree thesis (electrical engineering), I don't have to simultaneously LEARN an applicable programming language while trying to obtain good results in the project. "How to go from basic C to great application of Python", that sort of thing.
Any specific bits of code to make a great solution to this problem would also be appreciated, I need to learn good algorithms.. I am envisioning 3 situations. If the value is zero or single digit, if it is of odd length, and if it is of even length. I was planning to write for loops...
PS: The problem is: Find the highest value product of two 3 digit integers that is also a palindrome.
A pythonic way to determine if a given value is a palindrome:
str(n) == str(n)[::-1]
Explanation:
We're checking if the string representation of n equals the inverted string representation of n
The [::-1] slice takes care of inverting the string
After that, we compare for equality using ==
An alternative to the rather unintuitive [::-1] syntax is this:
>>> test = "abcba"
>>> test == ''.join(reversed(test))
True
The reversed function returns a reversed sequence of the characters in test.
''.join() joins those characters together again with nothing in between.
Just for the record, and for the ones looking for a more algorithmic way to validate if a given string is palindrome, two ways to achieve the same (using while and for loops):
def is_palindrome(word):
letters = list(word)
is_palindrome = True
i = 0
while len(letters) > 0 and is_palindrome:
if letters[0] != letters[(len(letters) - 1)]:
is_palindrome = False
else:
letters.pop(0)
if len(letters) > 0:
letters.pop((len(letters) - 1))
return is_palindrome
And....the second one:
def is_palindrome(word):
letters = list(word)
is_palindrome = True
for letter in letters:
if letter == letters[-1]:
letters.pop(-1)
else:
is_palindrome = False
break
return is_palindrome
The awesome part of python is the things you can do with it. You don't have to use indexes for strings.
The following will work (using slices)
def palindrome(n):
return n == n[::-1]
What it does is simply reverses n, and checks if they are equal. n[::-1] reverses n (the -1 means to decrement)
"2) My for loop (in in range (999, 100, -1), is this a bad way to do it in Python?"
Regarding the above, you want to use xrange instead of range (because range will create an actual list, while xrange is a fast generator)
My opinions on question 3
I learned C before Python, and I just read the docs, and played around with it using the console. (and by doing Project Euler problems as well :)
Below the code will print 0 if it is Palindrome else it will print -1
Optimized Code
word = "nepalapen"
is_palindrome = word.find(word[::-1])
print is_palindrome
Output:
0
word = "nepalapend"
is_palindrome = word.find(word[::-1])
print is_palindrome
Output:
-1
Explaination:
when searching the string the value that is returned is the value of the location that the string starts at.
So when you do word.find(word[::-1]) it finds nepalapen at location 0 and [::-1] reverses nepalapen and it still is nepalapen at location 0 so 0 is returned.
Now when we search for nepalapend and then reverse nepalapend to dnepalapen it renders a FALSE statement nepalapend was reversed to dnepalapen causing the search to fail to find nepalapend resulting in a value of -1 which indicates string not found.
Another method print true if palindrome else print false
word = "nepalapen"
print(word[::-1]==word[::1])
output:
TRUE
There is also a functional way:
def is_palindrome(word):
if len(word) == 1: return True
if word[0] != word[-1]: return False
return is_palindrome(word[1:-1])
I know that this question was answered a while ago and i appologize for the intrusion. However,I was working on a way of doing this in python as well and i just thought that i would share the way that i did it in is as follows,
word = 'aibohphobia'
word_rev = reversed(word)
def is_palindrome(word):
if list(word) == list(word_rev):
print'True, it is a palindrome'
else:
print'False, this is''t a plindrome'
is_palindrome(word)
There is much easier way I just found. It's only 1 line.
is_palindrome = word.find(word[::-1])
The most pythonic way to do this is indeed using the slicing notation to reverse the string as mentioned already:
def is_palindrome(string: str) -> bool:
return string == string[::-1]
In some other occasions though (like technical interviews), you may have to write a "proper" algorithm to find the palindrome. In this case, the following should do the trick:
def is_palindrome(string: str) -> bool:
start = 0
end = len(string) - 1
while end >= start:
if string[end] != string[start]:
return False
start += 1
end -= 1
return True
Set pointers to the start and end of the string
Iterate while end exceeds start
If the character in end and start indices don't match then this is not a palindrome, otherwise keep comparing
Increase start pointer by 1
Decrease end pointer by 1
Test Cases:
import unittest
class Test(unittest.TestCase):
palindromes = ['a', 'aa', 'aba', '12321']
non_palindromes = ['ab', 'aab', 'cacacc']
def test_is_palindrome(self):
for case in self.palindromes:
self.assertTrue(is_palindrome(case))
for case in self.non_palindromes:
self.assertFalse(is_palindrome(case))
if __name__ == '__main__':
unittest.main()
You could use this one-liner that returns a bool value:
str(x)==str(x)[::-1]
This works both for words and numbers thanks to the type casting...
Here a case insensitive function since all those solutions above are case sensitive.
def Palindrome(string):
return (string.upper() == string.upper()[::-1])
This function will return a boolean value.
doing the Watterloo course for python, the same questions is raised as a "Lesseon" find the info here:
http://cscircles.cemc.uwaterloo.ca/13-lists/
being a novice i solved the problem the following way:
def isPalindrome(S):
pali = True
for i in range (0, len(S) // 2):
if S[i] == S[(i * -1) - 1] and pali is True:
pali = True
else:
pali = False
print(pali)
return pali
The function is called isPalindrome(S) and requires a string "S".
The return value is by default TRUE, to have the initial check on the first if statement.
After that, the for loop runs half the string length to check if the character from string "S" at the position "i" is the same at from the front and from the back.
If once this is not the case, the function stops, prints out FALSE and returns false.
Cheers.kg
If the string has an uppercase or non-alphabetic character then the function converts all characters to lowercase and removes all non-alphabetic characters using regex finally it applies palindrome check recursively:
import re
rules = [
lambda s: any(x.isupper() for x in s),
lambda s: not s.isalpha()
]
def is_palindrome(s):
if any(rule(s) for rule in rules):
s = re.sub(r'[^\w]', '', s).lower()
if len(s) < 2:
return True
if s[0] != s[-1]:
return False
return is_palindrome(s[1:-1])
string = 'Are we not drawn onward, we few, drawn onward to new era?'
print(is_palindrome(string))
the output is True for the input above.
maybe you can try this one:
list=input('enter a string:')
if (list==list[::-1]):
print ("It is a palindrome")
else:
print("it is not palindrome")
You are asking palindrome in python. palindrome can be performed on strings, numbers and lists. However, I just posted a simple code to check palindrome of a string.
# Palindrome of string
str=raw_input("Enter the string\n")
ln=len(str)
for i in range(ln/2) :
if(str[ln-i-1]!=str[i]):
break
if(i==(ln/2)-1):
print "Palindrome"
else:
print "Not Palindrome"
The real easy way to do that it is
word = str(raw_input(""))
is_palindrome = word.find(word[::-1])
if is_palindrome == 0:
print True
else:
print False
And if/else here just for fancy looks. The question about palindrome was on Amazon's interview for QA
Assuming a string 's'
palin = lambda s: s[:(len(s)/2 + (0 if len(s)%2==0 else 1)):1] == s[:len(s)/2-1:-1]
# Test
palin('654456') # True
palin('malma') # False
palin('ab1ba') # True
word = "<insert palindrome/string>"
reverse = word[::-1]
is_palindrome = word.find(reverse)
print is_palindrome
This was a question in Udacity comp 101, chapter 1. Gives a 0 for palindrome gives a -1 for not. Its simple, and does not use loops.
I wrote this code:
word = input("enter: ")
word = ''.join(word.split())`
for x in range(len(word)):
if list(word)[x] == ((list(word)[len(word)-x-1])):
if x+1 == len(word):
print("its pali")
and it works.
it gets the word, then removes the spaces and turns it into a list
then it tests if the first letter is equal to the last and if the 2nd is equal to 2nd last and so on.
then the 'if x+1 == len(word)' means that since x starts at 0 it becomes 1 and then for every next .. blah blah blah it works so it works.
#compare 1st half with reversed second half
# i.e. 'abba' -> 'ab' == 'ba'[::-1]
def is_palindrome( s ):
return True if len( s ) < 2 else s[ :len( s ) // 2 ] == s[ -( len( s ) // 2 ):][::-1]
You can use Deques in python to check palindrome
def palindrome(a_string):
ch_dequeu = Deque()
for ch in a_string:
ch_dequeu.add_rear(ch)
still_ok = True
while ch_dequeu.size() > 1 and still_ok:
first = ch_dequeu.remove_front()
last = ch_dequeu.remove_rear()
if first != last:
still_ok = False
return still_ok
class Deque:
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def add_rear(self, item):
self.items.insert(0, item)
def add_front(self, item):
self.items.append(item)
def size(self):
return len(self.items)
def remove_front(self):
return self.items.pop()
def remove_rear(self):
return self.items.pop(0)
import string
word = input('Please select a word to test \n')
word = word.lower()
num = len(word)
x = round((len(word)-1)/2)
#defines first half of string
first = word[:x]
#reverse second half of string
def reverse_odd(text):
lst = []
count = 1
for i in range(x+1, len(text)):
lst.append(text[len(text)-count])
count += 1
lst = ''.join(lst)
return lst
#reverse second half of string
def reverse_even(text):
lst = []
count = 1
for i in range(x, len(text)):
lst.append(text[len(text)-count])
count += 1
lst = ''.join(lst)
return lst
if reverse_odd(word) == first or reverse_even(word) == first:
print(string.capwords(word), 'is a palindrome')
else:
print(string.capwords(word), 'is not a palindrome')
the "algorithmic" way:
import math
def isPalindrome(inputString):
if inputString == None:
return False
strLength = len(inputString)
for i in range(math.floor(strLength)):
if inputString[i] != inputString[strLength - 1 - i]:
return False
return True
There is another way by using functions, if you don't want to use reverse
#!/usr/bin/python
A = 'kayak'
def palin(A):
i = 0
while (i<=(A.__len__()-1)):
if (A[A.__len__()-i-1] == A[i]):
i +=1
else:
return False
if palin(A) == False:
print("Not a Palindrome")
else :
print ("Palindrome")
It looks prettier with recursion!
def isPalindrome(x):
z = numToList(x)
length = math.floor(len(z) / 2)
if length < 2:
if z[0] == z[-1]:
return True
else:
return False
else:
if z[0] == z[-1]:
del z[0]
del z[-1]
return isPalindrome(z)
else:
return False
def is_palindrome(string):
return string == ''.join([letter for letter in reversed(string)])
print ["Not a palindrome","Is a palindrome"][s == ''.join([s[len(s)-i-1] for i in range(len(s))])]
This is the typical way of writing single line code
def pali(str1):
l=list(str1)
l1=l[::-1]
if l1==l:
print("yess")
else:
print("noo")
str1="abc"
a=pali(str1)
print(a)
I tried using this:
def palindrome_numer(num):
num_str = str(num)
str_list = list(num_str)
if str_list[0] == str_list[-1]:
return True
return False
and it worked for a number but I don't know if a string
def isPalin(checkWord):
Hsize = len(lst)/2
seed = 1
palind=True
while seed<Hsize+1:
#print seed,lst[seed-1], lst [-(seed)]
if(lst[seed-1] != lst [-seed]):
palind = False
break
seed = seed+1
return palind
lst = 'testset'
print lst, isPalin(lst)
lst = 'testsest'
print lst, isPalin(lst)
Output
testset True
testsest False
I think I have the right idea of solving this function, but I'm not sure why
I don't get the desired results shown in the docstring. Can anyone please help me fix this?
def check_password(s):
'''(str, bool)
>>> check_password('TopSecret')
False
>>> check_password('TopSecret15')
True
'''
for char in s:
if char.isdigit():
if char.islower():
if char.isupper():
return True
else:
return False
Your logic is flawed it should look like this:
def check_password(s):
has_digit = False
has_lower = False
has_upper = False
for char in s:
if char.isdigit():
has_digit = True
if char.islower():
has_lower = True
if char.isupper():
has_upper = True
# if all three are true return true
if has_digit and has_upper and has_lower:
return True
else:
return False
Now, let's talk about what's wrong with your code.
def check_password(s):
for char in s:
if char.isdigit():
if char.islower(): # we only get to this check if char was a digit
if char.isupper(): # we only get here if char was a digit and lower
# it is not possible to get here
# char would have to be a digit, lower, and upper
return True
else:
return False
As an example let's look at TopSecret15, we start with T
isdigit = False so we immediately return false for 'T'
We will continue to immediately return false until we get to '1'
Let's say we were on 1, isdigit would be true, but islower would be false so again it returns false
Do you see how it is impossible for all three of these to be true for the same char?
Your code is equivalent to:
if char.isdigit and char.islower and char.isupper:
# this will never happen
The reason this doesn't work is that for any given character, it first checks if it's a digit, then if it's lower, then if it's upper. Obviously, one character cannot be all three of these at once. You instead want to check each character to see if it's a digit, lowercase, or uppercase, and then flip a boolean value like has_upper. Then, after the for loop, you'll check to see if all of the boolean values are true.
See this answer:
https://stackoverflow.com/a/2990682/7579116
the best way to check if a password match all the requirements is by using a regex.
I've gone way overboard here (because I'm bored I guess) and whipped up an extensible password-checking system. Perhaps it will help clarify why your version doesn't do what you want (or maybe it won't).
The essential problem with your code is that it checks for a single characteristic instead each of the required characteristics.
def check_password(password):
# These are the characteristics we want a password to have:
characteristics = [
length(8), # At least 8 characters
lower_case(1), # At least 1 lower case letter
upper_case(1), # At least 1 upper case letter
number(1), # At least 1 number
]
# Check to see if the supplied password has *all* of the desired
# characteristics:
return all(
characteristic(password)
for characteristic in characteristics
)
def length(n=10):
# Ensure password has at least N characters
def check(password):
return len(password) >= n
return check
def lower_case(n=1):
# Ensure password has at least N lower case characters
def check(password):
count = 0
for char in password:
if char.islower():
count += 1
if count == n:
return True
return False
return check
def upper_case(n=1):
# Ensure password has at least N upper case characters
def check(password):
count = 0
for char in password:
if char.isupper():
count += 1
if count == n:
return True
return False
return check
def number(n=1):
# Ensure password has at least N numbers
def check(password):
count = 0
for char in password:
if char.isdigit():
count += 1
if count == n:
return True
return False
return check
# Doesn't have any numbers:
>>> print(check_password('TopSecret'))
False
# Acceptable:
>>> print(check_password('TopSecret15'))
True
# Has lower case, upper case, and number, but it's not long enough:
>>> print(check_password('Ab1'))
False
Notes:
Some parts of this are simplified in order to make it more clear what's going on (all of the check functions could be one-liners).
In a production system, password requirements will almost certainly change over time and you want to make sure that implementing additional requirements is easy.
A regular expression might not be as easy to understand or extend (although it might be a little faster, but that probably doesn't matter at all).
The approach above is somewhat similar to Django's password validation system.