from collections import OrderedDict
import tkinter as tk
from time import sleep
class StripChart(tk.Frame):
def __init__(self, parent, scale, historySize, trackColors, *args, **opts):
# Initialize
super().__init__(parent, *args, **opts)
self._trackHist = OrderedDict() # Map: TrackName -> list of canvas objID
self._trackColor = trackColors # Map: Track Name -> color
self._chartHeight = scale + 1
self._chartLength = historySize * 2 # Stretch for readability
self._canvas = tk.Canvas(self, height=self._chartHeight + 17,
width=self._chartLength, background='black')
self._canvas.grid(sticky=tk.N + tk.S + tk.E + tk.W)
# Draw horizontal to divide plot from tick labels
x, y = 0, self._chartHeight + 2
x2, y2 = self._chartLength, y
self._baseLine = self._canvas.create_line(x, y, x2, y2, fill='white')
# Init track def and histories lists
self._trackColor.update({'tick': 'white', 'tickline': 'white',
'ticklabel': 'white'})
for trackName in self._trackColor.keys():
self._trackHist[trackName] = [None for x in range(historySize)]
def plotValues(self, **vals):
for trackName, trackHistory in self._trackHist.items():
# Scroll left-wards
self._canvas.delete(trackHistory.pop(0))
# Remove left-most canvas objs
self._canvas.move(trackName, -2, 0)
# Scroll canvas objs 2 pixels left
# Plot the new values
try:
val = vals[trackName]
x = self._chartLength
y = self._chartHeight - val
color = self._trackColor[trackName]
objId = self._canvas.create_line(x, y, x + 1, y, fill=color,
width=3, tags=trackName)
trackHistory.append(objId)
except:
trackHistory.append(None)
def drawTick(self, text=None, **lineOpts):
# draw vertical tick line
x = self._chartLength
y = 1
x2 = x
y2 = self._chartHeight
color = self._trackColor['tickline']
objId = self._canvas.create_line(x, y, x2, y2, fill=color,
tags='tick', **lineOpts)
self._trackHist['tickline'].append(objId)
# draw tick label
if text is not None:
x = self._chartLength
y = self._chartHeight + 10
color = self._trackColor['ticklabel']
objId = self._canvas.create_text(x, y, text=text,
fill=color, tags='tick')
self._trackHist['ticklabel'].append(objId)
def configTrackColors(self, **trackColors):
# Change plotted data color
for trackName, colorName in trackColors.items():
self._canvas.itemconfigure(trackName, fill=colorName)
# Change settings so future data has the new color
self._trackColor.update(trackColors)
if __name__ == '__main__':
top = tk.Tk()
graph = StripChart(top, 100, 300, {'A': 'blue', 'B': 'green', 'C': 'red'})
graph.grid()
val_A = val_B = val_C = 0
delta = [-3, -2, -1, 0, 1, 2, 3] # randomly vary the values by one of these
tickCount = 0
def nextVal(current, lowerBound, upperBound):
from random import choice
current += choice(delta)
if current < lowerBound:
return lowerBound
elif current > upperBound:
return upperBound
else:
return current
def plotNextVals():
global val_A, val_B, val_C, tickCount
if tickCount % 50 == 0:
graph.drawTick(text=str(tickCount), dash=(1, 4))
tickCount += 1
sleep(0.05)
val_A = nextVal(val_A, 0, 99)
val_B = nextVal(val_B, 0, 99)
val_C = nextVal(val_C, 0, 99)
graph.plotValues(A=val_A, B=val_B, C=val_C)
# changeColor = { 800: 'black',
# 1200: 'yellow',
# 1600: 'orange',
# 2000: 'white',
# 2400: 'brown',
# 2800: 'blue' }
# if tickCount in changeColor:
# graph.configTrackColors( A=changeColor[tickCount] )
top.after(1, plotNextVals)
top.after(1, plotNextVals)
top.mainloop()
from tkinter import *
import tkinter.ttk as ttk
root = Tk()
root.title('test')
nb = ttk.Notebook(root)
nb.pack(fill='both', expand='yes')
f1 = Text(root)
f2 = Text(root)
f3 = Text(root)
nb.add(f1, text='page1')
nb.add(f2, text='page2')
nb.add(f3, text='page3')
root.mainloop()
import sys
from random import randint
from PyQt4 import QtCore, QtGui
class Tetris(QtGui.QMainWindow):
def __init__(self):
super(Tetris, self).__init__()
self.tboard = Board(self)
self.setCentralWidget(self.tboard)
self.statusbar = self.statusBar()
self.tboard.msg2Statusbar[str].connect(self.statusbar.showMessage)
self.tboard.start()
self.resize(180, 380)
self.center()
self.setWindowTitle('Tetris')
self.show()
def center(self):
screen = QtGui.QDesktopWidget().screenGeometry()
size = self.geometry()
self.move((screen.width() - size.width()) // 2, (screen.height() - size.height()) // 2)
class Board(QtGui.QFrame):
msg2Statusbar = QtCore.pyqtSignal(str)
BoardWidth, BoardHeight, Speed = 10, 22, 300
EmptyLine = [0] * BoardWidth
geometry = (None,
(((0, 0), (-1, -1), (0, -1), (-1, -2)), ((-1, 0), (0, 0), (0, -1), (1, -1)),
((0, 0), (-1, -1), (0, -1), (-1, -2)), ((-1, 0), (0, 0), (0, -1), (1, -1))),
(((-1, 0), (-1, -1), (0, -1), (0, -2)), ((0, 0), (1, 0), (-1, -1), (0, -1)),
((-1, 0), (-1, -1), (0, -1), (0, -2)), ((0, 0), (1, 0), (-1, -1), (0, -1))),
(((0, 0), (0, -1), (0, -2), (0, -3)), ((-2, -1), (-1, -1), (0, -1), (1, -1)),
((0, 0), (0, -1), (0, -2), (0, -3)), ((-2, -1), (-1, -1), (0, -1), (1, -1))),
(((-1, 0), (0, 0), (1, 0), (0, -1)), ((1, 0), (0, -1), (1, -1), (1, -2)),
((0, 0), (-1, -1), (0, -1), (1, -1)), ((-1, 0), (-1, -1), (0, -1), (-1, -2))),
(((-1, 0), (0, 0), (-1, -1), (0, -1)), ((-1, 0), (0, 0), (-1, -1), (0, -1)),
((-1, 0), (0, 0), (-1, -1), (0, -1)), ((-1, 0), (0, 0), (-1, -1), (0, -1))),
(((0, 0), (1, 0), (0, -1), (0, -2)), ((-1, 0), (0, 0), (1, 0), (1, -1)),
((0, 0), (0, -1), (-1, -2), (0, -2)), ((-1, 0), (-1, -1), (0, -1), (1, -1))),
(((-1, 0), (0, 0), (0, -1), (0, -2)), ((1, 0), (-1, -1), (0, -1), (1, -1)),
((0, 0), (0, -1), (0, -2), (1, -2)), ((-1, 0), (0, 0), (1, 0), (-1, -1))))
def __init__(self, parent):
super(Board, self).__init__(parent)
self.timer = QtCore.QBasicTimer()
self.isWaitingAfterLine = self.isStarted = self.isPaused = False
self.numLinesRemoved = 0
self.setFocusPolicy(QtCore.Qt.StrongFocus)
def start(self):
if self.isPaused:
return
self.isStarted = True
self.isWaitingAfterLine = False
self.numLinesRemoved = 0
self.board = [Board.EmptyLine.copy() for _ in range(Board.BoardHeight)]
self.msg2Statusbar.emit(str(self.numLinesRemoved))
self.newPiece()
self.timer.start(Board.Speed, self)
def paintEvent(self, event):
glass = [l.copy() for l in self.board]
if self.shape:
s, a, X, Y = self.shape
for x, y in self.geometry[s][a]:
glass[y + Y][x + X] = s
h, w = self.contentsRect().height() // Board.BoardHeight, self.contentsRect().width() // Board.BoardWidth
painter = QtGui.QPainter(self)
for y, l in enumerate(glass):
y = self.contentsRect().bottom() - (y + 1) * h
for x, s in enumerate(l):
if s:
x *= w
color = QtGui.QColor(
(None, 0xCC6666, 0x66CC66, 0x6666CC, 0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00)[s])
painter.fillRect(x + 1, y + 1, w - 2, h - 2, color)
painter.setPen(color.light())
painter.drawLine(x, y + h - 1, x, y)
painter.drawLine(x, y, x + w - 1, y)
painter.setPen(color.dark())
painter.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1)
painter.drawLine(x + w - 1, y + h - 1, x + w - 1, y + 1)
def keyPressEvent(self, event):
if not (self.isStarted and self.shape):
super(Board, self).keyPressEvent(event)
return
key = event.key()
if key == QtCore.Qt.Key_P:
self.isPaused ^= True
if self.isPaused:
self.timer.stop()
self.msg2Statusbar.emit('paused')
else:
self.timer.start(Board.Speed, self)
self.msg2Statusbar.emit(str(self.numLinesRemoved))
elif key == QtCore.Qt.Key_Left:
self.nextshape[2] -= 1
self.tryMove()
elif key == QtCore.Qt.Key_Right:
self.nextshape[2] += 1
self.tryMove()
elif key == QtCore.Qt.Key_Down:
self.nextshape[1] = (self.shape[1] + 1) % 4
self.tryMove()
elif key == QtCore.Qt.Key_Up:
self.nextshape[1] = (self.shape[1] + 3) % 4
self.tryMove()
elif key == QtCore.Qt.Key_Space:
self.dropDown()
elif key == QtCore.Qt.Key_D:
self.oneLineDown()
else:
super(Board, self).keyPressEvent(event)
def timerEvent(self, event):
if event.timerId() == self.timer.timerId():
if self.isWaitingAfterLine:
self.isWaitingAfterLine = False
self.newPiece()
else:
self.oneLineDown()
else:
super(Board, self).timerEvent(event)
def dropDown(self):
while self.tryMove():
self.nextshape[3] -= 1
self.pieceDropped()
def oneLineDown(self):
self.nextshape[3] -= 1
if not self.tryMove():
self.pieceDropped()
def pieceDropped(self):
s, a, X, Y = self.shape
for x, y in self.geometry[s][a]:
self.board[y + Y][x + X] = s
self.board = [l for l in self.board if not all(l)]
numFullLines = Board.BoardHeight - len(self.board)
if numFullLines:
for i in range(numFullLines):
self.board.append(Board.EmptyLine.copy())
self.numLinesRemoved += numFullLines
self.msg2Statusbar.emit(str(self.numLinesRemoved))
self.isWaitingAfterLine = True
self.shape = None
self.update()
if not self.isWaitingAfterLine:
self.newPiece()
def newPiece(self):
self.nextshape = [randint(1, 7), 0, Board.BoardWidth // 2, Board.BoardHeight - 1]
if not self.tryMove():
self.shape = None
self.timer.stop()
self.isStarted = False
self.msg2Statusbar.emit("Game over")
def tryMove(self):
s, a, X, Y = self.nextshape
for x, y in self.geometry[s][a]:
x += X
y += Y
if not (0 <= x < Board.BoardWidth and 0 <= y) or self.board[y][x]:
self.nextshape = self.shape.copy()
return False
self.shape = self.nextshape.copy()
self.update()
return True
if __name__ == '__main__':
app = QtGui.QApplication([])
tetris = Tetris()
sys.exit(app.exec_())
from random import random
from bisect import bisect_left
data = {"Вася": 2,
"Петя": 3,
"Кузя": 5}
scalefactor = sum(data.values())
names, scale = [], [0.]
for name, weight in data.items():
names.append(name)
scale.append(scale[-1] + weight / scalefactor)
# посмотрим, хорошо ли работает
counter = {name: 0 for name in names}
for i in range(10000):
x = random()
idx = bisect_left(scale, x) - 1
name = names[idx]
counter[name] += 1
print(counter)
>>> from itertools import chain
>>> def f(val):
... return "Hi"
...
>>> list(chain.from_iterable((a, f(a)) for a in [1, 2, 3]))
[1, 'Hi', 2, 'Hi', 3, 'Hi']