I'm trying to make a game, where a song name is picked from a file, and the title is replaced with underscores (apart from the first letter)
However I'm not sure how to add a space into it, as some songs are more than one word, this is what I have currently:
def QuizStart():
line = random.choice(open('songnamefile.txt').readlines())
line.split('-')
songname, artist = line.split('-')
underscoresong = songname
i=0
song_name = range(1,len(songname))
for i in song_name:
if ' ' in song_name:
i=i+1
else:
underscoresong = underscoresong.replace(songname[i],"_")
i=i+1
print(underscoresong, ' - ', artist)
It would be good to include expected output for a given input examples.
You can just multiply an array containing the placeholder character n times. e.g.:
songname = 'My blue submarine'
underscoresong = ''.join([songname[0]] + ['_'] * (len(songname) - 1))
print(underscoresong)
Output:
M________________
That will add the first character and then the underscore for as long as the songname is, minus one (for the first character). The join converts it to a string.
Or if you want to preserve spaces:
underscoresong = ''.join(
[songname[0]] + ['_' if c != ' ' else ' ' for c in songname[1:]]
)
print(underscoresong)
Output:
M_ ____ _________
Or if you want to also preserve the single quote:
songname = "God's Plan-Drake"
underscoresong = ''.join(
[songname[0]] +
['_' if c not in {' ', "'"} else c for c in songname[1:]]
)
print(underscoresong)
Output:
G__'_ __________
You could also use regular expressions:
import re
songname = "God's Plan-Drake"
underscoresong = songname[0] + re.sub(r"[^ ']", '_', songname[1:])
print(underscoresong)
Output:
G__'_ __________
Related
Can someone explain to me what
nextLine().split("\\s+")
does and how would I convert that to python?
Thanks
i wanted to use it but its in java
split takes an input string, possibly a regular expression (in your case) and uses the regex as a delimiter. Here, the regex is simply \s+ (the extra backslash is to escape the string), where \s denotes any sort of white space and + means "one or more", so basically, if I have the string "Hello world ! ." you will have the output ["Hello", "world", "!", "."].
In Python, you need to use the re library for this functionality:
re.split(r"\s+", input_str)
Or, just for this specific case (as #Kurt pointed out), input_str.split() will do the trick.
The nextLine() is used to read user input, and split("\\s+") will split it to a bunch of elements based on a specific delimiter, and for this case the delim is a regex \\s+.
The equivalent of it in python is this, by using the :
import re
s = input()
sub_s = re.split(r"\s+", s)
# hello and welcome everyone
# ['hello', 'and', 'welcome', 'everyone']
code in java
import java.util.*;
public class MyClass {
public static void main(String args[]) {
String s = "Hello my Wonderful\nWorld!";
// nextLine()
Scanner scanner = new Scanner(s);
System.out.println("'" + scanner.nextLine() + "'");
System.out.println("'" + scanner.nextLine() + "'");
scanner.close();
// nextLine().split("\\s+")
scanner = new Scanner(s);
String str[] = scanner.nextLine().split("\\s+");
System.out.println("*" + str[2] + "*");
scanner.close();
}
}
python
s = "Hello my Wonderful\nWorld!";
o = s.split("\n")
print ("'" + o[0] + "'")
print ("'" + o[1] + "'")
'''
resp. use of
i = s.find('\n')
print (s[:i])
print (s[i+1:])
e.g.
def get_lines(str):
start = 0
end = 0
sub = '\n'
while True:
end = str.find(sub, start)
if end==-1:
yield str[start:]
return
else:
yield str[start:end]
start = end + 1
i = iter(get_lines(s))
print ("'" + next (i) + "'")
print ("'" + next (i) + "'")
'''
o = s.split()
print ("*" + o[2] + "*")
output
'Hello my Wonderful'
'World!'
*Wonderful*
I am trying to get this code to split one at a time, but it is not functioning as expected:
for line in text_line:
one_line = line.split(' ',1)
if len(one_line) > 1:
acro = one_line[0].strip()
meaning = one_line[1].strip()
if acro in acronyms_dict:
acronyms_dict[acro] = acronyms_dict[acro] + ', ' + meaning
else:
acronyms_dict[acro] = meaning
Remove the ' ' from the str.split. The file is using tabs to delimit the acronyms:
import requests
data_site = requests.get(
"https://raw.githubusercontent.com/priscian/nlp/master/OpenNLP/models/coref/acronyms.txt"
)
text_line = data_site.text.split("\n")
acronyms_dict = {}
for line in text_line:
one_line = line.split(maxsplit=1) # <-- remove the ' '
if len(one_line) > 1:
acro = one_line[0].strip()
meaning = one_line[1].strip()
if acro in acronyms_dict:
acronyms_dict[acro] = acronyms_dict[acro] + ", " + meaning
else:
acronyms_dict[acro] = meaning
print(acronyms_dict)
Prints:
{
'24KHGE': '24 Karat Heavy Gold Electroplate',
'2B1Q': '2 Binary 1 Quaternary',
'2D': '2-Dimensional',
...
I am trying to remove spaces.
I have tried everything from previous threads including re.sub
Code:
wordinput = (input("Input:\n"))
wordinput = wordinput.lower()
cleanword = wordinput.replace(" ","")
cleanword = wordinput.replace(",","")
cleanword = wordinput.replace(".","")
revword = cleanword [::-1]
print(cleanword)
print(revword)
print("Output:")
if (cleanword == revword):
print('"The word ' + wordinput + ' is a palindrome!"')
else:
print('"Unfortunately the word ' + wordinput + ' is not a palindrome. :(')
Output:
Input:
mr owl ate my metal worm
mr owl ate my metal worm
mrow latem ym eta lwo rm
Output:
"Unfortunately the word mr owl ate my metal worm is not a palindrome. :(
The problem you are having is here:
cleanword = wordinput.replace(" ","")
cleanword = wordinput.replace(",","")
cleanword = wordinput.replace(".","")
You are not saving the results of the previous replace.
Try:
cleanword = wordinput.replace(" ", "").replace(",", "").replace(".", "")
#StephenRauch explains your problem well.
But here is a better way to implement your logic:
chars = ',. '
wordinput = 'mr owl ate my metal worm '
cleanword = wordinput.translate(dict.fromkeys(map(ord, chars)))
# 'mrowlatemymetalworm'
Did you try something like:
import re
cleanword = re.sub(r'\W+', '', wordinput.lower())
wordinput = (input("Input:\n"))
cleanword=''.join([e for e in wordinput.lower() if e not in ", ."])
You could try this comprehension
Maybe you should try this one:
wordinput = raw_input("Input:\n")
cleanword =''.join([x for x in wordinput.lower() if x not in (',','.',' ')])
if cleanword[:] == cleanword[::-1]:
print ('"The word ' + wordinput + ' is a palindrome!"')
else:
print ('"The word ' + wordinput + ' is not a palindrome!"')
After first replace, on subsequent replace, you need to use cleanword which is the updated string instead of wordinput. You can try following:
wordinput = (input("Input:\n"))
wordinput = wordinput.lower()
cleanword = wordinput.replace(" ","")
# updating 'cleanword' and saving it
cleanword = cleanword.replace(",","")
cleanword = cleanword.replace(".","")
revword = cleanword [::-1]
print(cleanword)
print(revword)
print("Output:")
if (cleanword == revword):
print('"The word ' + wordinput + ' is a palindrome!"')
else:
print('"Unfortunately the word ' + wordinput + ' is not a palindrome. :(')
During the analysis of tweets, I run in the "words" that have either \ or / (could have more than one appearance in one "word"). I would like to have such words removed completely but can not quite nail this
This is what I tried:
sen = 'this is \re\store and b\\fre'
sen1 = 'this i\s /re/store and b//fre/'
slash_back = r'(?:[\w_]+\\[\w_]+)'
slash_fwd = r'(?:[\w_]+/+[\w_]+)'
slash_all = r'(?<!\S)[a-z-]+(?=[,.!?:;]?(?!\S))'
strt = re.sub(slash_back,"",sen)
strt1 = re.sub(slash_fwd,"",sen1)
strt2 = re.sub(slash_all,"",sen1)
print strt
print strt1
print strt2
I would like to get:
this is and
this i\s and
this and
However, I receive:
and
this i\s / and /
i\s /re/store b//fre/
To add: in this scenario the "word" is a string separated either by spaces or punctuation signs (like a regular text)
How's this? I added some punctuation examples:
import re
sen = r'this is \re\store and b\\fre'
sen1 = r'this i\s /re/store and b//fre/'
sen2 = r'this is \re\store, and b\\fre!'
sen3 = r'this i\s /re/store, and b//fre/!'
slash_back = r'\s*(?:[\w_]*\\(?:[\w_]*\\)*[\w_]*)'
slash_fwd = r'\s*(?:[\w_]*/(?:[\w_]*/)*[\w_]*)'
slash_all = r'\s*(?:[\w_]*[/\\](?:[\w_]*[/\\])*[\w_]*)'
strt = re.sub(slash_back,"",sen)
strt1 = re.sub(slash_fwd,"",sen1)
strt2 = re.sub(slash_all,"",sen1)
strt3 = re.sub(slash_back,"",sen2)
strt4 = re.sub(slash_fwd,"",sen3)
strt5 = re.sub(slash_all,"",sen3)
print(strt)
print(strt1)
print(strt2)
print(strt3)
print(strt4)
print(strt5)
Output:
this is and
this i\s and
this and
this is, and!
this i\s, and!
this, and!
One way you could do it without re is with join and a comprehension.
sen = 'this is \re\store and b\\fre'
sen1 = 'this i\s /re/store and b//fre/'
remove_back = lambda s: ' '.join(i for i in s.split() if '\\' not in i)
remove_forward = lambda s: ' '.join(i for i in s.split() if '/' not in i)
>>> print(remove_back(sen))
this is and
>>> print(remove_forward(sen1))
this i\s and
>>> print(remove_back(remove_forward(sen1)))
this and
I am not using Python but I have script in python:
part of script
elif line.find("CONECT") > -1:
con = line.split()
line_value = line_value + 1
#print line_value
#print con[2]
try:
line_j = "e" + ', ' + str(line_value) + ', ' + con[2] + "\n"
output_file.write(line_j)
print(line_j)
line_i = "e" + ', ' + str(line_value) + ', ' + con[3] + "\n"
output_file.write(line_i)
print(line_i)
line_k = "e"+ ', ' + str(line_value) + ', ' + con[4] + "\n"
print(line_k)
output_file.write(line_k)
except IndexError:
continue
which give .txt output in format
e, 1, 2
e, 1, 3
e, 1, 4
e, 2, 1
e, 2, 3
etc.
I need remove similar lines with the same numbers, but no matter on order this numbers
i.e. line e, 2, 1..
Is it possible?
Of course, it is better to modify your code to remove that lines BEFORE you're writing them to file. You can use a list to store already saved values, and on each itereation, perfom a search if the values you're want to add is already exists in that list. The code below isn't tested and optimized, but it explains an idea:
# 'added = []' should be placed somewhere before 'if'
added = []
# you part of code
elif line.find("CONECT") > -1:
con = line.split()
line_value = line_value + 1
try:
line_j = "e, %s, %s\n" % (str(line_value),con[2])
tmp = sorted((str(line_value),con[2]))
if tmp not in added:
added.append(tmp)
output_file.write(line_j)
print(line_j)
line_i = "e, %s, %s\n" % (str(line_value),con[3])
tmp = sorted((str(line_value),con[3]))
if tmp not in added:
added.append(tmp)
output_file.write(line_i)
print(line_i)
line_k = "e, %s, %s\n" % (str(line_value),con[4])
tmp = sorted((str(line_value),con[4]))
if tmp not in added:
added.append(tmp)
print(line_k)
output_file.write(line_k)
except IndexError:
continue
Here is a comparison method for two lines of your file:
def compare(line1, line2):
els1 = line1.strip().split(', ')
els2 = line2.strip().split(', ')
return Counter(els1) == Counter(els2)
See the documentation for the Counter class.
If the count of elements doesn't matter you can replace the Counter class with set instead
The following approach should work. First add the following line further up in your code:
seen = set()
Then replace everything inside the try with the following code:
for con_value in con[2:5]:
entry = frozenset((line_value, con_value))
if entry not in seen:
seen.append(entry)
line_j = "e" + ', ' + str(line_value) + ', ' + con_value + "\n"
output_file.write(line_j)
print(line_j)
Make sure this code is indented to the same level as the code it replaces.