Python key sorting - python-2.7

Im taking an online beginner course through google on python 2, and I cannot figure out the answer to one of the questions. Here it is and thanks in advance for your help!
# A. match_ends
# Given a list of strings, return the count of the number of
# strings where the string length is 2 or more and the first
# and last chars of the string are the same.
# Note: python does not have a ++ operator, but += works.
def match_ends(words):
a = []
for b in words:
retun
I tried a few different things. This is just where i left off on my last attempt, and decided to ask for help. I have spent more time thinking about this than i care to mention

You should go through the course materials carefully. This can be solved easily if you have a beginner level understanding of Python. See the following code snippet:
def match_ends(words):
count = 0
for word in words:
if len(word) >= 2 and word[0] == word[-1]:
count += 1
return count

Related

How to I shorten this code to comply with the DRY (Don't Repeat Yourself) principle?

I want to take words a user provides, store them in a list, and then modify those words so that every other letter is capitalized. I have working code but it is repetitive. I cannot for the life of me figure out how to get all the words ran through in one function and not have it output one long string with the spaces removed. Any help is appreciated.
This is my current code:
def sarcastic_caps(lis1):
list=[]
index=0
for ltr in lis1[0]:
if index % 2 == 0:
list.append(ltr.upper())
else:
list.append(ltr.lower())
index=index+1
return ''.join(list)
final_list.append(sarcastic_caps(lis1))
Imagine 4 more iterations of this ^. I would like to do it all in one function if possible?
I have tried expanding the list index but that returns all of the letters smashed together, not individual words. That is because of the .join but I need that to get all of the letters back together after running them through the .upper/.lower.
I am trying to go from ['hat', 'cat', 'fat'] to ['HaT', 'CaT', 'FaT'].

How to make a regex pattern which compares the frequency of a group with another

The problem is to find the existence of a substring with n number of a and followed by 2 * n number b and n >= 1. This is a very easy question to do but I want to know if there is any way to do this using regex only.
For example:
zzaabbbbzz should print in print Yes.
zzaazzbbbbzz should print No.
zzaaabbbbzz should print in No.
I tried in python 3 like this:
pattern = re.compile(r'(a+)(b+)')
check = pattern.findall(input())
if(len(check)>0):
for i in check:
if(len(i[0])*2 == len(i[1])):
print('Yes')
break
else:
print('No')
else:
print('No')
I want to know if there is any way to provide some count for a and b in regex pattern itself.
The question can be done using simple loop and manually checking each character and count a and b occurrences with O(n) complexity but I want to learn something new.
Help me to shorten this code?
While this can't be done using only regex (regex can count deterministically, but can't compare quantities) your example's readability can be improved a bit:
import re
inputs = 'zzaabbbbzz', 'zzaazzbbbbzz', 'zzaaabbbbzz'
regex = re.compile(r'.*?(a+)(b+).*')
for inp in inputs:
match = regex.match(inp)
if match:
a_count = len(match.group(1))
b_count = len(match.group(2))
if b_count == 2 * a_count:
print('YES')
else:
print('NO')
else:
print('NO')
Outputs
YES
NO
NO

PythonQuestion on Longest Common Substring(LCS) algorithm

I'm pretty new to Python, it's my first programming language, and I've wanted to work on some manual data structure manipulation and playing around.
I've recently been learning the basic algorithm for solving the LCS problem, and I understand how it works besides one line of code that I for some weird reason can't seem to convince myself I am grasping entirely.
this is the code I've been using to learn from after I couldn't get it down myself quite right.
EDIT 2: Anyway to make this work with an input of two lists of integers?**I figured out that I was understanding my original question correctly, but would anyone know how I could make this work with a **list of integers? I tried converting S and T to a string of comma separated values, which worked in matching some of the characters, but even then it rarely worked in most test-cases. I'm not sure why it wouldn't, as it is still just two strings being compared, but with commas.
def lcs(S,T):
m = len(S)
n = len(T)
counter = [[0]*(n+1) for x in range(m+1)]
longest = 0
lcs_set = set()
for i in range(m):
for j in range(n):
if S[i] == T[j]:
c = counter[i][j] + 1
counter[i+1][j+1] = c
if c > longest:
lcs_set = set()
longest = c
lcs_set.add(S[i-c+1:i+1])
elif c == longest:
lcs_set.add(S[i-c+1:i+1])
return lcs_set
Now my issue is understanding is the line : lcs_set.add(S[i-c+1:i-1])
I understand that the counter is incremented when a match is found, to give longest the length of the substring. So, to make it easy, if S = Crow and T = Crown, when you reach w, the last match, the counter is incremented to 4, and i is at index 3 of S.
Does this mean I am to read this as: i (index3 on S, the W) - c (4), so 3-4 = -1, so 3-4+1 = 0 (at C) and for the right side of the slice: i(3) + 1 = 4(N, but will not be included, obviously), meaning we end with S[0:4], Crow, to LCS_Set?
If that is the case, I guess I am confused as to why we are adding the whole substring to the set, and not just the newest matched character?
If I understand right, it is updating LCS_set with the entire slice of the current matched substring, so if it were on the second match, R, the counter would be at 2, i would be at 1, and it would be saying S[1-2+1:i(1)+1], so 1-2 = -1, -1 + 1 = 0(C) up to i(1)+1 = 2 (leaving us with S[0:2], or CR), so each time around, the set is updated with the entire substring, and not just the current index.
It's not really a problem, I just want to make sure I'm understanding this correctly.
I would really appreciate any input, or any tips anyone might see with my current logic!!
EDIT:
I just realized I was totally forgetting that the position at C is the current counter number, therefore it obviously wouldn't be updating the LCS_set with the current max match number, and it can't update it with just the current matched letter, so it has to take the slice of the substring in order to update the LCS_Set.
Thanks in advance!

Python 2.7 trying to make this book text lowercase

Here is my code so far, the idea is to make all words lowercase, count the unique words (ones that are not repeated) as well as count the number of times "uncle" is typed in the book.
word_cnt = 0
book = open("shunned_house.txt")
lower = book.lower()
for line in lower:
words = line.split()
for word in words:
word_cnt += 1
print word_cnt
any help would be greatly appreciated. I have tried many different variations of this problem and keep getting stuck right here. In terms of words counted in this document its around 10700 or so. I especially have trouble setting the python code up to tackle the problem.
Pretty sure this is what you want:
with open('shunned_house.txt') as f:
book = f.read().lower()
words = book.split()
print len(set(words))
print book.count('uncle')

Python: get the string between two capitals

I'd like your opinion as you might be more experienced on Python as I do.
I came from C++ and I'm still not used to the Pythonic way to do things.
I want to loop under a string, between 2 capital letters. For example, I could do that this way:
i = 0
str = "PythonIsFun"
for i, z in enumerate(str):
if(z.isupper()):
small = ''
x = i + 1
while(not str[x].isupper()):
small += str[x]
I wrote this on my phone, so I don't know if this even works but you caught the idea, I presume.
I need you to help me get the best results on this, not just in a non-forced way to the cpu but clean code too. Thank you very much
This is one of those times when regexes are the best bet.
(And don't call a string str, by the way: it shadows the built-in function.)
s = 'PythonIsFun'
result = re.search('[A-Z]([a-z]+)[A-Z]', s)
if result is not None:
print result.groups()[0]
you could use regular expressions:
import re
re.findall ( r'[A-Z]([^A-Z]+)[A-Z]', txt )
outputs ['ython'], and
re.findall ( r'(?=[A-Z]([^A-Z]+)[A-Z])', txt )
outputs ['ython', 's']; and if you just need the first match,
re.search ( r'[A-Z]([^A-Z]+)[A-Z]', txt ).group( 1 )
You can use a list comprehension to do this easily.
>>> s = "PythonIsFun"
>>> u = [i for i,x in enumerate(s) if x.isupper()]
>>> s[u[0]+1:u[1]]
'ython'
If you can't guarantee that there are two upper case characters you can check the length of u to make sure it is at least 2. This does iterate over the entire string, which could be a problem if the two upper case characters occur at the start of a lengthy string.
There are many ways to tackle this, but I'd use regular expressions.
This example will take "PythonIsFun" and return "ythonsun"
import re
text = "PythonIsFun"
pattern = re.compile(r'[a-z]') #look for all lower-case characters
matches = re.findall(pattern, text) #returns a list of lower-chase characters
lower_string = ''.join(matches) #turns the list into a string
print lower_string
outputs:
ythonsun