I'm doing a Telegram bot and I want to print string in Inline keyboard. I have a variable text which can change and I want to chack how much lines(string) in variable as it can do with it 0<name<2 and do restrictions. How can do it?
I could make it with len(), but it show me list index out range
text="head,hand,..."
selectKeyboard = telebot.types.InlineKeyboardMarkup( row_width=1)
if 0<name<2:
for i in range(len(text)):
one=types.InlineKeyboardButton(text=str(text[0]['name']),callback_data="first")
selectKeyboard.add(one)
if 0<name<3:
for i in range(len(text)):
one=types.InlineKeyboardButton(text=str(text[0]['name'])+" ",callback_data="first")
two=types.InlineKeyboardButton(text=str(text[1]['name'])+" ",callback_data="second")
selectKeyboard.add(one,two)
if 0<name<4:
for i in range(len(text)):
one=types.InlineKeyboardButton(text=str(text[0]['name'])+" ",callback_data="first")
two=types.InlineKeyboardButton(text=str(text[1]['name'])+" ",callback_data="second")
three = types.InlineKeyboardButton(text=str(text[2]['name']) + " " ,callback_data="three")
selectKeyboard.add(one,two,three)
if 0<name<5:
for i in range(len(text)):
one=types.InlineKeyboardButton(text=str(text[0]['name'])+" ",callback_data="first")
two=types.InlineKeyboardButton(text=str(text[1]['name'])+" "+,callback_data="second")
three = types.InlineKeyboardButton(text=str(text[2]['name']) + " " ,callback_data="three")
four = types.InlineKeyboardButton(text=str(text[3]['name']) + " " , callback_data="four")
selectKeyboard.add(one,two,three,four)
if 0<name<6:
for i in range(len(text)):
one=types.InlineKeyboardButton(text=str(text[0]['name'])+" ",callback_data="first")
two=types.InlineKeyboardButton(text=str(text[1]['name'])+" ",callback_data="second")
three = types.InlineKeyboardButton(
text=str(text[2]['name']) + " " ,
callback_data="three")
four = types.InlineKeyboardButton(
text=str(text[3]['name']) + " " ,
callback_data="four")
five=types.InlineKeyboardButton(
text=str(text[4]['name']) + " " ,
callback_data="five")
selectKeyboard.add(one, two, three, four,five)
The following piece of code is not doing what you imagine, in fact it'll just return False, because name is a string and you're comparing it against integers:
0 < name < 2
Instead, you should test for the number of variables, like this:
text = "head,hand,..."
num_vars = len(text.split(','))
if 0 < num_vars < 2:
# same for all the other comparisons
Related
I need the print were words in my list are separated with space, but the result of my print is as follows
['Salt']
So it prints it as list with quotations :(
sry code is in Finnish :S
def poistaTuote(Tuotteet):
print("Ostoslistassasi on " + str(len(Tuotteet)) + " tuotetta.")
Index = int(input("Anna poistettavan tuotteen järjestysnumero: "))
Index = (Index)-1
for i in range(len(Tuotteet)):
if (Index == Tuotteet[i].index):
Index = i
if (Index == -1):
print("Indeksiä " + str(Index) + " ei löydy.")
print("Tuotteiden järjestysnumerot alkavat numerosta 1.")
else:
del Tuotteet[Index]
print("\nOstoslistasi sisältää seuraavat tuotteet:")
print(Tuotteet, end = " ")
return Tuotteet
Current output:
Ostoslistasi sisältää seuraavat tuotteet:
['Leipä', ' Leivän päälliset']
Desired output
Leipä Leivän päälliset
Spread the list elements as separate arguments to print:
print(*Tuotteet)
Or use str.join:
print(" ".join(Tuotteet))
I am trying to print out the phrase variable to the terminal using multiple strings. I am trying to replace one string with another string.
I don't know what to try to make sure the code will concatenate.
firstName = "jason", "jennifer"
LastName = "Maraz", "Lopez"
actor = firstName[0], LastName[0]
actress = firstName[1], LastName[1]
introduceActor= "hi my name is ".join(actor)
print (actor, actress)
s = "lucky"
t = "happy", "greatful", "nice"
phrase = "I am so " + str(s) + " see " + actor + " today. I am as " + str(s) + " as could be"
phrase = phrase.replace(str(s), str(t[1]))
phrase2 = introduceActor
print(phrase)
print(phrase2)
index = phrase.find("i")
print(index)
the error I got was:
File "/Users/zachary/Documents/code proejcts/Test.py", line 11, in <module>
phrase = "I am so " + str(s) + " see " + actor + " today. I am as " + str(s) + " as could be"
TypeError: can only concatenate str (not "tuple") to str
Your "actor" and "actress" are tuples that hold 2 strings each.
For your purpose, you should probably use:
actor = firstName[0] + LastName[0]
actress = firstName[1] + LastName[1]
That way, you will have strings instead of tuples. Check here for more information
I've written a function that surrounds a search term with a HTML element with given attributes. The idea is the resulting surrounded string is written to a log file later on with the search term highlighted.
def inject_html(needle, haystack, html_element="span", html_attrs={"class":"matched"}):
# Find all occurrences of a given string in some text
# Surround the occurrences with a HTML element and given HTML attributes
new_str = haystack
start_index = 0
while True:
try:
# Get the bounds
start = new_str.lower().index(needle.lower(), start_index)
end = start + len(needle)
# Needle is present, compose the HTML to inject
html_open = "<" + html_element + " " + " ".join(["%s=\"%s\""%(k,html_attrs[k]) for k in html_attrs]) + ">"
html_close = "</" + html_element + ">"
new_str = new_str[0:start] + html_open + new_str[start:end] + html_close + new_str[end:len(new_str)]
start_index = end + len(html_close) + len(html_open)
except ValueError as ex:
# String doesn't occur in text after index, break loop
break
return new_str
I want to open this up to accept an array of needles, locating and surrounding them with HTML in the haystack. I could easily do this by surrounding the code with another loop which iterates through the needles, locating and surrounding instances of the search term. Problem is, this doesn't protect from accidentally surrounding previously injected HTML code., e.g.
def inject_html(needles, haystack, html_element="span", html_attrs={"class":"matched"}):
# Find all occurrences of a given string in some text
# Surround the occurrences with a HTML element and given HTML attributes
new_str = haystack
for needle in needles:
start_index = 0
while True:
try:
# Get the bounds
start = new_str.lower().index(needle.lower(), start_index)
end = start + len(needle)
# Needle is present, compose the HTML to inject
html_open = "<" + html_element + " " + " ".join(["%s=\"%s\""%(k,html_attrs[k]) for k in html_attrs]) + ">"
html_close = "</" + html_element + ">"
new_str = new_str[0:start] + html_open + new_str[start:end] + html_close + new_str[end:len(new_str)]
start_index = end + len(html_close) + len(html_open)
except ValueError as ex:
# String doesn't occur in text after index, break loop
break
return new_str
search_strings = ["foo", "pan", "test"]
haystack = "Foobar"
print(inject_html(search_strings,haystack))
<s<span class="matched">pan</span> class="matched">Foo</span>bar
On the second iteration, the code searches for and surrounds the "pan" text from the "span" that was inserted in the previous iteration.
How would you recommend I change my original function to look for a list of needles without the risk of injecting HTML into undesired locations (such as within existing tags).
--- UPDATE ---
I got around this by maintaining a list of "immune" ranges (ones which have already been surrounded with HTML and therefore do not need to be checked again.
def inject_html(needles, haystack, html_element="span", html_attrs={"class":"matched"}):
# Find all occurrences of a given string in some text
# Surround the occurrences with a HTML element and given HTML attributes
immune = []
new_str = haystack
for needle in needles:
next_index = 0
while True:
try:
# Get the bounds
start = new_str.lower().index(needle.lower(), next_index)
end = start + len(needle)
if not any([(x[0] > start and x[0] < end) or (x[1] > start and x[1] < end) for x in immune]):
# Needle is present, compose the HTML to inject
html_open = "<" + html_element + " " + " ".join(["%s=\"%s\""%(k,html_attrs[k]) for k in html_attrs]) + ">"
html_close = "</" + html_element + ">"
new_str = new_str[0:start] + html_open + new_str[start:end] + html_close + new_str[end:len(new_str)]
next_index = end + len(html_close) + len(html_open)
# Add the highlighted range (and HTML code) to the list of immune ranges
immune.append([start, next_index])
except ValueError as ex:
# String doesn't occur in text after index, break loop
break
return new_str
It's not particularly Pythonic though, I'd be interested to see if anyone can come up with something cleaner.
I'd use something like this:
def inject_html(phrases, text_body, html_element_name="span", html_attrs={"class":"matched"}):
new_text_body = []
html_start_tag = "<" + html_element_name + " ".join(["%s=\"%s\""%(k,html_attrs[k]) for k in html_attrs]) + ">"
html_end_tag = "</" + html_element_name + ">"
text_body_lines = text_body.split("\n")
for line in text_body_lines:
for p in phrases:
if line.lower() == p.lower():
line = html_start_tag + p + html_end_tag
break
new_text_body.append(line)
return "\n".join(new_text_body)
It goes through line by line and replaces each line if the line is an exact match (case-insensitive).
ROUND TWO:
With the requirement that the match needs to be (1) case-insensitive and (2) matches multiple words/phrases on each line, I would use:
import re
def inject_html(phrases, text_body, html_element_name="span", html_attrs={"class": "matched"}):
html_start_tag = "<" + html_element_name + " " + " ".join(["%s=\"%s\"" % (k, html_attrs[k]) for k in html_attrs]) + ">"
html_end_tag = "</" + html_element_name + ">"
for p in phrases:
text_body = re.sub(r"({})".format(p), r"{}\1{}".format(html_start_tag, html_end_tag), text_body, flags=re.IGNORECASE)
return text_body
For each provided phrase p, this uses a case-insensitive re.sub() replacement to replace all instances of that phrase in the provided text. (p) matches the phrase via a regular expression group. \1 is a backfill operator that matches the found phrase, enclosing it in HTML tags.
text = """
Somewhat more than forty years ago, Mr Baillie Fraser published a
lively and instructive volume under the title _A Winter’s Journey
(Tatar) from Constantinople to Teheran. Political complications
had arisen between Russia and Turkey - an old story, of which we are
witnessing a new version at the present time. The English government
deemed it urgently necessary to send out instructions to our
representatives at Constantinople and Teheran.
"""
new = inject_html(["TEHERAN", "Constantinople"], text)
print(new)
> Somewhat more than forty years ago, Mr Baillie Fraser published a lively and instructive volume under the title _A Winter’s Journey (Tatar) from <span class="matched">Constantinople</span> to <span class="matched">Teheran</span>. Political complications had arisen between Russia and Turkey - an old story, of which we are witnessing a new version at the present time. The English government deemed it urgently necessary to send out instructions to our representatives at <span class="matched">Constantinople</span> and <span class="matched">Teheran</span>.
I have made a function, were I count how many times each word is used in a file, that will say the word frequency. Right now the function can calculate the sum of all words, and show me the seven most common words and how many times they are used. Now I want to compare my first file were I have analyzed the word frequency with another file were I have the most common words used in the english language, and I want to compare those words with the words I have in my first file to see if any of the words matches.
What I have come up to is to make lists of the two files and then compare them with each other. But the code I wrote for this doesn't give me any output, any idea on how I can solve this?
def CountWords():
filename = input('What is the name of the textfile you want to open?: ')
if filename == "alice" or "alice-ch1.txt" or " ":
file = open("alice-ch1.txt","r")
print('You want to open alice-ch1.txt')
wordcount = {}
for word in file.read().split():
if word not in wordcount:
wordcount[word] = 1
else:
wordcount[word] += 1
wordcount = {k.lower(): v for k, v in wordcount.items() }
print (wordcount)
sum = 0
for val in wordcount.values():
sum += val
print ('The total amount of words in Alice adventures in wonderland: ' + str(sum))
sortList = sorted(wordcount.values(), reverse = True)
most_freq_7 = sortList[0:7]
#print (most_freq_7)
print ('Totoro says: The 7 most common words in Alice Adventures in Wonderland:')
print(list(wordcount.keys())[list(wordcount.values()).index(most_freq_7[0])] + " " + str(most_freq_7[0]))
print(list(wordcount.keys())[list(wordcount.values()).index(most_freq_7[1])] + " " + str(most_freq_7[1]))
print(list(wordcount.keys())[list(wordcount.values()).index(most_freq_7[2])] + " " + str(most_freq_7[2]))
print(list(wordcount.keys())[list(wordcount.values()).index(most_freq_7[3])] + " " + str(most_freq_7[3]))
print(list(wordcount.keys())[list(wordcount.values()).index(most_freq_7[4])] + " " + str(most_freq_7[4]))
print(list(wordcount.keys())[list(wordcount.values()).index(most_freq_7[5])] + " " + str(most_freq_7[5]))
print(list(wordcount.keys())[list(wordcount.values()).index(most_freq_7[6])] + " " + str(most_freq_7[6]))
file_common = open("common-words.txt", "r")
commonwords = []
contents = file_common.readlines()
for i in range(len(contents)):
commonwords.append(contents[i].strip('\n'))
print(commonwords)
#From here's the code were I need to find out how to compare the lists:
alice_keys = wordcount.keys()
result = set(filter(set(alice_keys).__contains__, commonwords))
newlist = list()
for elm in alice_keys:
if elm not in result:
newlist.append(elm)
print('Here are the similar words: ' + str(newlist)) #Why doesn't show?
else:
print ('I am sorry, that filename does not exist. Please try again.')
I'm not in front of an interpreter so my code might be slightly off. But try something more like this.
from collections import Counter
with open("some_file_with_words") as f_file
counter = Counter(f_file.read())
top_seven = counter.most_common(7)
with open("commonwords") as f_common:
common_words = f_common.read().split()
for word, count in top_seven:
if word in common_words:
print "your word " + word + " is in the most common words! It appeared " + str(count) + " times!"
At some point of the program I ask it to take the user's text input and separate the text according to it's commas, and then I ",".join it again in a txt file. The idea is to have a list with all the comma separated information.
The problem is that, apparently, when I ",".join it, it separates every single character with commas, so if I've got the string info1,info2 it separates, getting info1 | info2, but then, when joining it back again it ends like i,n,f,o,1,,,i,n,f,o,2, which is highly unconfortable, since it get's the text back from the txt file to show it to the user later in the program. Can anyone help me with that?
categories = open('c:/digitalLibrary/' + connectedUser + '/category.txt', 'a')
categories.write(BookCategory + '\n')
categories.close()
categories = open('c:/digitalLibrary/' + connectedUser + '/category.txt', 'r')
categoryList = categories.readlines()
categories.close()
for category in BookCategory.split(','):
for readCategory in lastReadCategoriesList:
if readCategory.split(',')[0] == category.strip():
count = int(readCategory.split(',')[1])
count += 1
i = lastReadCategoriesList.index(readCategory)
lastReadCategoriesList[i] = category.strip() + "," + str(count).strip()
isThere = True
if not isThere:
lastReadCategoriesList.append(category.strip() + ",1")
isThere = False
lastReadCategories = open('c:/digitalLibrary/' + connectedUser + '/lastReadCategories.txt', 'w')
for category in lastReadCategoriesList:
if category.split(',')[0] != "" and category != "":
lastReadCategories.write(category + '\n')
lastReadCategories.close()
global finalList
finalList.append({"Title":BookTitle + '\n', "Author":AuthorName + '\n', "Borrowed":IsBorrowed + '\n', "Read":readList[len(readList)-1], "BeingRead":readingList[len(readingList)-1], "Category":BookCategory + '\n', "Collection":BookCollection + '\n', "Comments":BookComments + '\n'})
finalList = sorted(finalList, key=itemgetter('Title'))
for i in range(len(finalList)):
categoryList[i] = finalList[i]["Category"]
toAppend = (str(i + 1) + ".").ljust(7) + finalList[i]['Title'].strip()
s.append(toAppend)
categories = open('c:/digitalLibrary/' + connectedUser + '/category.txt', 'w')
for i in range(len(categoryList)):
categories.write(",".join(categoryList[i]))
categories.close()
You should pass ''.join() a list, you are passing in a single string instead.
Strings are sequences too, so ''.join() treats every character as a separate element instead:
>>> ','.join('Hello world')
'H,e,l,l,o, ,w,o,r,l,d'
>>> ','.join(['Hello', 'world'])
'Hello,world'