2016-03-29 8 views
0

私はモバイルデバイスで実行したときに16桁のメモリ問題に遭遇した単純な素数チェッカーを持っています。私はprime_numberチェッカーを別のスレッドでGUIとして実行させることでこれを解決できると考えました。他の例を見てもわかりませんが、別の例のランダムな部分を追加したようです。とにかくここにコードがあります。kivyのGUIでメモリエラーを防ぐために新しいスレッドを計算を開始するにはどうすればよいですか?

from kivy.app import App 
from kivy.uix.label import Label 
from kivy.uix.widget import Widget 
from kivy.uix.textinput import TextInput 
from kivy.uix.button import Button 
from kivy.properties import ObjectProperty 
from kivy.clock import mainthread 
from kivy.lang import Builder 

from numpy import remainder, sqrt, floor 

from datetime import datetime 
import threading 


Builder.load_string(''' 
<MainScreen>: 
    number: number_input 
    check: check_button 
    answer: answer 
    time: time 

    canvas: 

     Color: 
      rgba: .2, .2, .5, .5 
     Rectangle: 
      pos: self.pos 
      size: self.size 


     # answer button 
     Color: 
      rgba: .5, .8, .8, .5 
     Rectangle: 
      pos: 0, root.height/3 
      size: root.width/2, root.height/10 

     # time button 
     Color: 
      rgba: .2, .5, .5, .5 
     Rectangle: 
      pos: 0, root.height/6 
      size: root.width, root.height/10 


    TextInput: 

     id: number_input 
     pos: root.width/4, 2 * root.height/3 
     size: root.width/2, root.height/10 
     multiline: False 
     input_filter: 'int' 
     hint_text: 'Enter number' 
     write_tab: False 


    Button: 

     id: check_button 
     pos: root.width/2, root.height/3 
     size: root.width/2, root.height/10 
     text: 'Check' 
     on_press: 
      root.start_second_thread() 

    Label: 

     id: answer 
     text: 'Answer' 
     pos: 0, root.height/3 
     size: root.width/2, root.height/10 

    Label: 

     id: time 
     pos: 0, root.height/6 
     size: root.width, root.height/10 
     text: 'Time taken' 
''') 

class MainScreen(Widget): 

    number = ObjectProperty(None) 
    check = ObjectProperty(None) 
    answer = ObjectProperty(None) 
    time = ObjectProperty(None) 

    def start_second_thread(self): 

     thread2 = threading.Thread(target=self.prime_checker) 
     thread2.start() 
     #thread2.join() 
     print(threading.activeCount()) 

    def prime_checker(self, *args): 

     ans = '' 
     now = datetime.now() 
     if self.number.text == '': 
      #self.answer.text = 'No number entered' 
      ans = 'No number entered' 
      end = datetime.now() - now 
      #self.time_checker(end) 

     elif len(self.number.text) > 17: 
      #self.answer.text = 'Too big for now' 
      ans = 'Too big for now' 
      end = datetime.now() - now 
      #self.time_checker(end) 

     else: 
      numb = int(self.number.text) 
      upper_limit = int(floor(sqrt(numb))) 
      tested = False 

      if numb < 2: 
       #self.answer.text = 'Not Prime' 
       ans = 'Not Prime' 
       end = datetime.now() - now 
       #self.time_checker(end) 

      elif numb == 2: 
       #self.answer.text = 'Prime' 
       ans = 'Prime' 
       end = datetime.now() - now 
       #self.time_checker(end) 

      elif numb % 2 == 0: 
       #self.answer.text = 'Not Prime, 2' 
       ans = 'Not Prime, 2' 
       end = datetime.now() - now 
       #self.time_checker(end) 

      else: 
       for i in range(3, upper_limit, 2): 
        #if numb % i == 0: 
        if remainder(numb, i) == 0: 
         #self.answer.text = 'Not Prime, {}'.format(i) 
         ans = 'Not Prime, {}'.format(i) 
         tested = True 
         end = datetime.now() - now 
         #self.time_checker(end) 
         break 

       if tested == False: 
        #self.answer.text = 'Prime' 
        ans = 'Prime' 
        end = datetime.now() - now 
        #self.time_checker(end) 

     self.update_main_thread(ans, end) 

    def time_checker(self, some_time): 

     some_time = 'This took {0} seconds and {1} milliseconds'.format(some_time.seconds, float(some_time.microseconds)/1000) 
     #self.time.text = some_time 

    @mainthread 
    def update_main_thread(self, ans, tim): 
     self.answer.text = ans 
     tim = 'This took {0} seconds and {1} milliseconds'.format(tim.seconds, float(tim.microseconds)/1000) 
     self.time.text = tim 


class PrimeNumberCheckerApp(App): 

    def build(self): 

     return MainScreen() 

if __name__ == '__main__': 
    PrimeNumberCheckerApp().run() 

私はより良いことをすることができるたくさんのものがあると確信しています。しかし、私にとって最も重要なことは、なぜline print(threading.activeCount())が2ではなく1を出力するのかということです。

+0

printステートメントに入る前にスレッドが単純に終了していないことは確かですか? – Natecat

+0

まあ、私はprint文を決して正しい場所に置かないと思います。あなたのコメントを読んだり、プリントステートメントのカップルラインを移動したりして、今、私が望んでいたことをやっている。ありがとう。 補足として、方法を見つけたら質問を閉じることにします。 – pizz

答えて

0

Natecatのおかげで、スレッドはprintステートメントの直前に終了したようです。他の誰かが同じような問題に遭遇した場合、私はちょうど1,2行下の印刷文を移動しました

def prime_checker(self, *args): 

     print(threading.activeCount()) 
     ... 

私は期待していました。迅速な答えをNatecatに感謝します。

関連する問題