Procedure in Python - python

Question
Write a procedure that takes a string of words separated by spaces (assume no punctuation or capitalization), together with a ”target” word, and shows the position of the target word in the string of words. For example, if the string is:
'we dont need no education we dont need no thought control no we dont'
and the target is the word ”dont” then your procedure should return the list 1, 6, 13 because ”dont” appears at the 1st, 6th, and 13th position in the string. (We start counting positions of words in the string from 0.) Your procedure should return False if the target word doesn’t appear in the string.
My solution-
def procedure(string,target):
words=string.split(" ") #turn the string into a list of words
solution=[] #list that will be displayed
for i in range(len(words)):
if words[i]==target: solution.append(i)
if len(solution)==0: return False
return solution
string="we dont need no education we dont need no thought control no we dont"
print procedure(string, "dont")
assert procedure(string, "dont")
Why is this not running in python?! The problem is on print procedure(string, "dont") it mentions invalid syntax. I am running it in the IDLE.

The following is your code with the indentation fixed, compare this with what you posted and you should see why it now works.
It is unclear to me why your original code has a problem because the indentation controls how python views the blocks of code and will fail to run if the indentation is incorrect. I suspect that your problem is that you had these lines in your code:
for i in range(len(words)):
if words[i]==target: solution.append(i)
if len(solution)==0: return False
The above will fail and return False because solution length will be 0 on the first iteration if your word is not found on the first iteration, you should check the len of solution outside the scope of the for loop.
In [42]:
def procedure(string,target):
words=string.split(" ") #turn the string into a list of words
solution=[] #list that will be displayed
for i in range(len(words)):
if words[i]==target: solution.append(i)
if len(solution)==0: return False
return solution
string="we dont need no education we dont need no thought control no we dont"
print(procedure(string, "dont"))
assert(procedure(string, "dont"))
[1, 6, 13]

You can user a list comprehension for this:
def list_word_indexes(word, text):
return [index for index, text_word in enumerate(text.split())
if text_word == word]

The problem is on print procedure(string, "dont") it mentions invalid syntax
This means you are using python 3, where print is a function and not a statement. You should add brackets around the argument(s) to print or make sure to use python 2.
eg.
print(procedure(string, "dont"))

Related

Why does it recognize the second capital T as 0?

I'm trying to make a short program that will find all the capital letters in a single string. I got it to work for the first two capital letters but it won't return the correct position of the last capital letter. What did I do wrong?
def capital_indexes(n):
listOfUpperPlaces = []
for x in n:
print(x)
if x.isupper():
characterPlace = n.index(x)
print(characterPlace)
listOfUpperPlaces.append(characterPlace)
return listOfUpperPlaces
print(capital_indexes("TEsTo"))
That is because n.index(x) returns the first occurrence of x in the string n. Because "T" occurs multiple times, n.index(x) returns the first occurrence of "T"
You want to iterate through range(len(n), like
def capital_indexes(n):
listOfUpperPlaces = []
for x in range(len(n)):
print(n[x])
if n[x].isupper():
print(x)
listOfUpperPlaces.append(x)
return listOfUpperPlaces
print(capital_indexes("TEsTo"))
The issue is the call to n.index(x)
This is searching the string to find x, and its able to find a capital T right at the beginning of the string.
A better way to do this would be to use enumerate, which gives you both the index and the item at the same time.
Can't code very well from a phone, but something like:
for index, character in enumerate(n):
if character.isUpper():
list_of_upper_places.append(index)
This will handle duplicates correctly, and will also be faster, since you don't need to search through the string just to count which character you are currently checking. It will be easier to read for most python programmers too.

My code is incorrectly removing a strings from a larger string

"""
This code takes two strings and returns a copy of the first string with
all instances of the second string removed
"""
# This function removes the letter from the word in the event that the
# word has the letter in it
def remove_all_from_string(word, letter):
while letter in word:
find_word = word.find(letter)
word_length = len(word)
if find_word == -1:
continue
else:
word = word[:find_word] + word[find_word + word_length:]
return word
# This call of the function states the word and what letter will be
# removed from the word
print(remove_all_from_string("bananas", "an"))
This code is meant to remove a defined string from a larger define string. In this case the larger string is "bananas" and the smaller string which is removed is "an".
In this case the smaller string is removed multiple times. I believe I am very close to the solution of getting the correct output, but I need the code to output "bas". Instead, it outputs "ba".
The code is supposed to remove all instances of "an" and print whatever is left, however it does not do this. Any help is appreciated.
Your word_length should be len(letter), and as the while ensures the inclusion, don't need to test the value of find_word
def remove_all_from_string(word, replacement):
word_length = len(replacement)
while replacement in word:
find_word = word.find(replacement)
word = word[:find_word] + word[find_word + word_length:]
return word
Note that str.replace exists
def remove_all_from_string(word, replacement):
return word.replace(replacement, "")
You can simply use the .replace() function for python strings.
def remove_all_from_string(word, letter):
word = word.replace(letter, "")
return word
print(remove_all_from_string("bananas", "an"))
Output: bas
The Python language has built-in utilities to do that in a single expression.
The fact that you need to do that, indicates you are doing sme exercise to better understand coding, and that is important. (Hint: to do it in a single glob, just use the string replace method)
So, first thing - avoid using built-in tools that perform more than basic tasks - in this case, in your tentative code, you are using the string find method. It is powerful, but combining it to find and remove all occurrences of a sub-string is harder than doing so step by step.
So, what ou need is to have variables to annotate the state of your search, and your result. Variables are "free" - do not hesitate in creating as many, and updating then inside the proper if blocks to keep track of your solution.
In this case, you can start with a "position = 0", and increase this "0" until you are at the end of the parent string. You check the character at that position - if it does match the starting character of your substring, you update other variables indicating you are "inside a match", and start a new "position_at_substring" index - to track the "matchee". If at any point the character in the main string does not correspond to the character on the substring: not an occurrence, you bail out (and copy the skipped charactrs to your result -therefore you also have to accumulate all skipped characters in a "match_check" substring) .
Build your code with the simplest 'while', 'if' and variable updates - stick it all inside a function, so that whenever it works, you can reuse it at will with no effort, and you will have learned a lot.

How to search and get the second word in a string that has two of the search word in Python 3?

I am making a Python script that finds the word "Hold" in a list string and confirms if it is holdable or not.
File = [
"Hold_Small_Far_BG1_123456789.jpg",
"Firm_Large_Near_BG1_123456789.jpg",
"Move_Large_Far_BG1_123456789.jpg",
"Firm_Large_Far_BG1_123456789.jpg",
"Hold_Small_Hold_BG1_123456789.jpg",
"Hold_Small_Near_BG1_123456789.jpg",
"Small_Small_Far_BG1_123456789.jpg",
]
for item in File:
if "Hold" in item: return print('Yes, object is holdable.')
else: return print('No, object is not holdable.')
The code above sees the first 'Hold' word and returns true. The holdable objects are the ones that have 'Hold' as the third word.
The problem is the code sees the first 'Hold' word and returns true. I want the code to check if there's a word 'Hold' in the filename while ignoring the first 'Hold' word.
Please note that I cannot split the string using the '_' because it is generated by people. So, sometimes it can be a comma, dot, or space even.
Is there an expression for this? Sorry for the bad English.
Thank you. :)
You can use a regex pattern:
import re
holdables = ['yes' if re.findall(r'\w.*(Hold)', x) else 'no' for x in File]
for x in holdables:
print(x)
The regex here only assumes that 'Hold' is not the first word in the string but does exist elsewhere, since you said you can't be sure whether underscores or other delimiters will be present. If you need more stringent conditions for the regex pattern, you can always update it.
If I have understood the question correctly, we want to find if the filename contains "Hold" anywhere ignoring the first occurrence. Without definite separators, however, it is difficult. Here are two approaches that I think could work:
Using regex like:
import re
for fname in File:
if re.match("(^.+Hold.*$)", fname):
#code if hold is found
Assumptions: This answer relies on the assumption that Hold can only occur only in the third position and first position if it does occur. We ignore the first in this case and search for the third "hold"
>>> re.match("(^.+Hold.*$)", "Hold_Small_Hold_BG1_123456789.jpg")
<re.Match object; span=(0, 33), match='Hold_Small_Hold_BG1_123456789.jpg'>
>>> re.match("(^.+Hold.*$)", "Hold_Small_Far_BG1_123456789.jpg")
>>>
Use split()
We can split the string with "Hold". When "Hold" is present in the third position, we get a list with either 2 or 3 elements.
for fname in File:
if len(fname.split("Hold")) == 3:
#code if hold is found
Again the assumption is that Hold can only occur only at the third position and first position if it does occur.
>>> "Hold_Small_Hold_BG1_123456789.jpg".split("Hold")
['', '_Small_', '_BG1_123456789.jpg'] #list with 3 elements
>>> "Hold_Small_Far_BG1_123456789.jpg".split("Hold")
['', '_Small_Far_BG1_123456789.jpg'] #list with 2 elements
i = 0
while (i< len(File)):
s = File[i]; ct = 0
ct = s.count('Hold')
if ct >1:
print ('Yes, object is holdable.')
else:
print ('No, object is not holdable.')
i+=1
Edited, now it works only if 'Hold' appears more than once.

How to change a single letter in input string

I'm newbie in Python so that I have a question. I want to change letter in word if the first letter appears more than once. Moreover I want to use input to get the word from user. I'll present the problem using an example:
word = 'restart'
After changes the word should be like this:
word = 'resta$t'
I was trying couple of ideas but always I got stuck. Is there any simple sollutions for this?
Thanks in advance.
EDIT: In response to Simas Joneliunas
It's not my homework. I'm just finished reading some basic Python tutorials and I found some questions that I couldn't solve on my own. My first thought was to separate word into a single letters and then to find out the place of the letter I want to replace by "$". I have wrote that code but I couldn't came up with sollution how to get to specific place and replace it.
word = 'restart'
how_many = {}
for x in word:
how_many=+1
else:
how_many=1
for y in how_many:
if how_many[y] > 0:
print(y,how_many[y])
Using str.replace:
s = "restart"
new_s = s[0] + s[1:].replace(s[0], "$")
Output:
'resta$t'
Try:
"".join([["$" if ch in word[:i] else ch for i, ch in enumerate(word)])
enumerate iterates through the string (i.e. a list of characters) and keeps a running index of the iteration
word[:i] checks the list of chars until the current index, i.e. previously appeared characters
"$" if ch in word[:i] else ch means replace the character at existing position with $ if it appears before others keep the character
"".join() joins the list of characters into a single string.
This is where the python console is handy and lets you experiment. Since you have to keep track of number of letters, for a good visual I would list the alphabet in a list. Then in the loop remove from the list the current letter. If letter does not exist in the list replace the letter with $.
So check if it exists first thing in the loop, if it exists, remove it, if it doesn’t exist replace it from example above.

Python - Capture string with or without specific character

I am trying to capture the sentence after a specific word. Each sentences are different in my code and those sentence doesn't necessarily have to have this specific word to split by. If the word doesn't appear, I just need like blank string or list.
Example 1: working
my_string="Python is a amazing programming language"
print(my_string.split("amazing",1)[1])
programming language
Example 2:
my_string="Java is also a programming language."
print(my_string.split("amazing",1)[1]) # amazing word doesn't appear in the sentence.
Error: IndexError: list index out of range
Output needed :empty string or list ..etc.
I tried something like this, but it still fails.
my_string.split("amazing",1)[1] if my_string.split("amazing",1)[1] == None else my_string.split("amazing",1)[1]
When you use the .split() argument you can specify what part of the list you want to use with either integers or slices. If you want to check a specific word in your string you can do is something like this:
my_str = "Python is cool"
my_str_list = my_str.split()
if 'cool' in my_str_list:
print(my_str)`
output:
"Python is cool"
Otherwise, you can run a for loop in a list of strings to check if it finds the word in multiple strings.
You have some options here. You can split and check the result:
tmp = my_string.split("amazing", 1)
result = tmp[1] if len(tmp) > 1 else ''
Or you can check for containment up front:
result = my_string.split("amazing", 1)[1] if 'amazing' in my_string else ''
The first option is more efficient if most of the sentences have matches, the second one if most don't.
Another option similar to the first is
result = my_string.split("amazing", 1)[-1]
if result == my_string:
result = ''
In all cases, consider doing something equivalent to
result = result.lstrip()
Instead of calling index 1, call index -1. This calls the last item in the list.
my_string="Java is also a programming language."
print(my_string.split("amazing",1)[1])
returns ' programming language.'

Categories

Resources