#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    10
    Rep Power
    0

    Beginning question: Tuple/ anagrams


    Hey all,

    I'm currently learning Python with the book think Python.
    I'm at chapter 12 (tuples) and I'm stuck.

    Could someone explain me what I'm doing rong?
    I'm doing it in steps so not everything from the exercise is yet in the script.

    The question is:
    At line 10 of find_anagrams we have the app.
    When i put after this funtion k = True and as return function print k it says True.
    But when I use the .append function it wont add it in the list.
    Could someone explain why this isn't working and what I should change?

    I know this script doesn't do 100% of the exercise but I like to work in steps. This way I can see earlier when i make a mistake and fix it. after all, I'm a beginner and make quiet a few mistakes.

    Exercise:
    Write a program that reads a word list from a file (see Section 9.1) and prints all the sets of
    words that are anagrams.
    Here is an example of what the output might look like:
    ['deltas', 'desalt', 'lasted', 'salted', 'slated', 'staled']
    ['retainers', 'ternaries']
    ['generating', 'greatening']
    ['resmelts', 'smelters', 'termless']

    Hint: you might want to build a dictionary that maps from a set of letters to a list of words that can be spelled with those letters. The question is, how can you represent the set of letters in a way that can be used as a key?


    Scripts:
    Code:
    # Gives True if it's an anagram
    def comperator(word, word2):
            if word == word2:
                    return False
            c = 0
            t = tuple(word) # Makes from a str a tuple with loose letters
            u = tuple(word2)# ^
            for letter in t:
                    if t[c] not in u:
                            return False
                    c += 1
            return True
    
    # Finds anagrams in wordlist
    def find_anagrams():
            e = [] #temp
            file = open('Downloads/words2.txt') 
            for line in file:
                    word = line.strip()
                    for line2 in file:
                            word2 = line2.strip()
                            s = comperator(word, word2) # Checks if it's a anagram
                            if s is True:
                                    # TODO Make lists TODO
                                    e.append(word) #temp
            return e
    I use Idle 3.3.0
    Mac OS X Snow Leopard

    Thank you very much

    Greetings,
    Rhaiko
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,997
    Rep Power
    481
    Does this correctly identify "line 10 of find_anagrams"?
    Code:
     0def find_anagrams():                                                          
     1        e = [] #temp                                                          
     2        file = open('Downloads/words2.txt')                                   
     3        for line in file:                                                     
     4                word = line.strip()                                           
     5                for line2 in file:                                            
     6                        word2 = line2.strip()                                 
     7                        s = comperator(word, word2) # Checks if it's a anagram
     8                        if s is True:                                         
     9                                # TODO Make lists TODO                        
    10                                e.append(word) #temp                          
    11        return e


    "When i put after this function k = True and as return function print k it says True."

    Please show the actual code you used, also the output you expected.


    spoiler: decode using xor with repeated 'spoiler:' and print the numbers with format '%c'. It worked for me.
    Code:
     80 122   6  4  28  10   0 78  83  19   0  5  0  0  17 78  26  31  1 26
    102 111  22 95  21  80   9  0   2   1  45 91 29 17   8 27  13   8  1 18
      4  31  29 13  31  76  72 48  83  80  79 73  8 69  79 26  16  31  3  5
      9   6   6 83  28  30  28 71   8   0  20 91  6 28  27 13   5   6  6 18
     31  25  28 29  69 111  82 26  83  80   9  6 30 69   5 85   1  20 79  0
      2  69   5 85   1  20  28 83 102  69  82 26 83 80  79 73  76   0 28 86
     26   3  27 12   8  58   5 85   1  20  79 84 76  9  27 73   7  88 24  6
     30   1  91 48  83  80  79 73  76  69  82 26  0  4  14  7   8   4  0 94
     44  17   1  8  11  23  19 87  83  77  79 78 75 75  24 85  26  30 71 26
      3  23   6 95  23  88  10  7   0  12   1 78 22 20  48 30   3  23 22 19
     90 122  79 73  76  69  82 26  83  80  11 50 31 17  19 84  23  17 29 13
     51   4  28 91  20   2  14  4  49  75  19 74  3 21   1 13  68  18 29 72
     23  89 101 73  76  69  82 72  22   4  26 27  2 69  22 48 121   0 29  0
      2  17  90 92  26  30  11 54  13  11  19 93  1 17   2 26  68  66 85 29
     23  17  28 13 102   4  22 94   0 122  28  8 13  1 120 94  22  28 27  8
     31 111  22 95   0  17   3 29 102   2  23 84 22  2  14 29   5  11 21 48
     20   2  10  8  24   0  28 83  29  23 101  5 13 22   6 95  23 122 29 12
     31   8  23 86   7   3 101 27   9  17  19 83 29 21  29 26 102  22 19 86
      7  21  11 99  31   9  19 78  22  20 101 26  1  0  30 78  22   2 28 99
     31  17  19 86  22  20 101 29   9  23  31 86 22  3  28 99  24   0  0 84
     18   2   6 12  31 111  85 29  84  94  28 25  0 12   6 18  90  89 70 99
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    10
    Rep Power
    0
    Well the scripts is what I posted before

    script:
    Code:
    # Gives True if it's an anagram
    def comperator(word, word2):
            if word == word2:
                    return False
            c = 0
            t = tuple(word) # Makes from a str a tuple with loose letters
            u = tuple(word2)# ^
            for letter in t:
                    if t[c] not in u:
                            return False
                    c += 1
            return True
    
    # Finds anagrams in wordlist
    def find_anagrams():
            e = [] #temp
            file = open('Downloads/words2.txt') 
            for line in file:
                    word = line.strip()
                    for line2 in file:
                            word2 = line2.strip()
                            s = comperator(word, word2) # Checks if it's a anagram
                            if s is True:
                                    # TODO Make lists TODO
                                    e.append(word) #temp
            return e
    And the word2.txt (what is what I uploaded in the program)
    Code:
    help
    hallo
    deltas
    desalt
    lasted
    And the result I expedted is:
    ['deltas', 'desalt', 'lasted']
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,997
    Rep Power
    481
    Try the following program with your input.

    Code:
    def find_anagrams():
        file = open('Downloads/words2.txt') 
        for line in file:
            word = line.strip()
            print('outer loop word:',word)
            for line2 in file:
                word2 = line2.strip()
                print('inner loop word2:',word2)
    What's the point? `word' was "help". There was no chance to find anagrams of "deltas".


    Separate the tasks. Your main program should use these logical blocks

    acquire data
    form words
    find anagrams
    report


    With a separated program changing the source from a file to a socket or text test data is trivial. If the data is an html page from which you need only a small portion then you change the `split' function. You don't change the `find_anagrams' because the data source changed.
    Code:
    import sys
    import pprint
    
    def main(filename='Downloads/words2.txt'):
        with open(filename) as source:
            data = load(source)
        words = split(data)
        result = find_anagrams(words)
        report(result)
    
    
    def report(obj, sink = sys.stdout):
        pprint.pprint(obj, stream = sink)
    
    
    def split(data):
        return data.split()
    
    
    def load(source):
        return source.read()
    
    
    # Finds anagrams in wordlist
    def find_anagrams(words):
        for word in words:
            e = [] #temp
            for word2 in words:
    ################################################################
    #
    #  Fix your anagram algorithm starting here.
    #
    
                s = comperator(word, word2) # Checks if it's a anagram
                if s is True:
                    # TODO Make lists TODO
                    e.append(word) #temp
        return e
    
    
    # Gives True if it's an anagram
    def comperator(word, word2):
        if word == word2:
            return False
        c = 0
        t = tuple(word) # Makes from a str a tuple with loose letters
        u = tuple(word2)# ^
        for letter in t:
            if t[c] not in u:
                return False
            c += 1
        return True
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    10
    Rep Power
    0
    Hey,

    Thanks for your answer and sorry for my late response.
    Could you tell me a little bit more about the "sys" and "pprint" module? Because I see you use this but I cant find this in my book and I cant find a good discription on internet.

    Thank you

    Greetings,
    Elrick
  10. #6
  11. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,997
    Rep Power
    481
    Put this link on your internet browser bookmarks bar:

    http://docs.python.org/3/library/

    I don't have deep feelings about your response time, for which you apologized. It's your question, after all.
    [code]Code tags[/code] are essential for python code and Makefiles!
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    10
    Rep Power
    0
    Thank you very much for the link!
    I'm going to learn this holidays and when I have a question I'll return

    and thank you also very much for all your help. Hopefully in a few weeks/ months I can also help other people around here.

    Greetings,
    Rhaiko
  14. #8
  15. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Location
    Iran
    Posts
    149
    Rep Power
    140
    Originally Posted by Rhaiko
    Exercise:
    Write a program that reads a word list from a file (see Section 9.1) and prints all the sets of
    words that are anagrams.
    Here is an example of what the output might look like:
    ['deltas', 'desalt', 'lasted', 'salted', 'slated', 'staled']
    ['retainers', 'ternaries']
    ['generating', 'greatening']
    ['resmelts', 'smelters', 'termless']
    According to the Cambridge Advanced Learner's dictionary here is how the term anagram has been defined
    a word or phrase made by using the letters of another word or phrase in a different order
    If I translate this to python I would say that two sets of letters which are equal (assuming their corresponding words based on which the sets are built are different)

    As a result, I think there is even a simpler solution. Using Python 3 I tested the following.

    Here is a test file named: testdata2.txt including the words
    Code:
    hello aaa oelh bbbb insert
    sirretn nnnttisre
    how owho hoow whwho
    ddd eee fff ggg
    happy apphy phpya elho
    Here is the python script that I tested
    Code:
    def main():
        wordsList = []
        
        # start by reading the file and put all words inside a list
        with open("testdata2.txt", "r") as inputFile:
            for line in inputFile:
                wordsList[0:0] = line.strip().split()
        
        indx = 0
        while (indx < len(wordsList)):
            currentWord = wordsList[indx]
            # anagrams of the currentWord are the list of
            # words having exactly the same set of letters
            # for those which are different of the current word.
            anagramsList = [
                                word for word in wordsList 
                                    if set(word) == set(currentWord) and
                                       word.lower() != currentWord.lower()
                           ]
            print("anagramsList("+currentWord+") = ", anagramsList)
            indx += 1
        
        
    main()
    Which gives the desired output

    Code:
    $python -tt myscript.py
    anagramsList(happy) =  ['apphy', 'phpya']
    anagramsList(apphy) =  ['happy', 'phpya']
    anagramsList(phpya) =  ['happy', 'apphy']
    anagramsList(elho) =  ['hello', 'oelh']
    anagramsList(ddd) =  []
    anagramsList(eee) =  []
    anagramsList(fff) =  []
    anagramsList(ggg) =  []
    anagramsList(how) =  ['owho', 'hoow', 'whwho']
    anagramsList(owho) =  ['how', 'hoow', 'whwho']
    anagramsList(hoow) =  ['how', 'owho', 'whwho']
    anagramsList(whwho) =  ['how', 'owho', 'hoow']
    anagramsList(sirretn) =  ['nnnttisre', 'insert']
    anagramsList(nnnttisre) =  ['sirretn', 'insert']
    anagramsList(hello) =  ['elho', 'oelh']
    anagramsList(aaa) =  []
    anagramsList(oelh) =  ['elho', 'hello']
    anagramsList(bbbb) =  []
    anagramsList(insert) =  ['sirretn', 'nnnttisre']
    $
    Regards,
    Dariyoosh
  16. #9
  17. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,997
    Rep Power
    481
    Try your program for input of two words:

    happy
    haapy
    [code]Code tags[/code] are essential for python code and Makefiles!
  18. #10
  19. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Location
    Iran
    Posts
    149
    Rep Power
    140
    Originally Posted by b49P23TIvg
    Try your program for input of two words:

    happy
    haapy
    I'm not sure to have understood what you meant. With a test data file including only the two given words in your comment here is the output
    Code:
    $ python -tt myscript.py
    anagramsList(haapy) =  ['happy']
    anagramsList(happy) =  ['haapy']
    $
    Which seems to me normal, no?
    Regards,
    Dariyoosh
  20. #11
  21. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,997
    Rep Power
    481
    haapy and happy are not anagrams. The letters of haapy cannot be arranged to spell happy. Imagine each letter on a child's alphabet block, or as Scrabble tiles.

    Find an anagram solver on line. I use

    http://www.wordsmyth.net/

    Have it look for anagrams of feet .
    Does it show eft ? No.
    Anagrams of ferret shows fret? No.

    In particular the definition of anagram didn't say
    "...from the SET of another..."

    The purpose of the original exercise might have been to motivate the python frozenset type, in which case my splitting hairs doesn't matter.
    Last edited by b49P23TIvg; March 30th, 2013 at 12:01 PM.
    [code]Code tags[/code] are essential for python code and Makefiles!
  22. #12
  23. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Location
    Iran
    Posts
    149
    Rep Power
    140
    Originally Posted by b49P23TIvg
    haapy and happy are not anagrams. The letters of haapy cannot be arranged to spell happy. Imagine each letter on a child's alphabet block, or as Scrabble tiles.
    Oh, what a terrible mistake I made !!!

    That actually could happen when English is not the mother tongue.

    I understood that anagram means words having exactly the same set of letters regardless of their order and number of occurrences.

    But now I checked the definition in Wikipedia
    An anagram is a type of word play, the result of rearranging the letters of a word or phrase to produce a new word or phrase, using all the original letters exactly once
    Conclusion: My program is rubbish

    Many thanks for correcting my mistake.
    Regards,
    Dariyoosh
  24. #13
  25. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,997
    Rep Power
    481
    The purpose of the original exercise might have been to motivate the python frozenset type, in which case my splitting hairs doesn't matter.
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo