2013-11-29 3 views
0

У меня проблема с позиционированием элементов списка в программе python.
Я использую Python 2.7 Это мой код:Неправильное позиционирование в списках python

MAX_DOWNLOADERS = 4 
from threading import Lock 
import time,random,unittest 
from random import randrange 

class Choker: 
    def __init__(self,PeerManager,max_uploads,min_uploads=None): 
     self.PM = PeerManager 
     self.max_uploads = max_uploads 
     if min_uploads == None: 
      self.min_uploads = max_uploads 
     else: 
      self.min_uploads = min_uploads 
     self._round = 0 
     self.run = True 
     self.lock = Lock() 
    def _unchoke_peers(self): 
     while self.run: 
      self._rechoke() 
      self.count += 1 
      time.sleep(UNCHOKE_INTERVAL) 
    def _rechoke(self): 
     count = 0 
     preferred = [] 
     if self._round % 3 == 0: 
      for pos,peer in enumerate(self.PM.peers): 
       if peer.am_choking and peer.peer_interested: 
        self.PM.peers = self.PM.peers[pos:] + self.PM.peers[:pos] 
        break 
     for i in self.PM.peers: 
      if not self._snubbed(i) and i.peer_interested: 
       if self.PM.completed: 
        preferred.append((i.download_speed,i)) 
       else: 
        preferred.append((i.upload_speed,i)) 
     preferred.sort(reverse=True) 
     print(len(preferred)) 
     del preferred[self.max_uploads-1:] 
     preferred = [x[1] for x in preferred] 
     print(len(preferred)) 
     hit = False 
     for peer in self.PM.peers: 
      if peer in preferred: 
       peer.send_unchoke() 
       print('unchoking peer in preferred') 
       count += 1 
       print('count += 1 in preferred') 
      else: 
       if count < self.min_uploads or not hit: 
        peer.send_unchoke() 
        print('unchoking peer in count < self.min_uploads') 
        if peer.peer_interested: 
         count += 1 
         hit = True 
         print('count += 1 in count < self.min_uploads') 
       else: 
        peer.send_choke() 
        print('choking peer') 
    def _snubbed(self, peer): 
     if self.PM.completed: 
      return False 
     return peer.is_snubbed() 
    def connection_made(self, peer,p=None): 
     if p == None: 
      p = randrange(-2, len(self.PM.peers) + 1) 
     print(p) 
     self.PM.insert(max(p, 0), peer) 
     self._rechoke() 
    def connection_lost(self, peer): 
     self.PM.peers.remove(peer) 
     if peer.peer_interested and not peer.am_choking: 
      self._rechoke() 
    def interested(self, peer): 
     if not peer.am_choking: 
      self._rechoke() 
    def not_interested(self, peer): 
     if not peer.am_choking: 
      self._rechoke() 


class PM: 
    def __init__(self): 
     self.peers = [] 
     self.completed = False 
     self.lock = Lock() 
    def insert(self,pos,elem): 
     self.lock.acquire() 
     self.peers.insert(pos,elem) 
     self.lock.release() 
    def remove(self,elem): 
     self.peers.remove(elem) 


class PeeR: 
    def __init__(self,upload_speed=0): 
     self.peer_interested = False 
     self.am_choking = True 
     self.is_seeder = False 
     self.upload_speed = upload_speed 
     self.download_speed = 0 
     self.snubbed = False 
    def send_choke(self): 
     self.am_choking = True 
    def send_unchoke(self): 
     self.am_choking = False 
    def is_snubbed(self): 
     return self.snubbed 

Когда я пишу код, расположенный ниже:

pm = PM() 
choker = Choker(pm,1) 
c1 = PeeR() 
c2 = PeeR(1) 
c3 = PeeR(2) 
c4 = PeeR(3) 
choker.connection_made(c1) 
choker.connection_made(c2,1) 
choker.connection_made(c3,1) 
choker.connection_made(c4,1) 

в pm.peers (это список) положение элементы (c1, c2 ...) неверны (например, c4 не находится в позиции 1, c1 не находится в положении 0).
Почему это происходит?
Пожалуйста, помогите мне.

+1

Каков ожидаемый порядок и какой фактический заказ вы получаете? Когда я его прочитал, ожидаемый порядок должен быть 'c1, c4, c3, c2', это правильно? – Hyperboreus

+0

Ваш код, как указано здесь, ** делает ** положить 'c1' в позицию 0. Я запустил код. 'c2' до' c4' вставляются в положение 1 и сдвигаются вправо по мере того, как вставляются больше, поэтому вы заканчиваете 'c1, c4, c3, c2' и их позиции не сдвигаются в противном случае. –

+0

Другими словами, что вы ** ** видите вместо этого, и уверены ли вы, что вы разместили здесь весь код? –

ответ

0

Я пытался уменьшить свой код на соответствующие части:

#! /usr/bin/python2.7 

from random import randrange 

class Choker: 
    def __init__(self,PeerManager): 
     self.PM = PeerManager 
    def connection_made(self, peer,p=None): 
     if p == None: 
      p = randrange(-2, len(self.PM.peers) + 1) 
     self.PM.insert(max(p, 0), peer) 

class PM: 
    def __init__(self): 
     self.peers = [] 
    def insert(self,pos,elem): 
     self.peers.insert(pos,elem) 

pm = PM() 
choker = Choker(pm) 
c1, c2, c3, c4 = 'C1', 'C2', 'C3', 'C4' 
choker.connection_made(c1) 
choker.connection_made(c2,1) 
choker.connection_made(c3,1) 
choker.connection_made(c4,1) 

print (pm.peers) 

Теперь это дает ожидаемый результат (как я ожидал): ['C1', 'C4', 'C3', 'C2'].

C1 вставляется в положении 0. C2 вставляется в положении 1. C3 вставляется в положении 1, перемещение C2 в положение 2. C4 вставляется в положении 1, перемещение C2 в положение 3 и C3 в положение 2.


Как Мартейн отметил: Помните, что внутри rechoke вы реорганизовать свой список:

self.PM.peers = self.PM.peers[pos:] + self.PM.peers[:pos] 
+0

Это означает, что, скорее всего, OP пропустил что-то в '_rechoke', где он изменит порядок сверстников. –

+0

Вы правы:' self.PM .peers = self.PM.peers [pos:] + self.PM.peers [: pos] 'inside' rechoke'. – Hyperboreus

+0

О, со строками это работает, но с объектами класса это беспорядок позиция – Nurchik

Смежные вопросы