python issue in anagram script - python

Second modification to the script (changes made below)
Made the changes mentioned in the comments (renamed all to print_all, and added the excepetion, changed the code below to reflect the same)
However, execution still exits without any reason
Initial query:
The following is a script that tries to identify various anagrams of a word (as in the website: http://wordsmith.org/anagram/anagram.cgi?anagram=suchindra&t=1000&a=n):
import sys
import itertools
import threading
from collections import defaultdict
words_dict = defaultdict(lambda: "")
def lower_and_nocrlf(s):
return s.lower().strip()
def two_or_more(s):
if len(s) >= 1:
return 1
else:
return 0
def get_perms(cur_iter):
lst = []
for i in range(0, 10000):
try:
lst.append("".join(cur_iter.next()))
except:
break
return lst
def get_twordlist(z):
lst1 = []
lst2 = []
for i in range (1, len(z)):
lst1.append(z[:i])
lst2.append(z[i:])
return lst1, lst2
def filter_dict(x):
if x in words_dict.keys():
return x
else:
return 0
def main():
print_all = None
word = None
try:
word = sys.argv[1]
print_all = sys.argv[2]
except:
pass
if word == None:
try:
word = sys.stdin.readline()
print_all = sys.stdin.readline()
except:
pass
if word == None:
sys.exit(1)
fd = open('/usr/apps/words', 'r')
words = fd.readlines()
fd.close()
words_lower = map(lower_and_nocrlf, words)
words_lower = filter(two_or_more, words_lower)
from collections import defaultdict
for i in words_lower:
words_dict[i] = ""
iter = itertools.permutations(word)
all_permutations = []
iters = []
for i in range(0, 100):
iters.append(iter)
result = map(get_perms, iters)
main_list = []
for l in result:
if l != []:
for word in l:
main_list.append(word)
results = []
try:
main_list_len = len(main_list)
for index in range(0, main_list_len):
percent = (index/len(main_list)) * 100
lst1, lst2 = get_twordlist(main_list[index])
result1 = map(filter_dict, lst1)
result2 = map(filter_dict, lst2)
for index in range(0, len(result1)):
if (result1[index] != 0) and (result2[index] != 0):
results.append("%s %s" % (result1[index], result2[index]))
except KeyboardInterrupt:
print("User stopped execution, partial results:")
print results
sys.exit(1)
except Exception:
# catches all other types of exception here
print(sys.exc_info())
traceback.print_exc()
print(results)
if __name__ == "__main__":
try:
main()
except:
sys.exit(0)

So, your code is clearly executing down to the print index line and then failing somewhere inside the block. The exception handler only catches exceptions of type KeyboardInterrupt - i.e. when a user presses Ctl+C on their keyboard. Any other error will exit via the sys.exit(0) method, so you have no way of knowing what the error is.
Personally I quite like the traceback module for these printing out errors, so I suggest you modify your try catch block to be something like:
import traceback
try:
main_list_len = len(main_list)
print main_list_len
for index in range(0, main_list_len):
print index
percent = (index/len(main_list)) * 100
lst1, lst2 = get_twordlist(main_list[index])
result = map(filter_dict, lst1, lst2)
results.append[result]
except KeyboardInterrupt:
print("User stopped execution, partial results:")
print("Exception: %s" % (sys.exc_info()))
print results
except Exception:
# catches all other types of exception here
traceback.print_exc()
This will allow you to debug the problem as the traceback module will give you line numbers and an error message to work with.
Good luck!

OK after some analysis, it looks like filter does not accept more than one list. The second issue is because I am using multiple lists in the filter

Related

One of methods doesn't work correctly when i call it

I need to make two checks in log files and display the result. Separately methods work correctly, but when I run all code method hit_unique_check always return "PASS: All hits are unique.". For two of three .log files this result is incorrect.
import os
class ReadFiles:
def __init__(self):
self.current_file = ""
self.shoot_from = "Shoot from"
self.hit_player = "Hit player"
def equally_check(self):
shoot_from_list = []
hit_player_list = []
for line in self.current_file:
if self.shoot_from in line:
shoot_from_list.append(line)
elif self.hit_player in line:
hit_player_list.append(line)
if len(shoot_from_list) == len(hit_player_list):
print(" PASS: Shoots and hits are equal.\n")
else:
print(" FAIL: Shoots and hits are NOT equal.\n")
def hit_unique_check(self):
unique_hit_list = []
duplicates = []
for line in self.current_file:
if self.hit_player in line:
unique_hit_list.append(line)
else:
continue
for i in unique_hit_list:
if unique_hit_list.count(i) > 1:
duplicates.append(i)
print(i)
else:
continue
if len(duplicates) < 1:
print(" PASS: All hits are unique.\n")
else:
print(" FAIL: This hits are duplicated.\n")
def run(self):
for file in os.listdir():
if file.endswith(".log"):
print(f"Log file - {file}")
self.current_file = open(f"{file}", 'rt')
print(self.current_file.readlines, f"")
self.equally_check()
self.hit_unique_check()
self.current_file.close()
if __name__ == "__main__":
run = ReadFiles()
run.run()
I run my python code, but result always the same: "PASS: All hits are unique.". For some files it must be "FAIL: This hits are duplicated.". I'm not sure that problem in the method hit_unique_check, and have no idea what to do.
Can you explain me, how I can make this method working correctly not only separately?
Consider this organization. Each function has one task, to evaluate and return its result. It's up to the caller to decide what to do with the result. Also note that I'm using counters instead of lists, since you don't really care what the lists contain. Also note the use of defaultdict, to avoid having to do repeated searches of your hit list.
import os
from collections import defaultdict
class ReadFiles:
def __init__(self):
self.shoot_from = "Shoot from"
self.hit_player = "Hit player"
def equally_check(self, lines):
shoot_from = 0
hit_player = 0
for line in lines:
if self.shoot_from in line:
shoot_from += 1
elif self.hit_player in line:
hit_player += 1
return shoot_from == hit_player
def hit_unique_check(self, lines):
unique_hit_list = defaultdict(int)
for line in lines:
if self.hit_player in line:
unique_hit_list[line] += 1
duplicates = 0
for k,v in unique_hit_list.items()
if v > 1:
duplicates += 1
print(k)
return not duplicates
def run(self):
for filename in os.listdir():
if filename.endswith(".log"):
print(f"Log file - {filename}")
lines = open(filename, 'rt').readlines()
print(lines)
if self.equally_check(lines):
print(" PASS: Shoots and hits are equal.\n")
else:
print(" FAIL: Shoots and hits are NOT equal.\n")
if self.hit_unique_check(lines):
print(" PASS: All hits are unique.\n")
else:
print(" FAIL: This hits are duplicated.\n")
if __name__ == "__main__":
run = ReadFiles()
run.run()
You could even replace the loop in hit_unique_check with a counter:
from collections import Counter
...
def hit_unique_check(self,lines):
unique_hit_list = Counter(lines)
for k,v in unique_hit_list,items():
...

this program checks whether it is in the file text.txt that the user has received

If I remove these lines of code:
else:
print("Boş")
break
Then, the program seems to work fine, but when I add it again, the program does not find any words in the text.txt and throw a Not found exception.
Here is the full code:
class x():
def __init__(self):
with open('metin.txt', 'r', encoding="utf-8")as file:
icerik = file.read()
icerik = icerik.split()
self.sade_kelime = []
self.sozluk = dict()
file.seek(0)
for i in icerik:
i = i.strip(".")
i = i.strip(",")
i = i.strip("")
self.sade_kelime.append(i)
for i in self.sade_kelime:
if i in self.sozluk:
self.sozluk[i] += 1
else:
self.sozluk[i] = 1
def kelime_frekans(self):
for i in self.sozluk:
if i == kelime:
print(kelime, self.sozluk[i], "kez metinde geciyor")
else:
print("Boş")
break
dosya = x()
while True:
kelime = input('kelime:')
if kelime == "q":
break
else:
dosya.kelime_frekans()
if i == kelime condition is not satisfy on first iteration, loop will break.
Logically this is not a correct code. Your kelime_frekans function should be like this:
def kelime_frekans(self):
for i in self.sozluk:
if i == kelime:
print(kelime, self.sozluk[i], "kez metinde geciyor")
return
print("Boş")

Tweets in Python

def twitter_search(twitter_api,q,max_results=200,**kw):
search_results = twitter_api.search.tweets(q=q,count=100,**kw)
statuses = search_results['statuses']
max_results=min(1000,max_results)
for _ in range(10):
try:
next_results = search_results['search_metadata']['next_results']
except KeyError, e:
break
kwargs = dict([ kv.split('=')
for kv in next_results[1:].split("&") ])
search_results = twitter_api.search.tweets(**kwargs)
statuses += search_results['statuses']
if len(statuses) > max_results:
break
return statuses
results = twitter_search(twitter_api,q,max_results=10)
print json.dumps(results[0], indent =1)
The last line is returning an error that 'NoneType' object has no attribute __getitem__
You have two issues here:
The return statement is inside the for loop, and might not be reached if the loop hits one of the break statements first. If it is reached, it will return earlier than you want, without running the rest of the loop iterations.
You are assuming results will have at least one element (results[0]). If results is an empty list, this will fail with an IndexError.
Solution:
Move the return statement outside of the for loop (dedent one level).
Check if results: before indexing into it.
The problem is q not have trends :S
q = '#vladimirala1'
count = 100
search_results = twitter_api.search.tweets(q=q, count =count)
statuses = search_results['statuses']
for _ in range(5):
print "Length of statuses", len(statuses)
try:
next_results = search_results['search_metadata']['next_results']
except KeyError, e: # No mas resultados si no hay mas datos
break
kwargs = dict([kv.split('=') for kv in next_results[1:].split('&') ])
search_results = twitter_api.search.tweets(**kwargs)
statuses += search_results['statuses']
print json.dumps(statuses[0], indent=1)

Stopiteration identfying the iterable object

I have 2 generator and using the next method & while loop to process thru it as below,
code
while end_of_loop = 'n':
try:
table1_row = next(table1_generator)
table2_row = next(table2_generator)
except StopIteration:
end_of_loop = 'y'
How do I identify which iterator object has no rows?
Im trying to compare 2 tables and each table rows are in generator objects.
def _compare(self):
end_of_table = 'N'
try:
while end_of_table =='N':
try:
if self.table1_key == self.table2_key:
print 'same key'
self.table1_row = next(self.table1_generator)
self._convert_table1_key_fields()
self.table2_row = next(self.table2_generator)
self._convert_table2_key_fields()
elif self.table1_key > self.table2_key:
self.table2_row = next(self.table1_generator)
self._convert_table2_key_fields()
elif self.table1_key < self.table2_key:
self.table1_row = next(self.table2_generator)
self._convert_table1_key_fields()
except StopIteration as e:
print e.args
print 'IterError'
end_of_table = 'y'
except StopIteration:
print 'Next Iteration'
You can provide a second "sentinel" value to next:
sentinel = object()
while end_of_loop = 'n':
table1_row = next(table1_generator,sentinel)
table2_row = next(table2_generator,sentinel)
#I don't account for the case where they could be exhausted at
#the same time. It's easy to add that if it matters though.
if table1_row is sentinel:
print "table1_generator gave up first"
#"break" might be more appropriate ...
#(Unless there more to the loop than this.)
end_of_loop = 'y'
elif table2_row is sentinel:
print "table2_generator gave up first"
end_of_loop = 'y'
You didn't provide details about the context or what you're actually trying to do, but it sounds like itertools.izip_longest might be useful in your case (and more pythonic). You can fill with Nones or another value which is suitable.
I can't think of a use case for this (care to share?), but I'd try wrapping next into my own function:
def mynext(it):
try:
return next(it)
except StopIteration:
raise StopIteration(it)
and then, for example,
a = iter([1,2,3,4,5])
b = iter([4,5,6,7])
try:
while True:
print mynext(a)
print mynext(b)
except StopIteration as e:
if e.args[0] == a: print 'a ended'
if e.args[0] == b: print 'b ended'

Read file error in Python, even though print function is printing the list

I have been trying different ways of writing this code but cannot get past this. Currently the program will run all the way to the write_names(list) function and create the file, and the print function will print the sorted list. The program refuses to get the user input for the search_names() function but it will print anything I ask it to.
Debug highlights: while index < len(list) and in the debug I\O only states "read file error". Hopefully someone has an idea what I'm doing wrong.
'# Abstract: This program creates a list of names. The list is printed,
'# sorted, printed again, written to file, and searched.
'#=============================================================================
'#define the main function
def main():
#try:
##open data file for read
#infile = open('names.txt', 'r')
#call get_names function
list = get_names()
#call print function
print_names(list)
#sort list
list.sort()
#print sorted list
print_names(list)
#write sorted list to new file
write_names(list)
#allow user to search list
search_names(list)
def get_names():
try:
infile = open('names.txt', 'r')
#read file contents into a list
list = infile.readlines()
#close file
infile.close()
#strip \n from each element
index = 0
while index < len(list):
list[index] = list[index].rstrip('\n')
index += 1
return list
except IOError:
print 'Read file error'
def print_names(list):
#print header
print '******************'
#print list line by line
index = 0
while index < len(list):
print list[index]
index += 1
return
def write_names(list):
#open file for writing
outfile = open('sortedNames.txt', 'w')
#write the list to the file
for item in list:
outfile.write(str(item) + '\n')
#close file
outfile.close()
def search_names(list):
#set user test variable
again = 'Y'
while again.upper == 'Y':
#get search from user
search = raw_input('Enter a name to search for: ')
#open list for search
if search in list:
try:
item_index = list.index(search)
print search, 'found.', item_index
except ValueError:
print search, 'not found.'
main()
'
Thanks in advance!
Your issue is that upper is a function, and you are not calling it. Your while in search_names() should read:
while again.upper() == 'Y':
instead of:
#strip \n from each element
index = 0
while index < len(list):
list[index] = list[index].rstrip('\n')
index += 1
return list
just use this list comprehension:
lines = infile.readlines()
infile.close()
return [ line.strip() for line in lines ]
edit:
It looks like you are using an index and a while loop where a for loop can be used.
Instead of:
while index < len(list):
print list[index]
index += 1
use:
# using name_list instead of list
for name in name_list:
print name
also, your search_names() function looks flawed:
def search_names(list):
#set user test variable
again = 'Y'
while again.upper == 'Y':
#get search from user
search = raw_input('Enter a name to search for: ')
#open list for search
if search in list:
try:
item_index = list.index(search)
print search, 'found.', item_index
except ValueError:
print search, 'not found.'
would never exit (again is never reassigned). try:
def search_names(names_list):
again = 'Y'
while again.upper() == 'Y':
s_name = raw_input('Enter a name to search for: ')
if s_name in names_list:
print s_name, 'found.', names_list.index(s_name)
else:
print search, 'not found.'
again = raw_input('Search for another name (Y|N)?: ')
or:
def search_names(names_list):
again = 'Y'
while again == 'Y':
s_name = raw_input('Enter a name to search for: ')
try:
idx = names_list.index(s_name)
print s_name, 'found.', idx
except ValueError:
print search, 'not found.'
again = raw_input('Search for another name (Y|N)?: ').upper()
Which brings up the issue of when to catch exceptions vs using an if statement:
from msdn:
The method you choose depends on how
often you expect the event to occur.
If the event is truly exceptional and
is an error (such as an unexpected
end-of-file), using exception handling
is better because less code is
executed in the normal case. If the
event happens routinely, using the
programmatic method to check for
errors is better. In this case, if an
exception occurs, the exception will
take longer to handle.
Comments begin with #, not '# - you are making every other line of your header a docstring.
You are using an index to iterate across lists, which is inefficient - just iterate on the list items.
Calling a variable list is bad because it prevents you from accessing the list() datatype.
Using with is a more reliable replacement for open() .. close()
again.upper is a function reference - you have to call the function, ie again.upper().
You never change the value of again - this will be an infinite loop!
You test if search in list but then do a try..except block which will only fail if it is not in the list (ie you are testing for the same failure twice).
.
#
# Operate on a list of names
#
def load_names(fname):
try:
with open(fname, 'r') as inf:
return [line.strip() for line in inf]
except IOError:
print "Error reading file '{0}'".format(fname)
return []
def print_names(namelist):
print '******************'
print '\n'.join(namelist)
def write_names(namelist, fname):
with open(fname, 'w') as outf:
outf.write('\n'.join(namelist))
def search_names(namelist):
while True:
lookfor = raw_input('Enter a name to search for (or nothing to quit): ').strip()
if lookfor:
try:
ind = namelist.index(lookfor)
print("{0} found.".format(lookfor))
except ValueError:
print("{0} not found.".format(lookfor))
else:
break
def main():
namelist = load_names('names.txt')
print_names(namelist)
namelist.sort()
print_names(namelist)
write_names(namelist, 'sorted_names.txt')
search_names(namelist)
if __name__=="__main__":
main()

Categories

Resources