Home > database >  My information finding program returns '0'
My information finding program returns '0'

Time:05-05

I am trying to make a program which will find the optimal word to eliminate the most letters from the keyboards alphabet at once when given a list of words. My program always returns "0". I would expect the value to be around 5. I suspect my error is in the "get_best_word" function, but it could be the "get_possible_letters" function as well. I would appreciate any help, my code is as follows.

import os
import random


wordlist = ['crane', 'soare', 'adieu', 'wario', 'crazy', 'aback', 'Abuse','Adult', 'Agent', 'Anger', 'Apple', 'Award', 'Basis', 'Beach', 'Birth', 'Block', 'Blood', 'Board', 'Brain', 'Bread', 'Break', 'Brown', 'Buyer', 'Cause', 'Chain', 'Chair', 'Chest', 'Chief', 'Child', 'China', 'Claim', 'Class', 'Clock', 'Coach', 'Coast', 'Court', 'Cover', 'Cream', 'Crime', 'Cross', 'Crowd', 'Crown', 'Cycle', 'Dance', 'Death', 'Depth', 'Doubt', 'Draft', 'Drama', 'Dream', 'Dress', 'Drink', 'Drive', 'Earth', 'Enemy', 'Entry', 'Error', 'Event', 'Faith', 'Fault', 'Field', 'Fight', 'Floor', 'Focus', 'Force', 'Frame', 'Frank', 'Front', 'Fruit', 'Glass', 'Grant', 'Grass', 'Green', 'Group', 'Guide', 'Heart', 'Henry', 'Horse', 'Hotel', 'House', 'Image', 'Index', 'Input', 'Issue', 'Japan', 'Jones', 'Judge', 'Knife', 'Laura', 'Layer', 'Level', 'Lewis', 'Light', 'Limit', 'Lunch', 'Major', 'March', 'Match', 'Metal', 'Model', 'Money', 'Month', 'Motor', 'Mouth', 'Music', 'Night', 'Noise', 'North', 'Novel', 'Nurse', 'Offer', 'Order', 'Other', 'Owner', 'Panel', 'Paper', 'Party', 'Peace', 'Peter', 'Phase', 'Phone', 'Piece', 'Pilot', 'Pitch', 'Place', 'Plane', 'Plant', 'Plate', 'Point', 'Pound', 'Power', 'Press', 'Price', 'Pride', 'prize', 'Proof', 'Queen', 'Radio', 'Range', 'Ratio', 'Reply', 'Right', 'River', 'Round', 'Route', 'Rugby', 'Scale', 'Scene', 'Scope', 'Score', 'Sense', 'Shape', 'Share', 'Sheep', 'Sheet', 'Shift', 'Shirt', 'Shock', 'Sight', 'Simon', 'Skill', 'Sleep', 'Smile', 'Smith', 'Smoke', 'Sound', 'South', 'Space', 'Speed', 'Spite', 'Sport', 'Squad', 'Staff', 'Stage', 'Start', 'State', 'Steam', 'Steel', 'Stock', 'Stone', 'Store', 'Study', 'Stuff', 'Style', 'Sugar', 'Table', 'Taste', 'Terry', 'Theme', 'Thing', 'Title', 'Total', 'Touch', 'Tower', 'Track', 'Trade', 'Train', 'Trend', 'Trial', 'Trust', 'Truth', 'Uncle', 'Unity', 'Value', 'Video', 'Visit', 'Voice', 'Waste', 'Watch', 'Water', 'While', 'White', 'Whole', 'Woman', 'World', 'Youth']

letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

def get_possible_letters(word):
  possible_letters = letters

  for i in word:
    if i in possible_letters:
      possible_letters.remove(i)
  return possible_letters

class Word:
  def __init__(self, text, coloured_text):
    self.text = text
    self.coloured_text = coloured_text

def get_best_word():
  max_score = len(letters)
  for i in wordlist:
    score = len(get_possible_letters(i))
    if score < max_score:
      max_score = score
  return score
    

print(get_best_word())

CodePudding user response:

You should be counting the letters by an int counter. Rather than taking the length of a list:

def get_possible_letters(word):
    possible_letters = letters.copy()
    counter = 0
    for i in word:
        if i in possible_letters:
            possible_letters.remove(i)
            counter  = 1
    return counter

Then you need to make a current_score, rather than a maximum score. And only update it when you find one better score > current_score.

def get_best_word():
    current_score = 0
    for i in wordlist:
        score = get_possible_letters(i)
        if score > current_score:
            current_score = score
    return current_score

This will try and get the lowest scoring word (4)

if score < max_score:
    max_score = score

CodePudding user response:

  possible_letters = letters[:]

Create a copy of letters using slicing. Otherwise you change the original list - which is not what you want since you need to check against it everytime. Here is the correct code and possible solution:

import os
import random


wordlist = ['crane', 'soare', 'adieu', 'wario', 'crazy', 'aback', 'Abuse','Adult', 'Agent', 'Anger', 'Apple', 'Award', 'Basis', 'Beach', 'Birth', 'Block', 'Blood', 'Board', 'Brain', 'Bread', 'Break', 'Brown', 'Buyer', 'Cause', 'Chain', 'Chair', 'Chest', 'Chief', 'Child', 'China', 'Claim', 'Class', 'Clock', 'Coach', 'Coast', 'Court', 'Cover', 'Cream', 'Crime', 'Cross', 'Crowd', 'Crown', 'Cycle', 'Dance', 'Death', 'Depth', 'Doubt', 'Draft', 'Drama', 'Dream', 'Dress', 'Drink', 'Drive', 'Earth', 'Enemy', 'Entry', 'Error', 'Event', 'Faith', 'Fault', 'Field', 'Fight', 'Floor', 'Focus', 'Force', 'Frame', 'Frank', 'Front', 'Fruit', 'Glass', 'Grant', 'Grass', 'Green', 'Group', 'Guide', 'Heart', 'Henry', 'Horse', 'Hotel', 'House', 'Image', 'Index', 'Input', 'Issue', 'Japan', 'Jones', 'Judge', 'Knife', 'Laura', 'Layer', 'Level', 'Lewis', 'Light', 'Limit', 'Lunch', 'Major', 'March', 'Match', 'Metal', 'Model', 'Money', 'Month', 'Motor', 'Mouth', 'Music', 'Night', 'Noise', 'North', 'Novel', 'Nurse', 'Offer', 'Order', 'Other', 'Owner', 'Panel', 'Paper', 'Party', 'Peace', 'Peter', 'Phase', 'Phone', 'Piece', 'Pilot', 'Pitch', 'Place', 'Plane', 'Plant', 'Plate', 'Point', 'Pound', 'Power', 'Press', 'Price', 'Pride', 'prize', 'Proof', 'Queen', 'Radio', 'Range', 'Ratio', 'Reply', 'Right', 'River', 'Round', 'Route', 'Rugby', 'Scale', 'Scene', 'Scope', 'Score', 'Sense', 'Shape', 'Share', 'Sheep', 'Sheet', 'Shift', 'Shirt', 'Shock', 'Sight', 'Simon', 'Skill', 'Sleep', 'Smile', 'Smith', 'Smoke', 'Sound', 'South', 'Space', 'Speed', 'Spite', 'Sport', 'Squad', 'Staff', 'Stage', 'Start', 'State', 'Steam', 'Steel', 'Stock', 'Stone', 'Store', 'Study', 'Stuff', 'Style', 'Sugar', 'Table', 'Taste', 'Terry', 'Theme', 'Thing', 'Title', 'Total', 'Touch', 'Tower', 'Track', 'Trade', 'Train', 'Trend', 'Trial', 'Trust', 'Truth', 'Uncle', 'Unity', 'Value', 'Video', 'Visit', 'Voice', 'Waste', 'Watch', 'Water', 'While', 'White', 'Whole', 'Woman', 'World', 'Youth']

letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

def get_possible_letters(word):
  possible_letters = letters[:]
  word = word.lower()
  for c in word:
    if c in possible_letters:
      possible_letters.remove(c)
  return possible_letters

class Word:
  def __init__(self, text, coloured_text):
    self.text = text
    self.coloured_text = coloured_text

    
def get_best_word():
  min_score = len(letters)
  for w in wordlist:
    score = len(get_possible_letters(w))
    if score < min_score:
      min_score = score
  return len(letters)-min_score
print(get_best_word())

Corrections:

  1. You have to copy the list properly otherwise it still points to the letters and it modifies it.

  2. You need to use lowercase letters in words since you letters list contains only lower case letters.

  3. Ideally you are looking for words that has as many different letters as possible but your code for scoring was wrong. You should subtract from total number of letters to get the desired correct number of distinct letter in your words.

Another solution (short)

def get_best_word1():
  max_distinct_letters = 0
  for w in wordlist:
    w = w.lower()
    distinct_letters= len(set(list(w)))
    if distinct_letters > max_distinct_chars :
      max_distinct_chars = distinct_letters
  return max_distinct_chars 

Few other points: try to use proper variable names. In the last code, you can see that the variables clearly conveys the idea to some extent. This is actually quite helpful for reading the code and understanding it.

  • Related