I'm attempting to create a source for icecast2/shoutcast. But after compiling everything I've run into a segmentation error. After further debugging with gdb I was given a more detailed error.
I do not know c of any kind so I'm not sure what to make of this error
Program received signal SIGSEGV, Segmentation fault.
send_mp3 (self=0x988eb0, buff = 0xa5c154 "" at mp3.c:175175 mp3.c: No such file or directory.
I thought maybe it was the loop using to much resources. But no matter how much I set time.sleep() I still got the same result.
import random
import shout
from pyModules import db
from pyModules import error
import ID3
import time
import sys
import glob
class Audio(object):
def __init__(self):
self.count = 0
self.nbuf = 0
self.buf = 0
self.shout = shout.Shout()
self.db = db.database()
self.songs = self.load()
def load(self):
return glob.glob("%s*%s" % (self.config('directory'), self.config('ext')))
def start(self):
self.running = True
self.shout.host = self.config('host')
self.shout.port = self.config('port')
self.shout.mount = self.config('mount')
self.shout.protocol = self.config('protocol')
self.shout.user = self.config('user')
self.shout.password = self.config('password')
self.shout.name = self.config('name')
self.shout.format = self.config('format')
self.shout.genre = self.config('genre')
self.shout.url = self.config('url')
self.shout.public = self.config('public')
self.shout.description = self.config('description')
self.songs = self.load()
self.shout.open()
def cShuffle(self):
sh = self.getSettings(1, key='shuffle')
if sh == 1:
random.shuffle(self.songs)
def cNext(self):
n = self.getSettings(1, key='setSong')
if n == 1:
self.stop()
self.db.setNext(0)
self.Change()
def cPrev(self):
p = self.getSettings(1, key='prevSong')
if p == 1:
self.stop()
if self.count == 0:
self.count -= 1
self.db.setPrev(0)
self.Change()
else:
self.count -= 2
self.Change()
def cReload(self):
r = self.getSettings(1, key='reload')
if r == 1:
self.songs = self.load()
def check(self):
self.cShuffle()
self.cNext()
self.cPrev()
self.cReload()
def getSettings(self, mode=0, key=None):
return self.db.getSettings(mode, key)
def config(self, value):
return self.db.config(value)
def getTitle(self, File, mode=0):
try:
song = ID3.ID3(File)
title = song["TITLE"]
except:
title = "unknown"
title = title.replace("'", "")
if mode == 0:
self.db.setSongTitle(title)
return title
elif mode == 1:
self.db.setNextSongTitle(title)
return title
elif mode == 2:
self.db.setPrevSongTitle(title)
def sendBlankFile(self):
File = open('/home/radio/AudioServer/bin/blank.mp3').read()
self.shout.send(File)
def stop(self):
self.buf = 0
self.nbuf = 0
self.running = 0
self.sendBlankFile()
def Change(self):
self.stop()
if len(self.songs) >= self.count: self.count = 0
else: self.count += 1
song = self.songs[self.count]
psong = self.songs[self.count - 1]
nsong = self.songs[self.count + 1]
self.getTitle(song, mode=0)
self.getTitle(nsong, mode=1)
self.getTitle(psong, mode=2)
self.play()
def play(self):
song = open(self.songs[self.count])
cs = self.songs[self.count]
self.shout.set_metadata({'song': self.getTitle(cs)})
total = 0
st = time.time()
self.nbuf = song.read(4096)
while self.running:
self.check()
self.buf = self.nbuf
self.nbuf = song.read(4096)
self.buf = self.nbuf
total = total + len(self.buf)
if len(self.buf) == 0:
self.running = False
self.Change()
self.shout.send(self.buf)
self.shout.sync()
if __name__ == "__main__":
Server = Audio()
default = Server.config('default')
Server.db.clear(default)
Server.start()
The issue was indeed a compile problem of libshout as cox pointed out. But it only worked in debian 7 and not ubuntu 12. I think the reason why is because I did not install libogg in ubuntu I only installed vorbis which I thought was the same thing. I also installed mp3 codecs just in case.
Related
I've noticed that the code prints the date twice to the constructor and am having trouble understanding why since I believe I only instantiate the object once within my code.
This is the constructor
def __init__(self):
self.today = date.today()
print(self.today)
Here is where I instantiate it
self.data = database()
self.schedule_today = self.data.get_bulletin()
Full code for this section of the program with some unfinished functions
class database:
sch_today = ['apt: 8:00', "breakfast", "music", 'apt: 9:00', "therapy", 'apt: 12:00', "lunch"]
test_schedule = []
def __init__(self):
self.today = date.today()
print(self.today)
def get_parse_bulletin_list(self):
temp = []
index = 0
for i in self.sch_today:
if i[0:3] == 'apt':
while index%3 != 0:
temp.append('')
index+=1
temp.append(i)
else:
temp.append(i)
index += 1
return temp
def get_bulletin(self):
n_count = 1
temp = []
ref = self.get_parse_bulletin_list()
for i in ref:
if i[0:3] == 'apt':
temp.append(paper_scrap().get_layout())
n_count = 1
elif not i:
temp.append(Notecard().blank_layout())
#elif i[0:5] == '[hlf]':
#temp.append(Notecard())
elif n_count >= 3: #allign left
temp.append(Notecard())
else:
temp.append(Notecard())
n_count += 1
return temp
def update_schedule(self):
with open('calendar.txt') as r:
pass
class BulletinInterface(RelativeLayout):
def __init__(self, **kwargs):
super(BulletinInterface, self).__init__(**kwargs)
self.data = database()
self.schedule_today = self.data.get_bulletin()
self.l1 = BulletinArea(size_hint=(1,1),
padding=(38, 135, 37, 34),
orientation=('tb-lr'))
self.add_widget(self.l1)
self.b1 = Button(text="test",
background_color=(1, 1, 1, 1),
size_hint=(0.1, 0.1)
)
self.b1.bind(on_press=self.bulletin_init)
self.add_widget(self.b1)
# bulletin board initialize
self.bulletin_init()
def bulletin_init(self, touch=None):
self.init_bulletin(self.schedule_today)
def init_bulletin(self, element_list):
for i in element_list:
self.l1.add_widget(i)
Found the problem after reviewing the construction of the GUI. The KV language and regular python code were both instantiating the GUI, leading to duplicate function calls for everything.
the original code which only support python 2 is here
link to thinkgear.py
I'm trying to edit it to support python 3. the edited code is here:
import sys
import serial
from io import BytesIO
import struct
from collections import namedtuple
import logging
import logging.handlers
import sys
import time
import datetime
global delta
delta = []
_log = logging.getLogger(__name__)
_bytelog = logging.getLogger(__name__+'.bytes')
_bytelog.propagate = False
fh = logging.FileHandler('spam.log')
fh.setLevel(logging.DEBUG)
_log.addHandler(fh)
class ThinkGearProtocol(object):
def __init__(self, port):
self.serial = serial.Serial(port, 57600)
self.preread = BytesIO()
self.io = self.serial
#staticmethod
def _chksum(packet):
return ~sum(c for c in packet ) & 0xff
def _read(self, n):
buf = self.io.read(n)
if len(buf) < n:
_log.debug('incomplete read, short %s bytes', n - len(buf))
if self.io == self.preread:
_log.debug('end of preread buffer')
# self.preread.reset()
# self.preread.truncate()
# two line comment out
self.io = self.serial
buf += self.io.read(n-len(buf))
if len(buf) < n:
_log.debug('incomplete read, short %s bytes', n - len(buf))
for o in range(0, len(buf), 16):
_bytelog.debug('%04X '+' '.join(('%02X',)*len(buf[o:o+16])), o, *(c for c in buf[o:o+16]))
return buf
def _deread(self, buf):
_log.debug('putting back %s bytes', len(buf))
pos = self.preread.tell()
self.preread.seek(0, 2)
self.preread.write(buf)
self.preread.seek(pos)
self.io = self.preread
def get_packets(self):
last_two = ()
while True:
last_two = last_two[-1:]+(self._read(1),)
# _log.debug('last_two: %r', last_two)
if last_two == (b'\xAA',b'\xAA'):
plen = self._read(1)
if plen >= b'\xAA':
# Bogosity
_log.debug('discarding %r while syncing', last_two[0])
last_two = last_two[-1:]+(plen,)
else:
last_two = ()
packet = self._read(int.from_bytes((plen), byteorder='big'))
# _log.debug(plen)
checksum = self._read(1)
if ord(checksum) == self._chksum(packet):
yield self._decode(packet)
else:
_log.debug('bad checksum')
self._deread(packet+checksum)
elif len(last_two) == 2:
_log.debug('discarding %r while syncing', last_two[0])
def _decode(self, packet):
decoded = []
while packet:
extended_code_level = 0
while len(packet) and packet[0] == '\x55':
extended_code_level += 1
packet = packet[1:]
if len(packet) < 2:
_log.debug('ran out of packet: %r', '\x55'*extended_code_level+packet)
break
code = packet[0]
if code < 0x80:
value = packet[1]
packet = packet[2:]
else:
vlen = packet[1]
if len(packet) < 2+vlen:
_log.debug('ran out of packet: %r', '\x55'*extended_code_level+chr(code)+chr(vlen)+packet)
break
value = packet[2:2+vlen]
packet = packet[2+vlen:]
# _log.debug('extended_code_level is '+str(extended_code_level))
# _log.debug('code is '+str(code))
# _log.debug('data_types is '+str(data_types))
# _log.debug(not extended_code_level and code in data_types)
# _log.debug(not bool(extended_code_level and code in data_types))
# _log.debug((extended_code_level,code) in data_types)
if not bool(extended_code_level and code in data_types):
data = data_types[code](extended_code_level, code, value)
# _log.debug('extended_code_level is '+str(extended_code_level))
# _log.debug('code is '+str(code))
# _log.debug('value is '+str(value))
# _log.debug('data_types is '+str(data_types))
elif (extended_code_level,code) in data_types:
data = data_types[(extended_code_level,code)](extended_code_level, code, value)
else:
data = ThinkGearUnknownData(extended_code_level, code, value)
decoded.append(data)
return decoded
data_types = {}
class ThinkGearMetaClass(type):
def __new__(mcls, name, bases, data):
cls = super(ThinkGearMetaClass, mcls).__new__(mcls, name, bases, data)
code = getattr(cls, 'code', None)
if code:
data_types[code] = cls
extended_code_level = getattr(cls, 'extended_code_level', None)
if extended_code_level:
data_types[(extended_code_level,code)] = cls
return cls
class ThinkGearData(object, metaclass=ThinkGearMetaClass):
def __init__(self, extended_code_level, code, value):
self.extended_code_level = extended_code_level
self.code = code
# self.value = self._decode(value)
self.value = value
# _log.debug('123')
if self._log:
_log.log(self._log, '%s', self)
#staticmethod
def _decode(v):
return v
def __str__(self):
return self._strfmt % vars(self)
# __metaclass__ = ThinkGearMetaClass
_log = logging.DEBUG
class ThinkGearUnknownData(ThinkGearData):
'''???'''
_strfmt = 'Unknown: code=%(code)02X extended_code_level=%(extended_code_level)s %(value)r'
class ThinkGearPoorSignalData(ThinkGearData):
'''POOR_SIGNAL Quality (0-255)'''
code = 0x02
_strfmt = 'POOR SIGNAL: %(value)s'
_decode = staticmethod(ord)
class ThinkGearAttentionData(ThinkGearData):
'''ATTENTION eSense (0 to 100)'''
code = 0x04
_strfmt = 'ATTENTION eSense: %(value)s'
_decode = staticmethod(ord)
class ThinkGearMeditationData(ThinkGearData):
'''MEDITATION eSense (0 to 100)'''
code = 0x05
_strfmt = 'MEDITATION eSense: %(value)s'
_decode = staticmethod(ord)
class ThinkGearRawWaveData(ThinkGearData):
'''RAW Wave Value (-32768 to 32767)'''
code = 0x80
_strfmt = 'Raw Wave: %(value)s'
_decode = staticmethod(lambda v: struct.unpack('>h', v)[0])
# There are lots of these, don't log them by default
_log = False
EEGPowerData = namedtuple('EEGPowerData', 'delta theta lowalpha highalpha lowbeta highbeta lowgamma midgamma')
delta_value = namedtuple('EEGPowerData', 'delta')
class ThinkGearEEGPowerData(ThinkGearData):
'''Eight EEG band power values (0 to 16777215).
delta, theta, low-alpha high-alpha, low-beta, high-beta, low-gamma, and
mid-gamma EEG band power values.
'''
code = 0x83
_strfmt = 'ASIC EEG Power: %(value)r'
_decode = staticmethod(lambda v: EEGPowerData(*struct.unpack('>8L', ''.join( '\x00'+v[o:o+3] for o in range(0, 24, 3)))))
#print(EEGPowerData.delta)
def main():
global packet_log
packet_log = []
logging.basicConfig(level=logging.DEBUG)
for pkt in ThinkGearProtocol('COM3').get_packets():
packet_log.append(pkt)
if __name__ == '__main__':
main()
when running in python2, i get the result like this:
DEBUG:__main__:ASIC EEG Power: EEGPowerData(delta=7784, theta=7734, lowalpha=2035, highalpha=1979, lowbeta=2914, highbeta=3996, lowgamma=1944, midgamma=1847
when running in python3, the result is like this:
DEBUG:__main__:ASIC EEG Power: b'\x00\xa9\xf1\x00t%\x00\rK\x00\x18"\x00\x16%\x00\x1d6\x00OT\x00\x17\x84'
Anyone know how should i edit this line of code in order to make it work in python 3? Thank you
_decode = staticmethod(lambda v: EEGPowerData(*struct.unpack('>8L', ''.join( '\x00'+v[o:o+3] for o in range(0, 24, 3)))))
I have 500 links to download and want to batch them by for example 10 items.
How this pseudo code would be like?
class BatchJobTask(luigi.Task)
items = luigi.Parameter()
def run(self):
listURLs = []
with ('urls_chunk', 'r') as urls
for line in urls:
listURLs.append('http://ggg'+line+'.org')
10_urls = listURLs[0:items] #10 items here
for i in 10_urls:
req = request.get(url)
req.contents
def output(self):
return self.LocalTarger("downloaded_filelist.txt")
class BatchWorker(luigi.Task)
def run(self)
# Here I should run BatchJobTask from 0 to 10, next 11 - 21 new etc...
How it would be?
Here is an approach to doing something like what you want, but with the list of strings stored as separate lines in a file.
import luigi
import requests
BATCH_SIZE = 10
class BatchProcessor(luigi.Task):
items = luigi.ListParameter()
max = luigi.IntParameter()
def requires(self):
return None
def output(self):
return luigi.LocalTarget('processed'+str(max)+'.txt')
def run(self):
for item in self.items:
req = requests.get('http://www.'+item+'.org')
# do something useful here
req.contents
open("processed"+str(max)+".txt",'w').close()
class BatchCreator(luigi.Task):
file_with_urls = luigi.Parameter()
def requires(self):
required_tasks = []
f = open(self.file_with_urls)
batch_index = 0
total_index = 0
lines = []
while True:
line = f.readline()
if not line: break
total_index += 1
if batch_index < BATCH_SIZE:
lines.append(line)
batch_index += 1
else:
required_tasks.append(BatchProcessor(batch=lines))
lines = [line]
batch_index = 1
return required_tasks
def output(self):
return luigi.LocalTarget(str(self.file_with_urls) + 'processed')
def run(self):
open(str(self.file_with_urls) + 'processed', 'w').close()
I did this.
class GetListtask(luigi.Task)
def run(self):
...
def output(self):
return luigi.LocalTarget(self.outputfile)
class GetJustOneFile(luigi.Task):
fid = luigi.IntParameter()
def requires(self):
pass
def run(self):
url = 'http://my-server.com/test' + str(self.fid) + '.txt'
download_file = requests.get(url, stream=True)
with self.output().open('w') as downloaded_file:
downloaded_file.write(str(download_file.content))
def output(self):
return luigi.LocalTarget("test{}.txt".format(self.fid))
class GetAllFiles(luigi.WrapperTask):
def requires(self):
listoffiles = [] # 0..999
for i in range(899):
listoffiles.append(i)
return [GetJustOneFile(fid=fileid) for fileid in listoffiles]
Does this code awful?
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am writing a Neural Net program to play connect four in python, and training it using existing minimax algorithms. I have written some basic code to establish communication between two algorithms. Following lines should result in one game between the two programs :-
game = ConnectFour()
game.start_new()
However, the game is played twice. ("IA is the winner" is printed twice.)
I added some debug print lines. There's a lot of code, but I cannot figure out the point where the problem is. So I am posting all of it. I suspect import statements, but do not know what is the problem exactly.
ConnectFourAIb.py:
from minimax2b import ConnectFour
def get_AI_move(grid):
i = 0
while grid[0][i]!=' ':
i += 1
return i
game = ConnectFour()
game.start_new()
minimax2b.py:
import os
import random
import time
from abc import ABCMeta, abstractmethod
CONNECT_FOUR_GRID_WIDTH = 7
CONNECT_FOUR_GRID_HEIGHT = 6
CONNECT_FOUR_COLORS = ["x","o"]
class ConnectFour(object):
_GRID_WIDTH = CONNECT_FOUR_GRID_WIDTH
_GRID_HEIGHT = CONNECT_FOUR_GRID_HEIGHT
_grid = None
_round = None
_finished = False
_winner = None
_current_player = None
_players = [None, None]
_COLORS = CONNECT_FOUR_COLORS
def __init__(self):
print("__init__")
self._round = 1
self._finished = False
self._winner = None
self._players[0] = _HumanPlayer(self._COLORS[0])
self._players[1] = _ComputerPlayer(self._COLORS[1])
for i in xrange(2):
print('%s play with %s ' % (self._players[i]._type, self._COLORS[i]))
self._current_player = self._players[random.randint(0, 1)]
self._grid = []
for i in xrange(self._GRID_HEIGHT):
self._grid.append([])
for j in xrange(self._GRID_WIDTH):
self._grid[i].append(' ')
def start(self):
print("start")
while not self._finished:
self._next_move()
def start_new(self):
print("start_new")
self._round = 1
self._finished = False
self._winner = None
self._current_player = self._players[random.randint(0, 1)]
self._grid = []
for i in xrange(self._GRID_HEIGHT):
self._grid.append([])
for j in xrange(self._GRID_WIDTH):
self._grid[i].append(' ')
self.start()
def _switch_player(self):
print("_switch_player")
if self._current_player == self._players[0]:
self._current_player = self._players[1]
else:
self._current_player = self._players[0]
def _next_move(self):
print("_next_move")
column = self._current_player.get_move(self._grid)
for i in xrange(self._GRID_HEIGHT - 1, -1, -1):
if self._grid[i][column] == ' ':
self._grid[i][column] = self._current_player._color
self._check_status()
if self._finished:
self._print_state()
return 1
self._switch_player()
self._round += 1
return 1
print("This column is full. Please choose an other column")
return
def _check_status(self):
print("_check_status")
if self._is_full():
self._finished = True
elif self._is_connect_four():
self._finished = True
self._winner = self._current_player
def _is_full(self):
print("_is_full")
return self._round > self._GRID_WIDTH * self._GRID_HEIGHT
def _is_connect_four(self):
print("_is_connect_four")
for i in xrange(self._GRID_HEIGHT - 1, -1, -1):
for j in xrange(self._GRID_WIDTH):
if self._grid[i][j] != ' ':
# check for vertical connect four
if self._find_vertical_four(i, j):
return True
return False
def _find_vertical_four(self, row, col):
print("_find_vertical_four")
consecutive_count = 0
if row + 3 < self._GRID_HEIGHT:
for i in xrange(4):
if self._grid[row][col] == self._grid[row + i][col]:
consecutive_count += 1
else:
break
if consecutive_count == 4:
if self._players[0]._color == self._grid[row][col]:
self._winner = self._players[0]
else:
self._winner = self._players[1]
return True
return False
def _print_state(self):
print("_print_state")
if self._finished:
print("Game Over!")
if self._winner != None:
print(str(self._winner._type) + " is the winner!")
else:
print("Game is a draw")
class _Player(object):
__metaclass__ = ABCMeta
_type = None
_color = None
def __init__(self, color):
self._color = color
#abstractmethod
def get_move(self, grid):
pass
class _HumanPlayer(_Player):
def __init__(self, color):
super(_HumanPlayer, self).__init__(color)
self._type = "Human"
def get_move(self, grid):
from ConnectFourAIb import get_AI_move
return get_AI_move(grid)
class _ComputerPlayer(_Player):
_DIFFICULTY = 5
def __init__(self, color,_DIFFICULTY=5):
super(_ComputerPlayer, self).__init__(color)
self._DIFFICULTY = _DIFFICULTY
self._type = "IA"
def get_move(self, grid):
return 4
There's still too much code to go all the way through, but at least one thing is suspicious. You start the game with a module-level call to ConnectFour in ConnectFourAIb.py. But your _HumanPlayer.get_move method imports ConnectFourAIb again; this will re-trigger the two lines at the end of that file.
To fix this, use the if __name__ == '__main__' trick:
if __name__ == '__main__':
game = ConnectFour()
game.start_new()
This ensures that those lines are only called when the file is run from the command line, not when it is imported.
(As an aside, please drop all those leading underscores. They don't add anything and just make your code harder to read.)
I'm running a python (2.7) Tkinter GUI application on Mac OS X (10.7 and 10.8). The UI is in a separate process that gets forked off from the main script using multiprocessing. When I run, however, it fails with:
'The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec(). Break on THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY_YOU_MUST_EXEC__() to debug.'
This works on Windows just fine.
I've found a bug related to it logged with python: http://bugs.python.org/issue8713
But sadly, it looks like the fix was only implemented in 3.x versions but I need to support 2.7 as well.
I know there's a few other SO questions regarding the same error, like this: Python multiprocessing bug on Mac OS X
But I've not been able to figure out what would actually fix the issue in my particular case.
Any thoughts on how to get this to work on Mac?
Code is below. DriverVisualizer() is created (in another script), which initializes the UI on another process.
from util import *
from multiprocessing import Process, Pipe
from Tkinter import *
import threading
import Queue
from time import *
class VisualizerUI:
def __init__(self, conn, count, pixelSize):
self._conn = conn
self._master = Tk()
self._q = Queue.Queue()
self._count = count
self._values = []
self._leds = []
self._pixelSize = pixelSize
self._pixelPad = int(pixelSize / 2)
self._pixelSpace = 4
#init colors to all black (off)
for i in range(self._count):
self._values.append("#000000")
self.initUI()
self._thread = threading.Thread(target=self.commThread).start()
def mainloop(self):
self._master.mainloop()
try:
self._conn.send({"status" : False})
except:
pass
def updateUI(self):
try:
for i in range(self._count):
self._canvas.itemconfig(self._leds[i], fill=self._values[i])
except TclError:
#Looks like the UI closed!
pass
def commThread(self):
data = None
error = False
while True:
#bit of a hack, but need to check occasionaly for window size change
if self._width != self._master.winfo_width() or self._height != self._master.winfo_height():
self._width = self._master.winfo_width()
self._height = self._master.winfo_height()
self._master.after_idle(self.layoutPixels)
try:
data = self._conn.recv()
except EOFError:
error = True
break
if data["run"]:
self._values = data["data"]
self.updateUI()
self._conn.send({"status" : True})
else:
break
if not error:
self._conn.send("Killing UI...")
self._master.destroy()
def layoutPixels(self):
self._canvas.config(width=self._width, height=self._height)
newRow = True
x_off = self._pixelPad
y_off = self._pixelPad
for i in range(self._count):
if (x_off + (self._pixelSize * 2) + self._pixelSpace + self._pixelPad) > self._width:
newRow = True
y_off = y_off + self._pixelPad + self._pixelSize
if newRow:
x_off = self._pixelPad
newRow = False
else:
x_off = x_off + self._pixelSize + self._pixelSpace
self._canvas.coords(self._leds[i], x_off, y_off, x_off + self._pixelSize, y_off + self._pixelSize)
y = (y_off + self._pixelSize + self._pixelPad)
if self._height != y:
self._master.geometry("{0}x{1}".format(self._width, y))
self._master.update()
def __CancelCommand(event=None):
pass
def initUI(self):
m = self._master
m.protocol('WM_DELETE_WINDOW', self.__CancelCommand)
m.title("LED Strip Visualizer")
m.geometry("1400x50")
m.update()
self._width = m.winfo_width()
self._height = m.winfo_height()
m.minsize(self._width, self._height)
self._canvas = Canvas(self._master, background="#000000")
c = self._canvas
c.pack(side=TOP)
for i in range(self._count):
index = c.create_oval(0,0,self._pixelSize,self._pixelSize, fill=self._values[i])
self._leds.append(index)
#m.bind("<Configure>", self.resize)
self.layoutPixels()
def toHexColor(r,g,b):
return "#{0:02x}{1:02x}{2:02x}".format(r,g,b)
def startUI(conn, count, pixelSize):
ui = VisualizerUI(conn, count, pixelSize)
ui.mainloop()
class DriverVisualizer(object):
"""Main driver for Visualizer UI (for testing)"""
def __init__(self, leds, pixelSize = 15, showCurrent = False):
self.leds = leds
self._showCurrent = showCurrent
if self._showCurrent:
self._peakCurrent = 0;
else:
self._peakCurrent = None
self._parent_conn, self._child_conn = Pipe()
p = Process(target=startUI, args=(self._child_conn, self.leds, pixelSize))
p.start()
sleep(0.5) # give the UI some time to spin up before throwing data at it
def __del__(self):
self._parent_conn.send({"data" : None, "run" : False})
print self._parent_conn.recv()
def calcCurrent(self, data):
c = 0
for r, g, b in data:
c = c + int(((r/255.0) * 20.0) + ((g/255.0) * 20.0) + ((b/255.0) * 20.0))
if c > self._peakCurrent:
self._peakCurrent = c
return c
#Push new data to strand
def update(self, data):
c = None
if self._showCurrent:
c = self.calcCurrent(data)
self._parent_conn.send({"data" : [toHexColor(*(data[x])) for x in range(self.leds)], "run" : True, "c" : c, "peak" : self._peakCurrent})
resp = self._parent_conn.recv()
if not resp["status"]:
error = True
parent_conn.close()
I run into same problem, check this one:
https://stackoverflow.com/a/19082049/1956309
Which puts you in track to a Tkinter bug here:
http://bugs.python.org/issue5527#msg195480
The solution that did the trick for me (Mac OS 10.8 with Python 2.7) is to rearrange the code so the "import Tkinter" is placed after you have invoked any kind of process.start()
It looks like:
import multiprocessing
def cam_loop(the_q):
while True:
the_q.put('foo in the queue')
def show_loop(the_q):
while True:
from_queue = the_q.get()
print from_queue
if __name__ == '__main__':
try:
the_q = multiprocessing.Queue(1)
cam_process = multiprocessing.Process(target=cam_loop,args=(the_q, ))
cam_process.start()
show_process = multiprocessing.Process(target=show_loop,args=(the_q, ))
show_process.start()
import Tkinter as tk # << Here!
cam_process.join()
show_loop.join()
except KeyboardInterrupt:
cam_process.terminate()
show_process.terminate()
P.d: Thanks JW Lim for showing me good manners!