2013-10-06 47 views
1

因此,作爲我在Code Academy之外的第一個python項目,我決定在pygame上創建一個基本的分子動力學模擬器。它可以很好地工作一段時間,但是一旦電子開始移動得太快,並且將所有其他電子從原子上剝離,我就會在標題中看到TypeError。我不知道這是從哪裏來的,只是在程序運行足夠長的時間後纔會出現,讓我搞亂了所有的物理。TypeError:不可用類型:'list'(幾幀到程序中)

現在我知道這個錯誤告訴我,我正在嘗試將一個列表傳遞給我不應該的地方,但是我已經查看了該程序並且無法確定它在哪裏。這個錯誤會彈出來,告訴電子如何軌道運行他們的原子angle = findA(particles[el], particles[nuc]) + 0.001,它由接近結束的代碼塊控制,它告訴程序按什麼順序做物理,以及每個電子對軌道的意義列表由另一個點控制,依此類推。

所以我決定給你所有的代碼。

import sys, pygame, math 
from pygame.locals import * 

pygame.init() 
sizeScreen = width, height = 1000, 700 
sizeMenu = width, height = 652, 700 


e = 1.6 * 10 ** -19 
particles = {} 
mx, my = 0, 0 
selected = [] 

def findOrbital(el): 
    for a in particles: 
     if a != el and particles[a][4] != 'el': 
      if findD(particles[el], particles[a]) < 5 * 10 ** -11 and PTI[particles[a][4]][7] > len(particles[a][5]): 
       particles[a][5].append(el) 
       particles[el][5].append(a) 



def searcher(List, item): 
    for a in List: 
     if a == item: 
      return True 
    return False 

def moveAtEls(el, nuc): 
    angle = findA(particles[el], particles[nuc]) + 0.001 
    particles[el][0] = particles[nuc][0] + 50 * math.cos(angle) 
    particles[el][1] = particles[nuc][1] + 50 * math.sin(angle) 


def check(each): 
    if particles[each][0] < 175: 
     particles[each][2] = -particles[each][2] 
     particles[each][0] = 175 
    elif particles[each][0] > 1000: 
     particles[each][2] = -particles[each][2] 
     particles[each][0] = 1000 
    if particles[each][1] < 0: 
     particles[each][3] = -particles[each][3] 
     particles[each][1] = 0 
    elif particles[each][1] > 700: 
     particles[each][3] = -particles[each][3] 
     particles[each][1] = 700 
    if particles[each][4] == 'el': 
     a = 'n' 
     findOrbital(each) 
     if a != 'n': 
      particles[each][5].append(a) 
      particles[a][5].append(each) 


def findD(self, other): 
    return math.hypot((self[0] - other[0]), (self[1] - other[1])) * 0.62 * 10 ** -12 
def findA(self, other): 
    return math.atan2((self[1] - other[1]), (self[0] - other[0])) 


def move(self): 
    for other in particles: 
     if particles[other] != self and self[5] != particles[other] [5] and not searcher(self[5], other): 
      D = findD(self, particles[other]) 
      if D == 0: 
       self[5].append(other) 
       particles[other][5].append(self) 
       break 
      angle = findA(self, particles[other]) 
      F = 8987550000 * (PTI[self[4]][4] * PTI[particles[other][4]][4] * e ** 2)/D ** 2 
      a = int(F/PTI[self[4]][5]) 
      ax = a * math.cos(angle) 
      ay = a * math.sin(angle) 
      self[2] += ax/(10 ** 16) 
      self[3] += ay/(10 ** 16) 
    self[0] += self[2]/(10 ** 8) 
    self[1] += self[3]/(10 ** 8) 


pressed = '' 
press = {'Katom':[2,148,2,32,0],'Knuc':[2,148,36,66,0],'Kel':[2,148,70,100,0]} 

PTI = {'el':[0, 0, 0, 0, -1, 9.11 * 10 ** -31, pygame.image.load("electron.png"), 2], 
'HNuc' : [185, 214, 8, 37, 1, 1.7 * 10 ** -27, pygame.image.load("nuc/HNuc.png"), 2, 1], 
'HeNuc': [586, 613, 8, 37, 2, 6.6 * 10 ** -27, pygame.image.load("nuc/HeNuc.png"), 2, 2], 
'LiNuc': [185, 214, 40, 69, 1, 1.16 * 10 ** -26, pygame.image.load("nuc/LiNuc.png"), 8, 1], 
'BeNuc': [216, 246, 40, 69, 2, 1.53 * 10 ** -26, pygame.image.load("nuc/BeNuc.png"), 8, 2], 
'BNuc' : [428, 457, 40, 69, 3, 1.84 * 10 ** -26, pygame.image.load("nuc/BNuc.png"), 8, 3], 
'CNuc' : [460, 489, 40, 69, 4, 2.04 * 10 ** -26, pygame.image.load("nuc/CNuc.png"), 8, 4], 
'NNuc' : [492, 520, 40, 69, 5, 2.38 * 10 ** -26, pygame.image.load("nuc/NNuc.png"), 8, 5], 
'ONuc' : [523, 551, 40, 69, 6, 2.72 * 10 ** -26, pygame.image.load("nuc/ONuc.png"), 8, 6], 
'FNuc' : [554, 583, 40, 69, 7, 3.23 * 10 ** -26, pygame.image.load("nuc/FNuc.png"), 8, 7], 
'NeNuc': [586, 613, 40, 69, 8, 3.43 * 10 ** -26, pygame.image.load("nuc/NeNuc.png"), 8, 8]} 

menu = pygame.display.set_mode(sizeMenu) 
screenColor = pygame.Color(255, 255, 220) 
screen = pygame.display.set_mode(sizeScreen) 
edgeObj = pygame.image.load("edge.png") 
addEl = [pygame.image.load('addElectron1.png'), pygame.image.load('addElectron2.png')] 
addAtom = [pygame.image.load("addAtom1.png"), pygame.image.load("addAtom2.png"), pygame.image.load("atomTable.png")] 
addNucleus = [pygame.image.load("addNuc1.png"), pygame.image.load("addNuc2.png"), pygame.image.load("NucTable.png")] 

while True: 
    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      pygame.quit() 
      sys.exit(0) 

     elif event.type == MOUSEMOTION: 
      mx, my = event.pos 

     mouseState = pygame.mouse.get_pressed() 
     if mouseState[0]: 
      for key in press: 
       if press[key][0] < mx <press[key][1] and press[key][2] < my < press[key][3]: 
        pressed = key 
        press[key][4] = 1 

     if not mouseState[0] and pressed == 'Kel': 
      particles[len(particles)] = [mx, my, 0, 0, 'el', []] 
      pressed = '' 
      press['Kel'][4] = 0 

     if pressed != '': 
      if not mouseState[0]: 
       if press[pressed][0] < mx <press[pressed][1] and press[pressed][2] < my < press[pressed][3]: 
        press[pressed][4] = 2 
        pressed = '' 

     if press['Knuc'][4] == 2 or press['Katom'][4] == 2: 
      if mouseState[0]: 
       if 621 < mx < 651 and 2 < my < 14: 
        press['Knuc'][4] = 0 
        press['Katom'][4] = 0 
       if press['Knuc'][4] == 2: 
        for nuc in PTI: 
         if PTI[nuc][0] < mx < PTI[nuc][1] and PTI[nuc][2] < my < PTI[nuc][3]: 
          press['Knuc'][4] = 0 
          selected.append(nuc) 
       if press['Katom'][4] == 2: 
        for nuc in PTI: 
         if PTI[nuc][0] < mx < PTI[nuc][1] and PTI[nuc][2] < my < PTI[nuc][3]: 
          a = 0 
          selected.append(nuc) 
          while a < PTI[nuc][8]: 
           selected.append('el') 
           a += 1 
          press['Katom'][4] = 0 
     if selected != []: 
      if not mouseState[0]: 
       a = len(particles) 
       particles[a] = [mx, my, 0, 0, selected[0], [b for b in range(a+1, len(selected)-1)]] 
       for item in selected: 
        if item != selected[0]: 
         particles[len(particles)] = [mx, my, 0, 0, item, [a]] 
       selected = [] 


    for each in particles: 
     check(each) 
     move(particles[each]) 
     check(each) 
     if len(particles[each][5]) > 0 and particles[each][4] == 'el': 
      moveAtEls(each, particles[each][5][0]) 
     particles[each][5] = [] 

    screen.fill(screenColor) 
    for a in particles: 
     screen.blit(PTI[particles[a][4]][6], (particles[a][0] - 29, particles[a][1] - 31)) 
    menu.blit(edgeObj, (0, 0)) 
    menu.blit(addNucleus[press['Knuc'][4]], (2, 2)) 
    menu.blit(addAtom[press['Katom'][4]], (2, 2)) 
    menu.blit(addEl[press['Kel'][4]], (2, 2)) 

    pygame.display.flip() 

很抱歉,如果我是通過發佈所有的代碼討厭,但我是一個完整的n00b,我很驚訝,我得到這個至今沒有幫助。我知道整個事情是不整潔的,但如果你能幫助這個錯誤,我會非常感激。

下一次,我就堅持到print("Hello, World!")

+0

在findA中的語句周圍試一試。 TypeError除外。在except子句中,打印自己,其他可能是type(self),type(other)或者只是打印locals(),因爲它是一個非常簡單的函數。重新提出異常。你將能夠看到你是否通過它,你認爲你通過它。如果您使用的是Windows/Idle,則可以使用Debug菜單項的StackViewer選項檢查堆棧。 – wwii

回答

1

所以,我認爲正在發生的事情是,當執行該行angle = findA(particles[el], particles[nuc]) + 0.001,無論是el變量或nuc變量是某種類型的列表,而不是一個單個對象。

這會引發錯誤,因爲particles是字典,並且您不能在dict中將列表或任何可變類型作爲鍵。

因此,鑑於這個錯誤不會立即執行,我懷疑在某個地方,在一段不會立即執行的代碼中,您意外地傳入某種list


如果你確實意味着通過使用列表作爲關鍵要看東西在particles字典,那麼你應該將列表轉換爲tuple第一:元組是像列表一樣,但是是不可變的,所以可以被散列並用作字典的關鍵字。

相關問題