2014-04-18 124 views
1

我不是很好用蟒蛇,但對於這個項目,我需要使用Python的GUI來測試我的節目。它編譯沒有任何錯誤,但它給人錯誤,當我去測試它的GUI。該計劃的目的是從具有所有翻譯/定義.txt文件創建一個英語法語詞典。我的代碼如下。如果任何人都可以提供幫助,那會很棒。麻煩與Python GUI

這是我收到的錯誤:

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1470, in __call__ 
    return self.func(*args) 
    File "Dictionary.py", line 33, in <lambda> 
    lambda e, s=self: s.translate(english, french)) 
    File "Dictionary.py", line 69, in translate 
    clearall(english, french) 
NameError: global name 'clearall' is not defined 

如需進一步信息,我應該檢查這些條件: 1)沒有命令行參數和2)不成功的文件開口。

Dictionary.cpp:

#include "HashTable.h" 
#include "DictionaryEntry.h" 
#include <iostream> 
#include <fstream> 
#include <string> 
#include <vector> 

int main(int argc, char** argv) 
{ 
    HashTable <DictionaryEntry> table; 
    DictionaryEntry dictEntry; 
    string temp; 
    string entry; 
    string translation; 
    vector <string> engWords; 
    string uentry; 
    int randNum; 

    ifstream inputStream; 

    //If command line is empty, error 
    if(argc <= 1) 
    { 
     cout << "Invalid entry." << endl; 
     return 0; 
    } 

    inputStream.open(argv[1]); 

    //If no file is opened, error 
    /*if(!inputStream) 
    { 
     cout << "Invalid file." << endl; 
     return 0; 
    }*/ 

    while(!inputStream.eof()) 
    { 
     getline(inputStream, temp); 

     unsigned location = temp.find_first_of('\t'); 

     entry = temp.substr(0, location); 

     int end = temp.length(); 

     translation = temp.substr(location + 1, end); 

     dictEntry.set(entry, translation); 

     table.insert(dictEntry); 

     engWords.push_back(entry); 
    } 

    while(1) 
    { 
     cout << "Insert english word: "; 
     cin >> uentry; 

     DictionaryEntry search; 
     search.set(uentry, ""); 

     if(uentry == "random") 
     { 
      randNum = rand() % engWords.size(); 

      temp = engWords.at(randNum); 

      search.set(temp, ""); 

      dictEntry = table.retrieve(search); 

      cout << dictEntry.getEntry() << endl; 

      cout << dictEntry.getTranslation() << endl; 
     } 

     else 
     { 
      dictEntry = table.retrieve(search); 

      if(dictEntry.getEntry() != "") 
      { 
       cout << dictEntry.getEntry() << endl; 
       cout << dictEntry.getTranslation() << endl; 
      } 

      else 
      { 
       cout << "\n"; 
       cout << "\n"; 
      } 
     } 
    } 
} 

List.h:

#ifndef LIST_H 
#define LIST_H 
using namespace std; 

template <typename Object> 
class List 
{ 
    private: 
     struct Node 
     { 
      Object data; 
      Node *prev; 
      Node *next; 

      Node(const Object & d = Object{ }, Node * p = nullptr, Node * n = nullptr) 
       : data{ d }, prev{ p }, next{ n } { } 

      Node(Object && d, Node * p = nullptr, Node * n = nullptr) 
       : data{ std::move(d) }, prev{ p }, next{ n } { } 
     }; 

    public: 
     class const_iterator 
     { 
      public: 
       const_iterator() : current{ nullptr } 
        { } 

       const Object & operator* () const 
        { return retrieve(); } 

       const_iterator & operator++ () 
       { 
        current = current->next; 
        return *this; 
       } 

       const_iterator operator++ (int) 
       { 
        const_iterator old = *this; 
        ++(*this); 
        return old; 
       } 

       bool operator== (const const_iterator & rhs) const 
        { return current == rhs.current; } 

       bool operator!= (const const_iterator & rhs) const 
        { return !(*this == rhs); } 

      protected: 
        Node *current; 

        Object & retrieve() const 
         {return current->data;} 

        const_iterator(Node *p) : current{ p } 
         { } 

        friend class List<Object>; 
     }; 

     class iterator : public const_iterator 
     { 
      public: 
       iterator() 
        { } 

       Object & operator* () 
        { return const_iterator::retrieve(); } 

       const Object & operator* () const 
        { return const_iterator::operator*(); } 

       iterator & operator++ () 
       { 
        this->current = this->current->next; 
        return *this; 
       } 

       iterator operator++ (int) 
       { 
        iterator old = *this; 
        ++(*this); 
        return old; 
       } 

       iterator operator--() 
       { 
        const_iterator::current = const_iterator::current->prev; 
        return *this; 
       } 

       iterator operator--(int) 
       { 
        iterator old = *this; 
        --(*this); 
        return old; 
       } 

      protected: 
       iterator(Node *p) : const_iterator{ p } 
        { } 

       friend class List<Object>; 
     }; 

    public: 
     List() 
      { init(); } 

     ~List() 
     { 
      clear(); 
      delete head; 
      delete tail; 
     } 

     List(const List & rhs) 
     { 
      init(); 
      for(auto & x : rhs) 
       push_back(x); 
     } 

     List & operator= (const List & rhs) 
     { 
      List copy = rhs; 
      std::swap(*this, copy); 
      return *this; 
     } 

     List (List && rhs) 
      : theSize{ rhs.theSize }, head{rhs.head }, tail{rhs.tail } 
     { 
      rhs.theSize = 0; 
      rhs.head = nullptr; 
      rhs.tail = nullptr; 
     } 

     List & operator= (List && rhs) 
     { 
      std::swap(theSize, rhs.theSize); 
      std::swap(head, rhs.head); 
      std::swap(tail, rhs.tail); 

      return *this; 
     } 

     iterator begin() 
      { return { head->next }; } 
     const_iterator begin() const 
      { return { head->next }; } 
     iterator end() 
      { return { tail }; } 
     const_iterator end() const 
      { return { tail }; } 
     int size() const 
      { return theSize; } 
     bool empty() const 
      { return size() == 0; } 

     void clear() 
     { 
      while(!empty()) 
       pop_front(); 
     } 
     Object & front() 
      { return *begin(); } 
     const Object & front() const 
      { return *begin(); } 
     Object & back() 
      { return *--end(); } 
     const Object & back() const 
      { return *--end(); } 
     void push_front(const Object & x) 
      { insert(begin(), x); } 
     void push_front(Object && x) 
      { insert(begin(), std::move(x)); } 
     void push_back(const Object & x) 
      { insert(end(), x); } 
     void push_back(Object && x) 
      { insert(end(), std::move(x)); } 
     void pop_front() 
      { erase(begin()); } 
     void pop_back() 
      { erase(--end()); } 

     //Insert x before itr 
     iterator insert(iterator itr, const Object & x) 
     { 
      Node *p = itr.current; 
      theSize++; 
      return { p->prev = p->prev->next = new Node{ x, p->prev, p } }; 
     } 

     //Insert x before itr 
     iterator insert(iterator itr, Object && x) 
     { 
      Node *p = itr.current; 
      theSize++; 
      return { p->prev = p->prev->next = new Node{ std::move(x), p->prev, p } }; 
     } 

     //Erase item at itr 
     iterator erase(iterator itr) 
     { 
      Node *p = itr.current; 
      iterator retVal{ p->next }; 
      p->prev->next = p->next; 
      p->next->prev = p->prev; 
      delete p; 
      theSize--; 

      return retVal; 
     } 

     iterator erase(iterator from, iterator to) 
     { 
      for(iterator itr = from; itr != to;) 
       itr.erase(itr); 
      return to; 
     } 

     iterator find(const Object & x) 
     { 
      iterator start= begin(); 
      while(start!=end()){ 
      if(x==*start) 
       return start; 
      start++; 
      } 
      return start; 
     } 

     /* 
     iterator find(string & x) 
     { 
      iterator start = begin(); 
      while(start != end()) { 
       if(strcasecmp(x.c_str(),(*start).getWord().c_str())==0) 
        return start; 
       else 
        start++; 
       } 
      return start; 
     } 
     */ 
     const_iterator find(const Object & x) const 
     { 
      const_iterator start=begin(); 
      while(start!=end()){ 
      if(x==*start) 
       return start; 
      start++; 
      } 
      return start; 
     } 
     /* 
     const_iterator find(const string & x){ 
      const_iterator start = const_iterator(head); 
      while(start != end()){ 
       if(strcasecmp(x.c_str(),(*start).getWord().c_str())==0) 
        return start; 
       else 
        start++; 
       } 
      return start; 
     } 
     */ 

    private: 
     int theSize; 
     Node *head; 
     Node *tail; 

     void init() 
     { 
      theSize = 0; 
      head = new Node; 
      tail = new Node; 
      head->next = tail; 
      tail->prev = head; 
     } 
}; 

#endif 

HashTable.h:

#ifndef HASHTABLE_H 
#define HASHTABLE_H 

#include <vector> 
#include <string> 
#include "List.h" 
#include "DictionaryEntry.h" 

using namespace std; 

//checks if a value is prime 
bool isPrime(int n){ 
    if(n==2 || n==3) 
    return true; 

    if(n==1 || n%2 == 0) 
    return false; 

    for(int i=3; i*i<n; i+=2) 
    if(n%i == 0) 
     return false; 

    return true; 
} 

//finds the next prime number 
int nextPrime (int n) { 
    if(n%2==0) 
    n++; 

    while(!isPrime(n)) 
    n+=2; 

    return n; 
} 

template <typename HashedObj> 
class HashTable 
{ 
    public: 
     //constructor (explicit so no implicit conversion) 
     explicit HashTable(int size = 3500) : tableSize(size), currentSize(size), theLists(size) { } 

     //empty the Hashtable 
     void makeEmpty() 
     { 
      currentSize=0; 
      //clear each linked list from hastable 
      for(int i=0; i<tableSize; i++) 
       theLists[i].clear(); 
     } 

     //search for x in Hashtable 
     bool contains(const HashedObj & x) const{ 
      //assign reference variable to rename the complicated object 
      const List<HashedObj> & whichList = theLists[ myhash(x) ]; 
      //return whether x already exists in the list 
      return whichList.find(x) != whichList.end(); 
     } 

     //insert x into Hashtable (true if successful, false if already exists) 
     bool insert(const HashedObj & x) { 

      //assign reference variable to rename the complicated object 
      List<HashedObj> & whichList = theLists[ myhash(x) ]; 

      //if x already exists in the list, return false 
      if(whichList.find(x) != whichList.end()) 
       return false; 

      //otherwise push to list 
      whichList.push_front(x); 

      //rehash if new size is greater than hashtable size 
      if(++currentSize >tableSize) { 
       rehash(); 
      } 
      return true; 
     } 

     //remove x from Hashtable (true if successful, false if not found) 
     bool remove(const HashedObj & x) { 
      //assign reference variable to rename the complicated object 
      List<HashedObj> & whichList = theLists[ myhash(x) ]; 

      //iterator is at end of list (i.e., not found) 
      if(whichList.find(x) == whichList.end()) 
       return false; 

      //erase x 
      whichList.erase(whichList.find (x)); 
      --currentSize; 
      return true; 
    } 


     HashedObj & retrieve(HashedObj & obj) 
     { 
      return *(theLists[myhash(obj)].find(obj)); 
     } 

    private: 
     //The vector of linked-lists hashtable 
     vector<List<HashedObj> > theLists; 
     int currentSize; 
     int tableSize; 

     //Because coming with new stuff is hard <--Haha 
     void rehash(){ 
      vector<List<HashedObj> > oldLists=theLists; 
      int oldtableSize = tableSize; 

      tableSize = nextPrime(2* oldtableSize); 

      //Create new double-sized, empty table 
      theLists.resize(tableSize); 
      for(int i=0; i<tableSize; i++) 
       theLists[i].clear(); 

      //copy table over 
      currentSize = 0; 
      for(int i=0; i<oldtableSize; i++){ 
       while(!oldLists[i].empty()){ 
        insert(oldLists[i].front()); 
        oldLists[i].pop_front(); 
     } 
     } 
    } 

     //call hash function and makes sure values fit in table 
     int myhash(const HashedObj & x) const 
     { 
     int hashVal = hash2(x); //call hash function 

      //make sure the hash values fit into HashTable 
      hashVal %= tableSize; 
      if(hashVal < 0) 
      { 
       hashVal += tableSize; 
      } 
      return hashVal; 
    } 

    /* 
     int myhash(const string & x) const 
     {  
      int hashVal = hash(x); 
      hashVal %= tableSize; 
      if(hashVal < 0) 
      { 
       hashVal += tableSize; 
      } 
      return hashVal; 
     } 
    */ 
}; 

int hash2(const string & key) 
{ 
    int hashVal = 0; 

    for(int i = 0; i < key.length(); i++) 
    { 
    hashVal = 37 * hashVal + key[i]; 
    } 
    return hashVal; 
} 

int hash2(const DictionaryEntry word) 
{ 
    return hash2(word.getEntry()); 
} 

int hash2(int key) 
{ 
    return key; 
} 


#endif 

DictionaryEntry.h:

#ifndef DICTIONARYENTRY_H 
#define DICTIONARYENTRY_H 

#include <string> 
#include <iostream> 
#include "HashTable.h" 

using namespace std; 


class DictionaryEntry 
{ 
    public: 

     DictionaryEntry() 
     { 
      entry = ""; 
      translation = ""; 
     } 

     DictionaryEntry(const DictionaryEntry & rhs) 
     { 
      entry = rhs.entry; 
      translation = rhs.translation; 
     } 

     void set(string ent, string trans) 
     { 
      entry = ent; 
      translation = trans; 
     } 

     const string & getTranslation() const 
     { 
      return translation; 
     } 

     const string & getEntry() const 
     { 
      return entry; 
     } 

     bool operator== (const DictionaryEntry & rhs) const 
     { 
      return getEntry() == rhs.getEntry(); 
     } 

     bool operator!= (const DictionaryEntry & rhs) const 
     { 
      return (getEntry() != rhs.getEntry()); 
     } 


    private: 
     string entry; 
     string translation; 

}; 


#endif 

和Dictionary.py:

#!/usr/bin/python 

from Tkinter import * 
import subprocess 

# general function for frame generation 
def frame(root, side): 
    w = Frame(root) 
    w.pack(side=side, expand=YES, fill=BOTH) 
    return w 

# general function for button generation 
def button(root, side, text, command=None): 
    w = Button(root, text=text, command=command) 
    w.pack(side=side, expand=YES, fill=BOTH) 
    return w 

# main class for GUI 
class Translator(Frame): 
    def __init__(self): 
     Frame.__init__(self) 
     self.pack(expand=YES, fill=BOTH) 
     self.master.title("English-French Translator") 
     self.master.iconname("English-French Translator") 

     Label(self, text='English').pack(side=TOP, expand=YES, fill=BOTH) 
     english = StringVar() 
     Entry(self, relief=SUNKEN, textvariable=english).pack(side=TOP, expand=YES, fill=BOTH) 

     buttonsF = frame(self, TOP) 
     btn = button(buttonsF, LEFT, 'Translate') 
     btn.bind('<ButtonRelease-1>', 
       lambda e, s=self: s.translate(english, french)) 

     clearF = frame(self, TOP) 
     btn = button(buttonsF, LEFT, 'Clear') 
     btn.bind('<ButtonRelease-1>', 
       lambda e, s=self: s.clearall(english, french)) 

     randF = frame(self, TOP) 
     btn = button(buttonsF, LEFT, 'Flash Me (TM)') 
     btn.bind('<ButtonRelease-1>', 
       lambda e, s=self: s.random(english, french)) 

     Label(self, text='French').pack(side=TOP, expand=YES, fill=BOTH) 
     french = StringVar() 
     Message(self, relief=SUNKEN, textvariable=french, width=200).pack(side=TOP, expand=YES, fill=BOTH) 

    # clear all text boxes 
    def clearall(self, english, french): 
     english.set('') 
     french.set('') 

    # translate english to french 
    def translate(self, english, french): 
     if (len(english.get()) > 0): 
      try: 
       # send english word to subprocess 
       process.stdin.write('%s\n'%english.get()) 
       # read line of output from subprocess (original text) 
       original=process.stdout.readline() 
       # read line of output from subprocess (translated text) 
       translation=process.stdout.readline() 
       # set english textbox 
       english.set(original.rstrip()) 
       # set french textbox 
       french.set(translation.rstrip()) 
      except: 
       clearall(english, french) 

    def random(self, english, french): 
     try: 
      process.stdin.write('random\n') 
      original=process.stdout.readline() 
      translation=process.stdout.readline() 
      english.set(original.rstrip()) 
      french.set(translation.rstrip()) 
     except: 
      clearall(english, french) 

if __name__ == '__main__': 
    args='French.txt' 

    process=subprocess.Popen('Dictionary %s'%args, shell=True, 
         stdin=subprocess.PIPE, 
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE) 

    Translator().mainloop() 
+1

您需要添加,你得到這個問題的錯誤。 – ebarr

+0

這是_far_代碼太多。在你調試,你應該已經建造了一個_minimal testcase_,張貼經過。 –

回答

1

錯誤消息告訴你到底出了什麼問題:「全球名‘clearall’沒有定義」。你必須問自己'爲什麼python認爲它沒有被定義?'在這種情況下,線索是它認爲clearall是一個全局函數。爲什麼?因爲這就是你如何使用它。

在看着你代碼,看來你有一個「clearall」的方法作爲對象的一部分,所以可能你需要做的是改變clearall(...)self.clearall(...)到處打電話clearall