2013-02-16 28 views
6

Tôi đang cố gắng khởi động lại chương trình bằng cách sử dụng thử nghiệm nếu dựa trên dữ liệu nhập từ người dùng.Làm cách nào để khởi động lại một chương trình dựa trên đầu vào của người dùng?

Mã này không làm việc, nhưng đó là khoảng những gì tôi sau:

answer = str(raw_input('Run again? (y/n): ')) 

if answer == 'n': 
    print 'Goodbye' 
    break 
elif answer == 'y': 
    #restart_program??? 
else: 
    print 'Invalid input.' 

Những gì tôi đang cố gắng làm là:

  • nếu bạn trả lời y - khởi động lại chương trình từ đầu
  • nếu bạn trả lời n - chương trình kết thúc (phần đó hoạt động)
  • nếu bạn nhập bất kỳ thứ gì khác, nó sẽ in 'đầu vào không hợp lệ. xin vui lòng nhập y hoặc n ... 'hoặc một cái gì đó, và yêu cầu bạn một lần nữa cho đầu vào mới.

Tôi thực sự gần với giải pháp có vòng lặp "trong khi thực", nhưng chương trình chỉ khởi động lại bất kể bạn nhấn (ngoại trừ n) hoặc bất kể bạn nhấn gì (ngoại trừ y). Bất kỳ ý tưởng?

Trả lời

4

Hãy thử điều này:

while True: 
    # main program 
    while True: 
     answer = raw_input('Run again? (y/n): ') 
     if answer in ('y', 'n'): 
      break 
     print 'Invalid input.' 
    if answer == 'y': 
     continue 
    else: 
     print 'Goodbye' 
     break 

Các bên trong vòng lặp while vòng cho đến khi đầu vào là hai 'y' hoặc 'n'. Nếu đầu vào là 'y', vòng lặp while bắt đầu lại (continue từ khóa bỏ qua mã còn lại và chuyển thẳng đến lần lặp tiếp theo). Nếu đầu vào là 'n', chương trình sẽ kết thúc.

Cũng lưu ý rằng việc chuyển đổi raw_input thành str() là thừa vì raw_input đã trả về một chuỗi.

1

Dưới đây là một cách thú vị để làm điều đó với một decorator:

def restartable(func): 
    def wrapper(*args,**kwargs): 
     answer = 'y' 
     while answer == 'y': 
      func(*args,**kwargs) 
      while True: 
       answer = raw_input('Restart? y/n:') 
       if answer in ('y','n'): 
        break 
       else: 
        print "invalid answer" 
    return wrapper 

@restartable 
def main(): 
    print "foo" 

main() 

Cuối cùng, tôi nghĩ rằng bạn cần 2 vòng lặp while. Bạn cần một vòng lặp gắn kết phần mà nhắc cho câu trả lời để bạn có thể nhắc lại nếu người dùng cung cấp cho đầu vào xấu. Bạn cần một giây để kiểm tra câu trả lời hiện tại là 'y' và tiếp tục chạy mã cho đến khi câu trả lời không phải là 'y'.

2

Sử dụng một vòng lặp while:

In [1]: start = 1 
    ...: 
    ...: while True: 
    ...:  if start != 1:   
    ...:   do_run = raw_input('Restart? y/n:') 
    ...:   if do_run == 'y': 
    ...:    pass 
    ...:   elif do_run == 'n': 
    ...:    break 
    ...:   else: 
    ...:    print 'Invalid input' 
    ...:    continue 
    ...: 
    ...:  print 'Doing stuff!!!' 
    ...: 
    ...:  if start == 1: 
    ...:   start = 0 
    ...:   
Doing stuff!!! 

Restart? y/n:y 
Doing stuff!!! 

Restart? y/n:f 
Invalid input 

Restart? y/n:n 

In [2]: 
+0

Ok, Ok. Đủ công bằng. Bạn không * cần * 2 'while' vòng - Nhưng tôi vẫn nghĩ rằng nó sạch hơn theo cách đó :) - Tôi thực sự thích giải pháp trang trí của tôi, nhưng đó có thể là một chút tiên tiến cho một câu hỏi như thế này ... – mgilson

+0

@ mgilson - Có thể. Nhưng trang trí * chắc chắn là * khá gọn gàng, +1. – root

0

tôi có thể tạo chương trình này:

import pygame, sys, time, random, easygui 

skier_images = ["skier_down.png", "skier_right1.png", 
       "skier_right2.png", "skier_left2.png", 
       "skier_left1.png"] 

class SkierClass(pygame.sprite.Sprite): 
    def __init__(self): 
     pygame.sprite.Sprite.__init__(self) 
     self.image = pygame.image.load("skier_down.png") 
     self.rect = self.image.get_rect() 
     self.rect.center = [320, 100] 
     self.angle = 0 

    def turn(self, direction): 
     self.angle = self.angle + direction 
     if self.angle < -2: self.angle = -2 
     if self.angle > 2: self.angle = 2 
     center = self.rect.center 
     self.image = pygame.image.load(skier_images[self.angle]) 
     self.rect = self.image.get_rect() 
     self.rect.center = center 
     speed = [self.angle, 6 - abs(self.angle) * 2] 
     return speed 

    def move(self,speed): 
     self.rect.centerx = self.rect.centerx + speed[0] 
     if self.rect.centerx < 20: self.rect.centerx = 20 
     if self.rect.centerx > 620: self.rect.centerx = 620 

class ObstacleClass(pygame.sprite.Sprite): 
    def __init__(self,image_file, location, type): 
     pygame.sprite.Sprite.__init__(self) 
     self.image_file = image_file 
     self.image = pygame.image.load(image_file) 
     self.location = location 
     self.rect = self.image.get_rect() 
     self.rect.center = location 
     self.type = type 
     self.passed = False 

    def scroll(self, t_ptr): 
     self.rect.centery = self.location[1] - t_ptr 

def create_map(start, end): 
    obstacles = pygame.sprite.Group() 
    gates = pygame.sprite.Group() 
    locations = [] 
    for i in range(10): 
     row = random.randint(start, end) 
     col = random.randint(0, 9) 
     location = [col * 64 + 20, row * 64 + 20] 
     if not (location in locations) : 
      locations.append(location) 
      type = random.choice(["tree", "flag"]) 
      if type == "tree": img = "skier_tree.png" 
      elif type == "flag": img = "skier_flag.png" 
      obstacle = ObstacleClass(img, location, type) 
      obstacles.add(obstacle) 
    return obstacles 

def animate(): 
    screen.fill([255,255,255]) 
    pygame.display.update(obstacles.draw(screen)) 
    screen.blit(skier.image, skier.rect) 
    screen.blit(score_text, [10,10]) 
    pygame.display.flip() 

def updateObstacleGroup(map0, map1): 
    obstacles = pygame.sprite.Group() 
    for ob in map0: obstacles.add(ob) 
    for ob in map1: obstacles.add(ob) 
    return obstacles 

pygame.init() 
screen = pygame.display.set_mode([640,640]) 
clock = pygame.time.Clock() 
skier = SkierClass() 
speed = [0, 6] 
map_position = 0 
points = 0 
map0 = create_map(20, 29) 
map1 = create_map(10, 19) 
activeMap = 0 
obstacles = updateObstacleGroup(map0, map1) 
font = pygame.font.Font(None, 50) 

a = True 

while a: 
    clock.tick(30) 
    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: sys.exit() 
     if event.type == pygame.KEYDOWN: 
      if event.key == pygame.K_LEFT: 
       speed = skier.turn(-1) 
      elif event.key == pygame.K_RIGHT: 
       speed = skier.turn(1) 
    skier.move(speed) 
    map_position += speed[1] 

    if map_position >= 640 and activeMap == 0: 
     activeMap = 1 
     map0 = create_map(20, 29) 
     obstacles = updateObstacleGroup(map0, map1) 
    if map_position >=1280 and activeMap == 1: 
     activeMap = 0 
     for ob in map0: 
      ob.location[1] = ob.location[1] - 1280 
     map_position = map_position - 1280 
     map1 = create_map(10, 19) 
     obstacles = updateObstacleGroup(map0, map1) 
    for obstacle in obstacles: 
     obstacle.scroll(map_position) 

    hit = pygame.sprite.spritecollide(skier, obstacles, False) 
    if hit: 
     if hit[0].type == "tree" and not hit[0].passed: 
      skier.image = pygame.image.load("skier_crash.png") 
      easygui.msgbox(msg="OOPS!!!") 
      choice = easygui.buttonbox("Do you want to play again?", "Play", ("Yes", "No")) 
      if choice == "Yes": 
       skier = SkierClass() 
       speed = [0, 6] 
       map_position = 0 
       points = 0 
       map0 = create_map(20, 29) 
       map1 = create_map(10, 19) 
       activeMap = 0 
       obstacles = updateObstacleGroup(map0, map1) 
      elif choice == "No": 
       a = False 
       quit() 
     elif hit[0].type == "flag" and not hit[0].passed: 
      points += 10 
      obstacles.remove(hit[0]) 

    score_text = font.render("Score: " + str(points), 1, (0, 0, 0)) 
    animate() 

Link: https://docs.google.com/document/d/1U8JhesA6zFE5cG1Ia3OsTL6dseq0Vwv_vuIr3kqJm4c/edit

+2

Điều này là quá xa, quá dài để giải thích ngắn gọn cách khởi động lại một chương trình. –

10

Dòng này sẽ vô điều kiện khởi động lại chương trình đang chạy từ đầu:

os.execl(sys.executable, sys.executable, *sys.argv) 

Một trong những lợi thế của nó so với các đề xuất còn lại cho đến nay là bản thân chương trình sẽ được đọc lại.

Điều này có thể hữu ích nếu, ví dụ, bạn đang sửa đổi mã của nó trong một cửa sổ khác.

+1

Điều này không hoạt động trên các cửa sổ nếu Python được cài đặt trong đường dẫn có dấu cách – Beefster

+1

@Beefster điều này có thể được giải quyết bằng cách sử dụng 'subprocess.call (sys.executable + '"' + os.path.realpath (__ file__) + ' "')' –

+0

@EladAvron Vấn đề với giải pháp đó là nó tạo ra một chuỗi các tiến trình con vô tận mà cuối cùng sẽ làm cho hệ điều hành chạy hết bộ nhớ. Tôi không chắc điều gì xảy ra vào thời điểm đó. – Beefster

2

Bạn có thể thực hiện việc này chỉ đơn giản qua các hàm do người dùng xác định.Mã có dạng như sau:

def script() 
restart = raw_input("Would you like to restart this program?") 
    if restart == "yes" or restart == "y": 
     script() 
    if restart == "n" or restart == "no": 
     print "Script terminating. Goodbye." 
script() 

Tất nhiên bạn có thể thay đổi nhiều thứ ở đây. Những gì được nói, những gì kịch bản sẽ chấp nhận như là một đầu vào hợp lệ, các biến và tên hàm. Bạn chỉ có thể lồng toàn bộ chương trình vào một hàm do người dùng định nghĩa (Tất nhiên bạn phải cung cấp mọi thứ bên trong thụt lề thêm) và khởi động lại bất cứ lúc nào bằng cách sử dụng dòng mã sau: myfunctionname(). Thông tin thêm về điều này here.

+0

Tất nhiên, hãy cho tôi biết nếu điều này không thành công và tôi sẽ cố gắng sửa –

Các vấn đề liên quan