counting the number of palindromes in a range in python - python

I'm sort of new to python. I'm trying to go through a specific range of numbers and have python count all the palindromes in it and return them to me (total number count, not their sum). So it would count all the integers in this range and return it to me as one number.
I keep getting an invalid syntax error and I don't know what to change. Here is what I have so far:
import math
def ispal(n):
return str(n) == str(n)[::-1]
But this is basically just what we did in class.
My range of of numbers is from 171 to 115000 and I want to go through the entire range in between and including those 2 numbers and have python tell me how many numbers are palindromes. The problem is I don't know how to fit in the for loop.
I started with:
def count_pal(n):
count = 0
for i in range(n):
if i = str(n) == str(n)[::-1]:
return:
count =+ i
else:
pass
But I don't know how to put the 2 together. I have python 3.2. Can anyone please help me out? Thank you!

def num_palindromes(start, end):
count = 0
for i in range(start, end + 1):
if str(i) == str(i)[::-1]:
count += 1
return count
Or as a one liner
def num_palindromes(start, end):
return sum(str(i) == str(i)[::-1] for i in range(start, end + 1))

You're returning inside the for loop before you have a chance to increment the counter
You also don't need that empty 'else: pass' block as it does nothing.
A correct solution will return the counter at the end of the function after the loop terminates.
Something like this will work:
count = 0
for i in range(171, 115000):
if str(i) == str(i)[::-1]:
count += 1
return count
Note a few style changes:
- 4-space indentation
- no extraneous newlines
- no unnecessary coercion of i from 'True/False' to a number (which is what you get in your code when you do i = str(i) == str(i)[::-1])
Not directly related to your question but following python conventional style will help make your code more readable and easier for others to understand and help you with.
Lastly, just as n extra tidbit, you can also accomplish this task with a list comprehension:
sum([1 for i in range(171, 115000) if str(i) == str(i)[::-1]])
I personally find it more concise/easier to understand than the loop counter variation.

Related

How is the {:,} function work to add commas in between numbers?

Hey guy i recently found out this how you add commas between integer values, i have been trying to find out how it works i tried looking at other sources but none of them explain how this works?
Example:
numbers = "{:,}".format(5000000)
print(numbers)
I am wondering the logic behind {:,}
def add_comma(number: int) -> str:
new_number, cnt = '', 0
for num in str(number)[::-1]:
if cnt == 3:
new_number += ','
cnt = 0
new_number += num
cnt += 1
return new_number[::-1]
add_comma(1200000)
'1,200,000'
The mechanics behind it is that after every 3 numbers counting from behind, you add a comma to it; you start counting from behind and not from the beginning. So the code above is the equivalent of what the f-string function does for you.
For example, let's say the number '14589012'. To add comma to this, we count the first 3 numbers till we reach the beginning of the number, starting counting from the last digit in the number:
210,
210,985,
210,985,41
Then reverse the string, we have 14,589,012
I hope it helps, just read the code and explanation slowly.
{:,} is used along with format().
Example:
num = "{:,}".format(1000)
print(num)
Output: 1,000
This command add commas in every thousand place.
Example:
num = "{:,}".format(100000000)
print(num)
Output: 100,000,000

How To Fix String Index Out of Range in Python

I'm currently learning python. There is an exercise in the book which outlines code for decoding. I followed along with this code however I keep getting back an error in the middle of the program.
Here is the code that is causing the problem:
def decode(string_for_decoding):
result = ""
for i in range(0, len(string_for_decoding)):
if string_for_decoding[i+1].isdigit():
result += string_for_decoding[i] * int(string_for_decoding[i+1])
elif string_for_decoding[i].isalpha():
result += string_for_decoding[i]
return result
string_for_decoding = input("Enter a string to decode: ")
print(decode(string_for_decoding))
Check if the index from range is larger than the number of chars in the string. It might look like this:
def decode(string_for_decoding: str):
result = ""
for i in range(0, len(string_for_decoding)):
if len(string_for_decoding) > i + 1 and string_for_decoding[i + 1].isdigit():
result += string_for_decoding[i] * int(string_for_decoding[i + 1])
elif string_for_decoding.isalpha():
result += string_for_decoding[i]
return result
print(decode(input("Enter a string to decode: ")))
You are going from 0 to len(string) and inside for loop you are trying to access index: i+1
THis is the root cause! Either:
iterate till one length less e.g. till len(string) - 1
Or use indices
inside appropriately
Moreover it is highly discouraged to use range(len(x)). You can simply iterate over any collective datatype as for i in x: If you want indices too have a look at enumerate(). And you can forget about index errors all together.
You are trying to get index i+1 which cannot be equal or greater than len(string).

How can i fix the following Python code freeze issue?

I have a Python problem where i need to take input as a string in a function and need to return back a string where every alternate letter is a sequence of small case and Capital case. Ex: String passed to the function: AmsTerdam then the returned string should be AmStErDaM. It can start with any case i.e., small case or capital case.
I am still in learning phase of Python and have come up with the following but somehow when i try to execute, the code hangs. Could anyone please help me in fixing this?
def myfunc(NAME='AmsTerdam'):
leng=len(NAME)
ind=1
newlist=[]
while ind <= leng:
if ind%2==0:
newlist.append(NAME[ind-1].upper())
else:
newlist.append(NAME[ind-1].lower())
str(mylist) # Can we typecast a list to a string?
return newlist
OUT=myfunc('Ankitkumarsharma')
print('Output: {}'.format(OUT))
If the typecasting cannot be done, is the following correct?
def myfunc(NAME='AmsTerdam'):
leng=len(NAME)
ind=1
newstr=''
while ind <= leng:
if ind%2==0:
newstr=newstr+NAME[ind-1].upper()
else:
newstr=newstr+NAME[ind-1].lower()
return newstr
OUT=myfunc('AmsTerdam')
print('Output: {}'.format(OUT))
You have in essence, written a while true loop, without a break condition.
Going by your previous logic we can rewrite your loop and assume ind=1 being always the case, we get:
def myfunc(NAME='AmsTerdam'):
leng=len(NAME)
newstr=''
while 1 <= leng:
if ind%2==0:
newstr=newstr+NAME[ind-1].upper()
else:
newstr=newstr+NAME[ind-1].lower()
return newstr
Which means if len(name) > 1, the loop will run forever. Fixing that, we get the following function, which will terminate.
def myfunc(NAME='AmsTerdam'):
leng=len(NAME)
newstr=''
ind=1
while ind <= leng:
if ind%2==0:
newstr=newstr+NAME[ind-1].upper()
else:
newstr=newstr+NAME[ind-1].lower()
ind+=1
return newstr
def alternat_case(word):
word2 = []
for i in range(len(word)):
if i%2 ==0:
word2.append(word[i].upper())
else:
word2.append(word[i].lower())
word2 = "".join(word2)
return print(word2)
alternat_case("python")
PyThOn

why doesnt my code work, learning python

I am learning python on codecademy. It is going okay so far, however I cannot understand why my code works one way and not a different way. So here is the code I have made:
n = ["Michael", "Lieberman"]
def join_strings(words):
result = ""
for i in range(len(words)):
result += i
return result
print join_strings(n)
this code doesn't work... below is the code that is working for me...............
n = ["Michael", "Lieberman"]
def join_strings(words):
result = ""
for i in range(len(words)):
result += words[i]
return result
print join_strings(n)
my question is more regarding confusion on "words[i]", and what makes that code work vs the way I did it? thanks
In the first you are adding up the integer you loop over
n = ["Michael", "Lieberman"]
for i in range(len(n)):
result += i # i = 0 then i = 1, sum up to 1
print i # add this to see what you are adding up to your list
return result
Now, if you write:
n[0]
It will return the first element in your list n = ["Michael", "Lieberman"], then the code:
n = ["Michael", "Lieberman"]
for i in range(len(n)):
result += n[i]
return result
shall return the concatenation of what is in the list versus adding up the integer you loop over in the first code.
i will be an integer, not the word in word[] as this is what range() returns. len(words) also returns an integer which is the length or count of the words array.
You get access to the word by passing the index of the array in to word[] starting from 0 eg word[0] will be the first element of the array, word[1] will be the second.
Details about range():
http://pythoncentral.io/pythons-range-function-explained/
Details about len():
https://www.tutorialspoint.com/python/list_len.htm

Finding the index at which upon removing element string becomes palindrome

I'm writing the solution to this HackerRank problem - https://www.hackerrank.com/challenges/palindrome-index
I've tried this code:
T = int(raw_input())
for t in xrange(T):
s = raw_input()
index = -1
if s != s[::-1]:
for i in xrange(len(s)):
temp = s[:i:] + s[i+1::]
if temp == temp[::-1]:
index = i
break
print index
But when I submit it, out of the 14 test cases, around 8 take a long time to compute (~5-7 seconds) and 1 of them takes more than 10 seconds, so HackerRank doesn't even show the result (whether it gave the right output).
It seems my code is inefficient. Please help me out in making it run faster.
The easiest way to speed the code would be to remove slicing for every index in case that string isn't a palindrome. In case of maximum length string which is not a palindrome following line will generate over 200000 slices: temp = s[:i:] + s[i+1::].
You could start checking the string from start and beginning until you spot a difference. Once found you can generate slice which has either first or last letter removed and check if that's a palindrome. In case you removed the first character and result wasn't a palindrome you know that last character is the correct solution since the problem statement guarantees that:
T = int(raw_input())
for t in xrange(T):
s = raw_input()
length = len(s)
for i in xrange(length / 2):
if s[i] != s[length - i - 1]:
if s[i + 1:length - i] == s[length - i - 1:i:-1]:
print i
else:
print length - i - 1
break
else:
print -1
The most efficient way would be to check from both sides left and right and break on inequality:
for i in range(int(input())):
s=input()
if s==s[::-1]:
print(-1)
else:
for i in range(int(len(s)/2)):
if s[i]!=s[len(s)-1-i]:
print(i if ((s[:i]+s[i+1:])==(s[:i]+s[i+1:])[::-1]) else len(s)-1-i)
break
Apparently I'm a member of that site as well, executed my code and it passes all test cases with 0.01 s and 0.02s

Categories

Resources