2016-04-15 9 views
0

Ich habe ein wenig Code, der ein Array von Linien (32X32-Raster) zeichnet. Der eigentliche Code, der es zeichnet, beginnt bei #Nested loop to draw anti-aliased lines in a 32X32 grid. Da ich einen Patch mit Linien unterschiedlicher Ausrichtung habe, sind die Codes ein paar Zeilen lang.Wie mache ich eine Variable für eine verschachtelte Schleife?

Im Moment habe ich eine .draw() am Ende der verschachtelten Schleife, die mein Array zeichnet.

Es scheint nicht ein guter Weg, dies zu tun.

Gibt es eine Möglichkeit, eine Variable für diese gesamte geschachtelte Schleife zu erstellen, damit ich sie so aufrufen kann, wie ich will? Zum Beispiel myStim.draw()

# Import what is needed 
import numpy as np 
from psychopy import visual, event, core, logging 
from math import sin, cos 
import random, math 

# Create space variables and a window 
lineSpaceX = 0.55 
lineSpaceY = 0.55 

patch_orientation = 45 # zero is vertical, going anti-clockwise 
surround_orientation = 90 

#Jitter values 
g_posJitter = 0.05 #gaussian positional jitter 
r_posJitter = 0.05 #random positional jitter 

g_oriJitter = 5 #gaussian orientation jitter 
r_oriJitter = 5 #random orientation jitter 

#Region where the rectangular patch would appear 
x_rand=random.randint(6,13) #random.randint(Return random integers from low (inclusive) to high (inclusive). 
y_rand=random.randint(6,16) 

#rectangular patch dimensions 
width=15 
height=12 

message = visual.TextStim(win,pos=(0.0,-12.0),text='...Press SPACE to continue...') 

# Initialize clock to record response time 
rt_clock = core.Clock() 


#Nested loop to draw anti-aliased lines in a 32X32 grid 
for x in xrange(1,33): #32x32 grid. 
    for y in xrange(1,33): 
     ##Define x & y value (Gaussian distribution-positional jitter) 
     x_pos = (x-32/2-1/2)*lineSpaceX + random.gauss(0,g_posJitter) #random.gauss(mean,s.d); -1/2 is to center even-numbered stimuli; 32x32 grid 
     y_pos = (y-32/2-1/2)*lineSpaceY + random.gauss(0,g_posJitter) 

     if (x >= x_rand and x < x_rand+width) and (y >= y_rand and y < y_rand+height): # note only "=" on one side 
      Line_Orientation = random.gauss(patch_orientation,g_oriJitter) #random.gauss(mean,s.d) - Gaussian func. 
     else: 
      Line_Orientation = random.gauss(surround_orientation,g_oriJitter) #random.gauss(mean,s.d) - Gaussian func. 
      #stimOri = random.uniform(xOri - r_oriJitter, xOri + r_oriJitter) #random.uniform(A,B) - Uniform func. 
     visual.Line(win, units = "deg", start=(0,0), end=(0.0,0.35), pos=(x_pos,y_pos), ori=Line_Orientation, autoLog=False).draw() #Gaussian func. 

frameN = 0 
for frameN in range(80): #for exactly 80 frames; 1 frame = 16.67ms on the 1920 x 1080 monitor 
    if frameN == 0: 
     rt_clock.reset() # set reaction time clock to 0 
    message.draw() 
    win.flip()# display stimulus 

    frameN = frameN + 1 
    keys = event.waitKeys(keyList=['space', 'escape','q']) #create key list response 

    # handle key responses 
    if len(keys)>0: 
     rt = rt_clock.getTime() 
     if keys == ['space']: 
      event.clearEvents() 
      break 
     else: 
      print 'Stopped Early' 
      win.close() 
      core.quit() 

print x_rand, y_rand 
print keys, rt #display response and reaction time on screen output window 
+3

Sie müssen sich über Funktionen (Stichwort 'def') und Objekte (Stichwort' CLASS') lesen – Joe

+0

Wollen Sie um alle Zeileninformationen zu speichern, und nachdem die Doppelschleife beendet ist, zeichnen Sie alle auf einmal? Es ist unklar, was du fragst. – Evert

+0

Hi Slayer, es tut mir schrecklich leid, wenn das eine Anfängerfrage ist (Ich bin so neu in der Programmierung), aber wäre ich in der Lage, es zu einer Funktion zu machen, da die ganze Menge von Codes, an denen ich interessiert bin, in einer for-Schleife ist? Die meisten Beispiele, die ich online gesehen habe, sind nicht in for-Schleifen/hat so Zeilen von Codes. –

Antwort

1
  1. Es ist nicht eine Variable, die Sie wollen, aber eine Funktion.

  2. Die Art, wie Sie gerade Dinge tun (über visual.Line(...).draw()) ist sehr ineffizient. Sie erstellen eine neue Zeile während einer Iteration, nur um sie einmal zu zeichnen und keine Referenz darauf zu speichern. Ein viel zeiteffizienteres Schema besteht darin, nur eine einzelne Linienobjektinstanz zu erstellen, die mit einem Variablennamen referenziert wird, und dann bei jeder Iteration einfach ihre Attribute (Ausrichtung usw.) zu aktualisieren, bevor sie gezeichnet wird.

  3. Eine Alternative wäre, einmal mehrere Zeilenobjektinstanzen zu erstellen, aber jede in einer Liste zu speichern. Dann benötigt, um sie wieder als Zeichnung ist eine einfache Sache von:

for line_instance in line_list:

line_instance.draw() 
+0

1. Danke - Es ist jetzt einfacher, dass es in einer Funktion ist. –

+0

2. visual.line() ist das einzige, was PsychoPy zum Zeichnen von Linienreizen empfohlen wird. Würde es anders funktionieren? Wenn Sie sagen "bei jeder Iteration, aktualisieren Sie einfach ihre Attribute" meinst du, dass ich die Codes, die ich derzeit für die Position und Ausrichtung in einer Variablen habe, später zuweisen (dh; ArrayOri = .... myStim.ori = arrayOri myStim.draw() Wäre das korrekt? –

+0

Ja, natürlich sollten Sie 'visual.line()' verwenden, um Zeilenobjekte zu erstellen.Das Problem ist, dass Sie sie in einer Variablen speichern sollten , um ihnen die Flexibilität zu geben, sie später über eine Funktion schnell neu zu zeichnen und/oder ihre Attribute nach Bedarf zu aktualisieren.Dies ist eher ein generelles Python-Programmierprinzip als PsychoPy-spezifisch. –