Error Handling If - python

I'm writing the following code and I'm trying not to add ' ' (a single space character) to my dictionary. I thought the following would work for my function. Do I need to write a more in-depth try and except statement? I get a KeyError when I run the code as is.
score = {"a": 1, "c":3, "b":3, "e": 1, "d": 2, "g": 2, "f": 4, "i" : 1, "h" : 4, "k": 5, "j" : 8, "m": 3, "l":1, "o": 1, "n":1,
"q":10, "p": 3, "s": 1, "r": 1, "u":1, "t": 1, "w": 4, "v": 4,"y": 4, "x": 8, "z": 10,}
def scrabble_score(word):
total = 0
for i in word:
total += score[i.lower()]
if i == ' ':
continue
return total
print scrabble_score('ten')
print scrabble_score('i like chicken')

In my opinion it would be better to ignore any char that is not in the table, not just spaces.
For this you can use
for c in word:
total += score.get(c, 0)
the second parameter of dict.get is the value to use if the value is not present in the dictionary.

Just change the if-statement with the previous line:
total += score[i.lower()]
if i == ' ':
continue
Id est, use:
if i == ' ':
continue
total += score[i.lower()]
edit: removed wrong explanation, see comments.

Related

What is the best algorithm to sort a number?

So I have this document called new.txt which contains many digits of pi (see https://www.piday.org/million/) and I want to split the number into a list made out of all these digits in order. My code works but it's extremely slow, (I have tried with a less digits of pi).
def sort(stuff):
for iter_num in range(len(stuff)-1,0,-1):
for idx in range(iter_num):
if stuff[idx]>stuff[idx+1]:
temp = stuff[idx]
stuff[idx] = stuff[idx+1]
stuff[idx+1] = temp
return stuff
a = []
with open("/Users/serax/desktop/new.txt", "r") as r:
for line in r.readlines():
for char in line:
text = a.append(char)
print(sort(a))
thanks to the comments i have edited my code, here's the result.
thisdict = {
".": 0,
"0": 0,
"1": 0,
"2": 0,
"3": 0,
"4": 0,
"5": 0,
"6": 0,
"7": 0,
"8": 0,
"9": 0,
}
with open("/Users/serax/documents/new.txt", "r") as r:
for line in r.readlines():
# print(sorted(line)) # built in function that can sort str/list/tuple (works)
for char in line:
for key in thisdict:
if char == key:
thisdict[key] += 1
ordered = ""
for i in thisdict:
ordered = ordered + i*thisdict[i]
print(ordered)

What can I do to speed up this code for a scrabble cheat?

I'm making a python script that accepts 7 letters and returns the highest scoring word along with all other possible words. At the moment it has a few "loops in loops" and others things that will slow down the process.
import json
#open file and read the words, output as a list
def load_words():
try:
filename = "dictionary_2.json"
with open(filename,"r") as english_dictionary:
valid_words = json.load(english_dictionary)
return valid_words
except Exception as e:
return str(e)
#make dictionary shorter as there will be maximum 7 letters
def quick():
s = []
for word in load_words():
if len(word)<7:
s.append(word)
return s
# takes letters from user and creates all combinations of the letters
def scrabble_input(a):
l=[]
for i in range(len(a)):
if a[i] not in l:
l.append(a[i])
for s in scrabble_input(a[:i] + a[i + 1:]):
if (a[i] + s) not in l:
l.append(a[i] + s)
return l
#finds all words that can be made with the input by matching combo's to the dictionary and returns them
def word_check(A):
words_in_dictionary = quick()
for word in scrabble_input(A):
if word in words_in_dictionary:
yield word
#gives each word a score
def values(input):
# scrabble values
score = {"a": 1, "c": 3, "b": 3, "e": 1, "d": 2, "g": 2,
"f": 4, "i": 1, "h": 4, "k": 5, "j": 8, "m": 3,
"l": 1, "o": 1, "n": 1, "q": 10, "p": 3, "s": 1,
"r": 1, "u": 1, "t": 1, "w": 4, "v": 4, "y": 4,
"x": 8, "z": 10}
word_total = 0
for word in word_check(input):
for i in word:
word_total = word_total + score[i.lower()]
yield (word_total, str(word))
word_total = 0
#prints the tuples that have (scrabble score, word used)
def print_words(a):
for i in values(a):
print i
#final line to run, prints answer
def answer(a):
print ('Your highest score is', max(values(a))[0], ', and below are all possible words:')
print_words(a)
answer(input("Enter your 7 letters"))
I have removed some of the for loops and have tried to make the json dictionary I found shorter by limiting it to 7 letter words max. I suppose I could do that initially so that it doesn't need to do that each time i run the script. Any other tips on how to speed it up?

Python optimize with multithreads?

I'm sorry if I post this on the wrong forum, but is there any way to improve my code to run faster with multi-threads, processes or other improvements?
The purpose of this script is to find all possible words for a scrabble game based on the word you type in and calculate it's scrabble score.
When I enter a word that has more than 7 characters, it takes forever to make the computations.
scores = {"a": 1, "c": 3, "b": 3, "e": 1, "d": 2, "g": 2,
"f": 4, "i": 1, "h": 4, "k": 5, "j": 8, "m": 3,
"l": 1, "o": 1, "n": 1, "q": 10, "p": 3, "s": 1,
"r": 1, "u": 1, "t": 1, "w": 4, "v": 4, "y": 4,
"x": 8, "z": 10}
WORDS = []
combs = dict()
def prepareDict(file):
try:
f = open(file, 'r')
for line in f:
WORDS.append(line.rstrip().lower())
except OpenErrors:
print("Could not open file")
finally:
f.close()
def combinations(word):
for i in range(len(word)+1):
combList = itertools.permutations(word, i)
for item in combList:
item = ''.join(item)
if item in WORDS:
value = 0
for c in item:
value += int(scores.get(c))
combs[item] = value
return (combs)
if __name__ == "__main__":
prepareDict('sowpods.txt')
if len(sys.argv) > 2 or len(sys.argv) < 2:
print("usage: %s <word>" % sys.argv[0])
sys.exit(1)
else:
word = sys.argv[1].lower()
combs = combinations(word)
sorted_combs = sorted(combs.items(), key=operator.itemgetter(1), reverse=True)
for word in sorted_combs:
print(word)
Change WORDS = [] into a set():
WORDS = set()
then change the method to add words to it:
from:
WORDS.append(line.rstrip().lower())
to:
WORDS.add(line.rstrip().lower())
No reason to use a list for that. This should improve performance.

Mapping of user accounts to dates and sorted list of dates return a mapping of the indexes the dates by user are in the sorted dates list efficently

I am duplicating Facebook's chat read receipt system. I wrote some basic code I think works. However my boss thinks it would be slow. I have no algorithms training. What is the most efficient way to return a mapping of indexes to numbers where the numbers are between two numbers in a sorted list and the index is the index of the first number in the between pair?
# Given say {"a": 3, "b": 10, "c": 7, "d": 19} and [1,5,15] return {0: ["a"], 1: ["b", "c"], 2: ["d"]}
def find_read_to(read_dates, message_dates):
read_indexes_to_user_ids = {}
for user_id in read_dates:
for i, date in enumerate(message_dates):
last_index = i + 1 == len(message_dates)
next_index = -1 if last_index else i + 1
if last_index or (read_dates[user_id] >= date and read_dates[user_id] < message_dates[next_index]):
if i in read_indexes_to_user_ids:
read_indexes_to_user_ids[i].append(user_id)
else:
read_indexes_to_user_ids[i] = [user_id]
break
return read_indexes_to_user_ids
find_read_to({"a": 3, "b": 10, "c": 7, "d": 19}, [1,5,15])
Version using bisect module
import bisect
def find_read_to(read_dates, message_dates):
read_indexes_to_user_ids = {}
user_ids, read_dates = zip(*read_dates.items())
def find_between(read_date):
answer = bisect.bisect_left(message_dates, read_date)
answer -= 1
if answer == -1:
return None
return answer
indexes_for_read_up_to = map(find_between, read_dates)
for i, index_for_read_up_to in enumerate(indexes_for_read_up_to):
user_id = user_ids[i]
if index_for_read_up_to is None:
continue
if index_for_read_up_to in read_indexes_to_user_ids:
read_indexes_to_user_ids[index_for_read_up_to].append(user_id)
else:
read_indexes_to_user_ids[index_for_read_up_to] = [user_id]
return read_indexes_to_user_ids
find_read_to({"a": 3, "b": 10, "c": 7, "d": 19}, [1,5,15])

Syntax and lists within lists

I am creating a vote system to pick a team, butI have hit a wall. The code works fine up until the point of decision2. Any ideas?
Please remember this code is a work-in-progress.
teamNames = []
teams = {}
easy = [0, 1, 2, 3, 4, 5]
NoVotes1 = {'first' : 0, 'second' : 0, 'third' : 0, 'fourth' : 0, 'fifth' : 0}
NoVotes2 = {'first' : 0, 'second' : 0, 'third' : 0, 'fourth' : 0, 'fifth' : 0}
NoVotes3 = {'first' : 0, 'second' : 0, 'third' : 0, 'fourth' : 0, 'fifth' : 0}
NoVotes4 = {'first' : 0, 'second' : 0, 'third' : 0, 'fourth' : 0, 'fifth' : 0}
NoVotes5 = {'first' : 0, 'second' : 0, 'third' : 0, 'fourth' : 0, 'fifth' : 0}
while True:
print("Enter team name " + str(len(teamNames) + 1) + (" or press enter to stop."))
name = input()
if name == "":
break
teamNames = teamNames + [name]
print("The team names are ")
for name in teamNames:
print(" " + name)
for name in teamNames:
teams[name] = 0
teamNames.sort()
print("In alphabetical order the team names are ")
print()
print(str(teamNames))
y = 0
decision1 = input("Would you like to enter a vote? (1 = yes, 2 = no)")
while decision1 == "1":
print("ok great, where did " + teamNames[y] + " come")
decision2 = input()
if decision2 == "1":
teams[easy[y]] = teams[easy[y]] + 1
y = y + 1
if decision1 == "2":
break
elif n == "6":
break
I think I see what you've misunderstood. Standard dictionaries, unlike lists, have no concept of order or the nth (e.g. first) item. They are just associations between keys and values. When you say teams[key] = value you are setting the value at key, when you say value = teams[key] you are getting the value at key. It's possible that key is a number but it doesn't have to be, and if key is 1 then that doesn't mean the second value in the dictionary, or the first, or any other position. Perhaps this example interactive session will help you understand:
>>> dictionary = {"a": "b", "c": "d"}
>>> dictionary = {"a": "b", "c": "d", 5: "e"}
>>> dictionary[1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 1
>>> dictionary["c"]
'd'
>>> dictionary[5]
'e'
What you want is teams[teamNames[y]] = teams[teamNames[y]] + 1, which by the way can be shortened to teams[teamNames[y]] += 1.
Does all that make sense? If not I suggest doing some simple experiments with dictionaries until you understand them better. Play around with the in the shell. Write some small programs using dictionaries to see what they do.

Categories

Resources