2016-08-04 10 views
1

私は初心者ですからこのプロジェクト、小さなPythonとTkinterプロジェクトに取り組んでいます。この小さな問題でなければほとんど終了しました私はいくつかのテストをした後にそれを検出しました。 入力に入力したシリアル番号が「悪魔番号」であるかどうかは、その番号の番号が「666」であるかどうかによって異なります。肯定的なケースでは、その中に666という数字があり、それは他の6とは離れているはずです。つまり、この "666"のようなものであってはなりません。数字「666」がシリアルナンバーの中で何度か繰り返されている場合(「666666」と一緒に詰め込まれていない場合)、それも悪魔の番号と見なすことができます。Python:長いシリアル番号の中の特定の番号を検出する方法

私が持っている問題は、その中に「666」しかなく、同時にその番号(666)で終わる数字をテストすると、それらの数字は悪魔の数字とはみなされないということです。私はこの問題を解決できないようです。

このプロジェクトを実現するために、PythonとTkinterを使用しました。コードは次のとおりです。

"""*************************************************************************""" 
""" Author: CHIHAB  Version: 2.0  Email: [email protected] """ 
""" Purpose: Practice  Level: Beginner  2016/2017      """ 
"""*************************************************************************""" 
############################ I M P O R T S##################################### 
from tkinter import* 
from types import * 
############################ T K I N T E R #################################### 
main = Tk() 

e = Entry(main, bg="darkblue", fg="white") 
e.pack(fill=X) 

l = Label(main, bg="blue", fg="yellow") 
l.pack(fill=X) 
############################ F U N C T I O N S ################################ 
def devil(x): #TEST ENTERED VALUE FOR DEVIL NUMBER 
    c = 0 
    i = 0 
    l = list(x) 
    while i < len(l):     #This block of code means that as long as the index i 
     if l[i] == "6":     # is below the length of the list to which we have 
      c = c+1      #  converted the entry, the program is allowed to keep 
      print("this is c :", c)  #   reading through the list's characters. 
     else: 
      c = 0 
     if i <= (len(l)-2) and c == 3 and l[i+1] != "6": 
      return True 
     i = i+1 
    return False 
def printo(): #GET VALUE ENTRY AND SHOW IT IN LABEL 
    x = e.get() 
    if x != "": 
     if x.isnumeric() == True: #SHOW ENTERED VALUE IF INTEGER 
      y = devil(x) 
      if y == True: 
       print("The number you entered is a devil number.")     
       l.config(text="The number you entered is a devil number.", bg="blue") 
      else: 
       print("The number you entered is NOT a devil number.")     
       l.config(text="The number you entered is NOT a devil number.", bg="blue") 
      #print(x) 
      e.delete(0, END) 
     else: #SHOW ERROR IF NOT INTEGER 
      l.config(text="please enter an integer in the entry.", bg="red") 
      print("please enter an integer in the entry.") 
      e.delete(0, END) 
    else: #SHOW ERROR IF EMPTY 
     l.config(text="please enter something in the entry.", bg="red") 
     print("please enter something in the entry.") 

############################ T K I N T E R #################################### 
b = Button(main, text="Go", bg="lightblue", command=printo) 
b.pack(fill=X) 

main.mainloop() 

ここでは、guyz。私のコードがきちんと整っていて、私が疑問に思っていることを手伝ってくれることを願っています。 ありがとうございます。

+0

マッチがNoneでない場合、それは上記のあなたの質問ごとに悪魔の番号です( '* 666 *' R、input_number)re.searchを使用してください。 – forvaidya

+0

あなたは* 666のいずれかが一致しなければならないことを意味しますか、または3つのシーケンスが存在する場合には繰り返し可能ですか?すなわち '123666'は悪魔の番号ですか? '123666666321'(666の2つのグループ)はどうでしょうか?そして '1236666'(4つの' 6's)? –

+0

@WayneWerner、6とは別の番号に固執していても、シリアル番号に少なくとも1つの「666」が含まれているはずですが、666のようなものは存在しません。 6666は働かないでしょう。しかし、12366678666は悪魔の番号とみなすべきです。ありがとうございました!! – Chihab

答えて

3

あなたはどこにでも数で見つかった666は、試合でなければならないことを意味している場合、それは非常に簡単です:

if '666' in '1234666321': 
    print("It's a devil's number") 

しかし、あなたは666は「孤独」666、すなわちちょうど3 6でなければならないことを言います横並びに、それ以上はなく、それ以上はありません。 2人も4人もいません。 5つの6が外に出ています。その場合、tobias_k's regexを使用します。

あなたが正規表現のための情熱的な憎しみを持っていた場合、あなたはそれがstring.partitionを使用して行うことができますけれども:私はのように驚いて

>>> x = ''' 
... import re 
... numbas = ['666', '6', '123666', '12366', '66123', '666123', '666666', '6666', '6'*9, '66661236666'] 
... 
... def devil(x): 
...  return re.search(r"(?:^|[^6])(666)(?:[^6]|$)", x) is not None 
... ''' 
>>> import timeit 
>>> timeit.timeit('[devil(num) for num in numbas]', setup=x) 
13.822128501953557 

>>> x = ''' 
... numbas = ['666', '6', '123666', '12366', '66123', '666123', '666666', '6666', '6'*9, '6666123 
666'] 
... def has_devils_number(num): 
...  start, mid, end = num.partition('666') 
...  if not mid: 
...   return False 
...  else: 
...   if end == '666': 
...    return False 
...   elif start.endswith('6') or end.startswith('6'): 
...    return has_devils_number(start) or has_devils_number(end) 
...   return True 
... ''' 
>>> timeit.timeit('[has_devils_number(num) for num in numbas]', setup=x) 
9.843224229989573 

def has_devils_number(num): 
    start, mid, end = num.partition('666') 
    if not mid: 
     return False 
    else: 
     if end == '666': 
      return False 
     elif start.endswith('6') or end.startswith('6'): 
      return has_devils_number(start) or has_devils_number(end) 
     return True 

はここのようにパフォーマンスが見えるものですあなたはそうです。

+1

OPを学び、テストするのに最適なツールです。「6666」は一致しないはずです。 –

+0

私はこれを最初に考えました。しかし、それが他の6sの中にあってもそれが666を検出するこのようには機能しません。 66666は、そうであってはならないときに悪魔の番号とみなされます。ありがとう!! – Chihab

+0

@Chihab私は*動作するだろういくつかのコードを追加しましたが、おそらくregexオプションを使用すると、遅いかもしれませんが?第2のアプローチについては、 –

3

これにはregular expressionを使用する必要があります。 (?:^|[^6])(666)(?:[^6]|$)のようなものが動作するようです。これは、文字列^または|のいずれかが6 [^6]でない場合は、666、次に6以外の文字列、または末尾にある$という文字列を意味します。あなたのコードで

>>> p = r"(?:^|[^6])(666)(?:[^6]|$)" 
>>> re.search(p, "123666") 
<_sre.SRE_Match at 0x7fe120f12918> 
>>> re.search(p, "666123") 
<_sre.SRE_Match at 0x7fe120f128a0> 
>>> re.search(p, "12366666123") 
None 

、これはトリック(テストされていない)を実行する必要があります。

def devil(x): 
    p = r"(?:^|[^6])(666)(?:[^6]|$)" 
    return re.search(p, x) is not None 

パフォーマンスが(しかし、あなたの場合には、それはすべきではない)問題がある場合は、正規表現をプリコンパイルすることができます。

p = re.compile(r"(?:^|[^6])(666)(?:[^6]|$)") 
def devil_fast(x): 
    return p.search(x) is not None 

タイミング:

In [5]: numbers = ['666', '6', '123666', '12366', '66123', '666123', '666666', '6666', '6'*9, '66661236666', '12366664566786669'] 
In [8]: %timeit [devil(x) for x in numbers] 
100000 loops, best of 3: 14 µs per loop 
In [9]: %timeit [devil_fast(x) for x in numbers] 
100000 loops, best of 3: 6.32 µs per loop 
+0

Yess !!!!ありがとうございました!!!!!!!!! – Chihab

+0

@Chihabこれで問題が解決した場合は、この質問または別の回答を確認して、質問を解決済みとマークすることが考えられます。 –

+0

@tobias_kあなたの投稿が表示されませんでした。私は今、なぜ私の答えは、 "エッジ"のケースでは動作しません:-)を参照してください –

関連する問題