I am trying to make a counter so if I type 'bye' it starts counting how long it has been since I said bye but the problem is that I can't type anything to stop the counter and I don't know how to have it tell you something when you type something to stop it. Here is my code for a counter but I tried to type something and it does not stop:
import time
s = 0
m = 0
h = 0
while s<=60:
print h, 'Hours', m, 'Minutes', s, 'Seconds'
time.sleep(1)
s+=1
if s == 60:
m+=1
s = 0
elif m ==60:
h+=1
m = 0
s = 0
Consider using threading.Thread:
import time
import threading
class MyTimer(threading.Thread):
def __init__(self):
self.h = 0
self.m = 0
self.s = 0
def count(self, t, stop_event):
while self.s <= 60:
print self.h, 'Hours', self.m, 'Minutes', self.s, 'Seconds'
time.sleep(1)
self.s += 1
if self.s == 60:
self.m += 1
self.s = 0
elif self.m == 60:
self.h += 1
self.m = 0
self.s = 0
elif stop_event.is_set():
print self.h, 'Hours', self.m, 'Minutes', self.s, 'Seconds'
break
class Asking(threading.Thread):
def asking(self, t, stop_event):
while not stop_event.is_set():
word = raw_input('enter a word:\n')
if word == 'bye':
timer_stop.set()
question_stop.set()
timer = MyTimer()
question = Asking()
question_stop = threading.Event()
timer_stop = threading.Event()
threading.Thread(target=question.asking, args=(1, question_stop)).start()
threading.Thread(target=timer.count, args=(2, timer_stop)).start()
Running it as an example:
$ python stackoverflow.py
enter a word:
0 Hours 0 Minutes 0 Seconds
0 Hours 0 Minutes 1 Seconds
0 Hours 0 Minutes 2 Seconds
0 Hours 0 Minutes 3 Seconds
hi
enter a word:
0 Hours 0 Minutes 4 Seconds
0 Hours 0 Minutes 5 Seconds
0 Hours 0 Minutes 6 Seconds
bye
0 Hours 0 Minutes 7 Seconds
The code could probably be a bit more neater :p. I shocked myself that I was able to produce this :D.
The only way I know is with pygame. It would set up a normal pygame loop, except having it only being 1 by 1, so you can see the background window, and when you enter in a letter it would exit the pygame loop.
maybe better...
.....
.....
while self.s <= 60:
print self.h, 'Hours', self.m, 'Minutes', self.s, 'Seconds'
time.sleep(1)
self.s += 1
if self.s == 60:
self.m += 1
self.s = 0
if self.m == 60:
self.h += 1
self.m = 0
elif stop_event.is_set():
print self.h, 'Hours', self.m, 'Minutes', self.s, 'Seconds'
break
......
......
Related
I will be grateful for help with the above-stated error message from running my pyomo script file - "pyomo solve Katrina_Model5.py Katrina_paper.dat --solver=gurobi --summary --stream-solver --report-timing" at the command prompt. I am still new to the software. I have included full code and data file to aid with your help.
Below is the entire syntax of my problem below:
from pyomo.environ import *
#--define the mode:
model = AbstractModel()
#--declaring parameters:
model.n = Param(within=PositiveIntegers, doc='total no. of depots & afected areas')
model.L = Param(within=PositiveIntegers, doc='Max. no. of nodes a salesman may visit')
model.K = Param(initialize=2, within=PositiveIntegers, doc='Min. no. of nodes a salesman may visit')
#model.m = Param(within=PositiveIntegers, doc='no. of initial salesmen positioned at depot i &j')
#--declare model sets names:
model.I = RangeSet(model.n, name='Set of Origin/intermediary nodes')
model.J = RangeSet(model.n, name='Set of affected areas/destination nodes')
model.A = model.I*model.J
model.D = RangeSet(2, name='Set of depots comprises first d nodes of Set V')
model.U = RangeSet(3,5, name='Set of impacted areas/or customers')
model.V = model.D | model.U
#-- define additional parameters with indexed sets:
model.d = Param(model.I, model.J, doc='Represents cost/travel time matrix.')
#--define model Variables:
model.x = Var(model.I, model.J, within=Binary, name="Var of a salesman traveling.")
model.u = Var(within=RangeSet(2,5), name="no. of nodes visited on traveler's path from origin up to node i")
model.m =Var(model.D, name='no. of initial salesmen positioned at depot i &j')
"""#model's objective function defined.#"""
def objective_rule(model):
return sum(model.d[i,j]*model.x[i,j] for (i,j) in model.A)
model.objective = Objective(rule=objective_rule, sense=minimize, name="Total distance traveled")
"""--Below we define and declare the constraints of the model --"""
#.....constraint # 2
def constrTWO_rule(model, i):
return sum(model.x[i,j] for j in model.U) == m[i]
model.ConsOutTrvler = Constraint(model.D, rule=constrTWO_rule)
#.....constraint # 3
def constrTHREE_rule(model, j):
return sum(model.x[i,j] for i in model.U) == m[j]
model.ConsInTrvler = Constraint(model.D, rule=constrTHREE_rule)
#.....constraint # 4
def constrFOUR_rule(model, j):
return sum(model.x[i,j] for i in model.V) == 1
model.ConsTrvlerInn = Constraint(model.U, rule=constrFOUR_rule)
#.....constraint # 5
def constrFIVE_rule(model, i):
return sum(model.x[i,j] for j in model.V) == 1
model.ConsTrvlerOut = Constraint(model.U, rule=constrFIVE_rule)
#......constraint # 6
def constrSIX_rule(model, i):
return u[i] + (L-2)*sum(model.x[k,i]-model.x[i,k] for k in model.D)-L + 1 <= 0
model.consLowBounds = Constraint(model.U, rule=constrSIX_rule)
#.....constraint # 7
def constrSEVEN_rule(model, i):
return u[i] + sum(model.x[k,i] + (2-K)*model.x[i,k] for k in model.D) >= 2
model.consUpBounds = Constraint(model.U, rule=constrSEVEN_rule)
#.....constraint # 8 ---DOUBLE-CHECK FORMULATION
def constrEIGHT_rule(model, k, i):
return model.x[k,i] + model.x[i,k] <= 1
model.consNotOneAffArea = Constraint(model.D, model.U, rule=constrEIGHT_rule)
#.....constraint # 9 ---DOUBLE-CHECK FORMULATION
def constrNINE_rule(model, i, j):
return ( u[i] - u[j] + L*x[i,j] + (L-2)*x[i,j] ) <= L-1
model.consSubTourElim = Constraint(model.U, rule=constrNINE_rule)
And, here are the '.dat' data file used:
param n := 5 ;
param L := 5 ;
param K := 2 ;
param d: 1 2 3 4 5 :=
1 0 8 4 9 9
2 8 0 6 7 10
3 4 6 0 5 6
4 9 7 5 0 4
5 9 10 6 4 0 ;
I have a sample Pandas data frame as follows:
Action Comedy Crime Thriller SciFi
1 0 1 1 0
0 1 0 0 1
0 1 0 1 0
0 0 1 0 1
1 1 0 0 0
I would like to plot the data-set using Python(Preferably by using matplotlib) in such a way that each of the columns will be a separate axis. Hence in this case, there will be 5 axis (Action, Comedy, Crime...) and 5 data points (since it has 5 rows).
Is it possible to plot this kind of multi-axis data using python matplotlib? If its not possible, what would be the best solution to visualize this data?
RadarChart
Having several axes could be accomplished using a RadarChart. You may adapt the Radar Chart example to your needs.
u = u"""Action Comedy Crime Thriller SciFi
1 0 1 1 0
0 1 0 0 1
0 1 0 1 0
0 0 1 0 1
1 1 0 0 0"""
import io
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.path import Path
from matplotlib.spines import Spine
from matplotlib.projections.polar import PolarAxes
from matplotlib.projections import register_projection
def radar_factory(num_vars, frame='circle'):
theta = np.linspace(0, 2*np.pi, num_vars, endpoint=False)
theta += np.pi/2
def draw_poly_patch(self):
verts = unit_poly_verts(theta)
return plt.Polygon(verts, closed=True, edgecolor='k')
def draw_circle_patch(self):
return plt.Circle((0.5, 0.5), 0.5)
patch_dict = {'polygon': draw_poly_patch, 'circle': draw_circle_patch}
def unit_poly_verts(theta):
x0, y0, r = [0.5] * 3
verts = [(r*np.cos(t) + x0, r*np.sin(t) + y0) for t in theta]
return verts
class RadarAxes(PolarAxes):
name = 'radar'
RESOLUTION = 1
draw_patch = patch_dict[frame]
def fill(self, *args, **kwargs):
"""Override fill so that line is closed by default"""
closed = kwargs.pop('closed', True)
return super(RadarAxes, self).fill(closed=closed, *args, **kwargs)
def plot(self, *args, **kwargs):
"""Override plot so that line is closed by default"""
lines = super(RadarAxes, self).plot(*args, **kwargs)
for line in lines:
self._close_line(line)
def _close_line(self, line):
x, y = line.get_data()
if x[0] != x[-1]:
x = np.concatenate((x, [x[0]]))
y = np.concatenate((y, [y[0]]))
line.set_data(x, y)
def set_varlabels(self, labels):
self.set_thetagrids(np.degrees(theta), labels)
def _gen_axes_patch(self):
return self.draw_patch()
def _gen_axes_spines(self):
if frame == 'circle':
return PolarAxes._gen_axes_spines(self)
spine_type = 'circle'
verts = unit_poly_verts(theta)
# close off polygon by repeating first vertex
verts.append(verts[0])
path = Path(verts)
spine = Spine(self, spine_type, path)
spine.set_transform(self.transAxes)
return {'polar': spine}
register_projection(RadarAxes)
return theta
df = pd.read_csv(io.StringIO(u), delim_whitespace=True)
N = 5
theta = radar_factory(N, frame='polygon')
fig, ax = plt.subplots(subplot_kw=dict(projection='radar'))
colors = ['b', 'r', 'g', 'm', 'y']
markers = ["s", "o","P", "*", "^"]
ax.set_rgrids([1])
for i,(col, row) in enumerate(df.iterrows()):
ax.scatter(theta, row, c=colors[i], marker=markers[i], label=col)
ax.fill(theta, row, facecolor=colors[i], alpha=0.25)
ax.set_varlabels(df.columns)
labels = ["Book {}".format(i+1) for i in range(len(df))]
ax.legend(labels*2, loc=(0.97, .1), labelspacing=0.1, fontsize='small')
plt.show()
heatmap
An easy and probably more readable way to visualize the data would be a heatmap.
u = u"""Action Comedy Crime Thriller SciFi
1 0 1 1 0
0 1 0 0 1
0 1 0 1 0
0 0 1 0 1
1 1 0 0 0"""
import io
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv(io.StringIO(u), delim_whitespace=True)
print df
plt.matshow(df, cmap="gray")
plt.xticks(range(len(df.columns)), df.columns)
plt.yticks(range(len(df)), range(1,len(df)+1))
plt.ylabel("Book number")
plt.show()
Here is a nice simple visualization that you can get with a bit of data manipulation and Seaborn.
import seaborn as sns
# df is a Pandas DataFrame with the following content:
# Action Comedy Crime Thriller SciFi
# 1 0 1 1 0
# 0 1 0 0 1
# 0 1 0 1 0
# 0 0 1 0 1
# 1 1 0 0 0
df = ...
# Give name to the indices for convenience
df.index.name = "Index"
df.columns.name = "Genre"
# Get a data frame containing the relevant genres and indices
df2 = df.unstack()
df2 = df2[df2 > 0].reset_index()
# Plot it
ax = sns.stripplot(x="Genre", y="Index", data=df2)
ax.set_yticks(df.index)
And you get:
For fine tuning you can check the documentation of sns.stripplot.
I am trying to display a value by increasing it incrementally until the desired value is reached.
I have tried two ways of doing it and neither works.
def temperature_gauge(self):
self.dT = self.dU.get() / (float(self.entry_m.get()) * float(self.entry_Cv.get()))
self.counter = 0
while self.counter >= 0:
self.c.delete(self.L2)
self.L2 = self.c.create_text(90,345, text=self.counter)
self.c.update()
self.counter += 1.00
if self.counter == float(self.dT):
break
def temperature_gauge(self):
self.dT = self.dU.get() / (float(self.entry_m.get()) * float(self.entry_Cv.get()))
self.counter = 0
for i in range(0, int(self.dT)):
self.number_text = self.c.create_text(90,345, text=(i))
self.c.update()
time.sleep(0.1)
self.c.delete(self.number_text)
I wrote a code in CodeSkultor, which made use of Simplegui module but that's not available in Python 2.7, obviously. I know we can make use of SimpleGUICS2Pygame module and I have set it up along with pygame but the below code for a simple Guess the Number game still doesn't seem to display the graphics. Couldn't attach a screenshot. Any ideas, anyone? Link to CodeSkultor program is here - http://www.codeskulptor.org/#user40_G13NSFMPzs_4.py
try:
import simplegui
except ImportError:
import SimpleGUICS2Pygame.simpleguics2pygame as simplegui
#import simpleplot
# define global variables
n = 0
min = 0
sec = 0
tenth_sec = 0
is_running = False
count_stop = 0
count_success_stop = 0
# define helper function format that converts time
# in tenths of seconds into formatted string A:BC.D
def format(t):
global sec
global tenth_sec
global min
#global is_running
sec = int (t / 10)
tenth_sec = t % 10
min = int (t / 600)
#return sec
if sec < 10:
return str(min) + ":0" + str(sec) + ":" + str(tenth_sec)
elif sec >= 10 and sec <= 59:
return str(min) + "0:" + str(sec) + ":" + str(tenth_sec)
elif sec >= 60:
sec = sec % 60
if sec >=10:
return str(min) + ":" + str(sec) + ":" + str(tenth_sec)
else:
return str(min) + ":" + "0" + str(sec) + ":" + str(tenth_sec)
#is_running = True
# define event handlers for buttons; "Start", "Stop", "Reset"
def button_start():
global count_start
global is_running
global check
timer.start()
is_running = True
check = True
def button_stop():
global count_stop
global count_success_stop
if timer.is_running():
count_stop += 1
if tenth_sec == 0:
count_success_stop += 1
timer.stop()
def button_reset():
global n
global count_stop
global count_success_stop
n = 0
count_stop = 0
count_success_stop = 0
timer.stop()
# define event handler for timer with 0.1 sec interval
def timer_handler():
global n
n = n + 1
#print n
# define draw handler
def draw_handler(canvas):
canvas.draw_text(format(n),[120,150],30,"Black")
canvas.draw_text(str(count_stop),[230,40],20,"Green")
canvas.draw_text("/",[250,40],20,"Green")
canvas.draw_text(str(count_success_stop),[265,40],20,"Green")
# create frame
# register event handlers
frame = simplegui.create_frame("Stopwatch", 300, 300)
frame.add_button("Start",button_start)
frame.add_button("Stop",button_stop)
frame.add_button("Reset",button_reset)
timer = simplegui.create_timer(100, timer_handler)
# start frame
frame.start()
frame.set_draw_handler(draw_handler)
You must start the frame at the end.
See https://simpleguics2pygame.readthedocs.io/en/latest/Compatibility.html
"With SimpleGUICS2Pygame, Frame.start() is blocking until Frame.stop() execution or closing window. So timers must be started before, and states must be initialized before. (Or maybe after by a handler function.)"
I have this method for my NBA basketball game simulation. The method checks with a variable named self.quarterMins to tell if the minutes in the quarter are done. Then it changes the index for 2 different variables that I use in my code to tell what quarter is being played.
def checkQuarter(self):
# Method that checks and makes sure that the quarter and game aren't over.
self.quarterIndex = 0
if self.quarterMins[0] > 0:
self.quarterIndex = 0
self.playerMins = -4
elif self.quarterMins[1] > 0:
self.quarterIndex = 1
self.playerMins = -3
elif self.quarterMins[2] > 0:
self.quarterIndex = 2
self.playerMins = -2
elif self.quarterMins[3] > 0:
self.quarterIndex = 3
self.playerMins = -1
else:
return False
The following method would do the same:
def checkQuarter(self):
self.quarterIndex = 0
for i in xrange(4):
if self.quarterMins[i] > 0:
self.quarterIndex = i
self.playerMins = -4 + i
break
else:
return False
This uses a loop to let the variable i go from 0 to 3 and it'll set the self.quarterIndex and self.playMins variables whenever the if statement is true. When that's the case, it'll break out of the for loop using break and the method is done. If it doesn't happen at all then Python will run the else: section that's part of the for loop - that will only run when you don't use break in the for loop.
I'm not necessarily saying the above code is better but it does shorten the logic. You can also write it like this (but I'm also not sure whether that's better):
def checkQuarter(self):
self.quarterIndex = 0
index = None
for i in xrange(4):
if self.quarterMins[i] > 0:
index = i
break
if index is None:
return False
self.quarterIndex = index
self.playerMins = -4 + index
I probably would have getters for quarterIndex() and playerMins() and don't store any values for those variables. Then you don't need to implement checkQuarter() to update variables. I find that this method would have the potential to introduce bugs if it doesn't get called the right time.
I would also reverse checking the quarterMins, because then your code assumes to use always the highest quarter, even if the other quarters still have values > 0.
def quarterIndex():
for i in range(4,-1,-1):
if self.quarterMins[i] > 0:
return i
return None
def playerMins():
quarterIndex = quarterIndex()
if (quarterIndex != None):
return -4 + quarterIndex
return None
def gameIsRunning():
if (quarterIndex() != None):
return True
return False
I do this (you can use range too)
def checkQuarter(self):
self.quarterIndex = 0
for i, item in enumerate(self.quarterMins):
if item > 0:
self.quarterIndex = i
self.playerMins = i - 4
if self.quarterIndex == 0:
return False