我正在阅读 O'Reilly 的书“Exploring Everyday Things in R and Ruby”,并尝试用 Python 重写所有 Ruby 代码。第一个示例是用于计算建筑物需要多少浴室的模型。我正在使用的代码如下。
但是,当我运行 example34.py 文件时,出现以下错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "example34.py", line 39, in <module>
new_restroom.enter(queue.pop(0))
File "restroom.py", line 21, in enter
unoccupied_facilities[0].occupy(person)
File "restroom.py", line 46, in occupy
Person.population.remove(person)
ValueError: list.remove(x): x not in list
我是 Python 新手,所以我怀疑这是与 Python 的变量范围或某些未知(对我而言)属性有关的问题。奇怪的是,在它中断之后,runningperson in Person.population
返回 True,并且命令Person.population.remove(person)
成功删除了那个 person 实例,所以这个 person 显然在列表中。
有任何想法吗?
示例 34.py:
from restroom import * # imports the model
# Simulation script 1
frequency = 3 # how many times a person goes to the restroom within the period
facilities_per_restroom = 3
use_duration = 1 # measured in ticks
population_range = range(100, 110, 10) # Creates an array from 10 to 600 by 10s
# Stores data for printing later
data = {}
# Loops for each population size in the above range
for population_size in population_range:
# Starts each loop fresh
Person.population = []
# Creates the population of people
Person.population = [
Person(frequency, use_duration) for
each in range(population_size)]
# Creates the key for this population size
data[population_size] = []
#Create the restroom
new_restroom = Restroom(facilities_per_restroom)
# Iterate over the period
for each in range(duration):
# Records the queue size at this tick
data[population_size].append(len(new_restroom.queue))
# Create a temporary queue so that we can sort people between the
# facilities and the restroom queue for this "tick"
queue = list(new_restroom.queue)
# Clear the queue to prepare for sorting
new_restroom.queue = []
# Take each person from the temporary queue and try adding
# them a facility
while bool(queue):
# De-queue the person at the front of the line, place in an
# unoccupied facility or, if none, back to the restroom queue
new_restroom.enter(queue.pop(0))
# for each person in the population, check if they need to go
for person in Person.population:
if person.need_to_go():
new_restroom.enter(person)
new_restroom.tick()
print(data)
厕所.py:
from random import randint
duration = 9 * 60 # minutes
class Restroom(object):
def __init__(self, facilities_per_restroom=3):
# Start with an empty queue
self.queue = []
# The facilities in this restroom
self.facilities = []
# Creates the facilities
self.facilities = ([Facility() for each in
range(facilities_per_restroom)])
def enter(self, person):
unoccupied_facilities = [
facility for facility in self.facilities
if facility.occupied() == 0]
if unoccupied_facilities:
unoccupied_facilities[0].occupy(person)
else:
self.queue.append(person)
Person.population.remove(person)
def tick(self):
[each.tick() for each in self.facilities]
[f.tick for f in self.facilities]
class Facility(object):
def __init__(self):
self.occupier = None # no one is occupying this facility at the start
self.duration = 0 # how long the facility has been occupied
def occupied(self):
return 1 if (self.occupier is not None) else 0
def occupy(self, person):
# if the facility is unoccupied, add the person. Else, return false.
if not self.occupied():
self.occupier = person
self.duration = 1
#remove the person from the population since
# they're in a facility now
Person.population.remove(person)
return 1 # return true
else:
return 0 # Return false
def vacate(self):
Person.population.append(self.occupier)
self.occupier = None
def tick(self):
# if the facility is occupied and they've been
# there longer than the use duration, have them leave
if self.occupied() and (self.duration > self.occupier.use_duration):
self.vacate()
self.duration = 0
elif self.occupied():
# If occupied, increment the time
self.duration += 1
class Person(object):
#Class variable for storing the entire population
population = []
def __init__(self, frequency=4, use_duration=1):
# Number of times a person uses the facilities per day
self.frequency = frequency
# How long each person uses the facilities
self.use_duration = use_duration
def need_to_go(self):
return randint(1, duration) <= self.frequency