Switch on the fill between plots only if a condition is met - if-statement

Ok. So I'm trying to make a switch for the fill in between the plots.
So that way, the fill doesn't always show up but only when I want it, and only between the plots I want, not all the ones that are there.
The first step, I thought, was to make a switch for the fill-- true or false. And then use the "if" later, as shown below.
//#version=3
study("fill ema test")
//---input switches for the emas
ei8 = input(true, title="ema 8")
ei100 = input(true, title="ema 100")
ei200 = input(true, title="ema 200")
//---input switch attempts for the fills.
// ef8 = input(false, title= "fill e8/e100")
// ef100 = input(false, title= "fill e100/e200")
// ef200 = input(false, title="fill e8/e200")
efp= input(false, title="fill in the emas")
//----ema calc
e8 = ema(close, 8)
e100 = ema(close, 100)
e200 = ema(close, 200)
//----plots. checks if the switch for the emas are on and then plots.
ep8 = plot(ei8 and e8?e8:na, color= e8>=e100? green:red)
ep100 = plot(ei100 and e100?e100:na, color= e100>=e200? blue:purple)
ep200 = plot(ei200 and e200?e200:na, color= gray)
//---- now if i make this if statement here, then i can
if efp
ep8= p8
ep100=p100
ep200=p200
fill(p8, p100, color=teal)
fill(p100, p200, color=olive)
fill(p8, p200, color=green)
That throws errors "Undeclared identifier p8;..." etc....
What am I doing wrong here?
There was another one I worked on, and that threw an error saying "fill cannot be used in local..." etc., something to that effect.
Edit: 9-4-19 as per baris's suggestion. But his idea turns on/off the line plots with the fills entirely, so i've tried putting the switches for the individual fills but that didn't work either.
So still I have problems coming up with a switch that will let me: 1. plot the individual emas, 2. fill the individual emas with another of choosing.
//#version=3
study("fill ema test")
//---input switches for the emas
ei8 = input(true, title="ema 8")
ei100 = input(true, title="ema 100")
ei200 = input(true, title="ema 200")
//----ema calc
e8 = ema(close, 8)
e100 = ema(close, 100)
e200 = ema(close, 200)
//---input switch attempts for the fills. this added to the plot will turn fills on or off but only along with the plots.
// ef8 = input(false, title= "fill e8/e100")
// ef100 = input(false, title= "fill e100/e200")
// ef200 = input(false, title="fill e8/e200")
efp= input(true, title="fill in the emas")
//----plots. checks if the switch for the emas are on and then plots.
ep8 = plot(ei8 and e8 and efp?e8:na, color= e8>=e100? green:red)
ep100 = plot(ei100 and e100 and efp?e100:na, color= e100>=e200? blue:purple)
ep200 = plot(ei200 and e200 and efp?e200:na, color= gray)
fill(ep8, ep100, color=teal)
fill(ep100, ep200, color=olive)
fill(ep8, ep200, color=green)
And doing the following will plot all the lines and fills but turn them both off individually at the same time.
ef8 = input(true, title= "fill e8/e100")
ef100 = input(true, title= "fill e100/e200")
ef200 = input(true, title="fill e8/e200")
// efp= input(true, title="fill in the emas")
//----plots. checks if the switch for the emas are on and then plots.
// ep8 = plot(ei8 and e8 and efp?e8:na, color= e8>=e100? green:red)
// ep100 = plot(ei100 and e100 and efp?e100:na, color= e100>=e200? blue:purple)
// ep200 = plot(ei200 and e200 and efp?e200:na, color= gray)
ep8 = plot(ei8 and e8 and ef8?e8:na, color= e8>=e100? green:red)
ep100 = plot(ei100 and e100 and ef100?e100:na, color= e100>=e200? blue:purple)
ep200 = plot(ei200 and e200 and ef200?e200:na, color= gray)
fill(ep8, ep100, color=teal)
fill(ep100, ep200, color=olive)
fill(ep8, ep200, color=green)
Ideally, the lines can be turned off and on individually, and the fills can also be turned off and on individually.
Is this just some logic problem I have or a limitation of tradingview?

The error message clearly tells you what you are doing wrong. You have not declared these variables: p8, p100 and p200. By looking at your code, you don't need those variables, you can simply use ep8, ep100 and ep200 respectively.
if efp
fill(ep8, ep100, color=teal)
fill(ep100, ep200, color=olive)
fill(ep8, ep200, color=green)
If you do that, you will get the following error:
line 31: Cannot use 'fill' in local scope.;
line 32: Cannot use 'fill'in local scope.;
line 33: Cannot use 'fill' in local scope.
You cannot call fill() (and some other functions) in local scope (if-block here).
What you can do is, simply add your condition to series parameter of your plot() functions.
ep8 = plot(ei8 and e8 and efp?e8:na, color= e8>=e100? green:red)
ep100 = plot(ei100 and e100 and efp?e100:na, color= e100>=e200? blue:purple)
ep200 = plot(ei200 and e200 and efp?e200:na, color= gray)
Note the and efp condition.
So, both together:
//----plots. checks if the switch for the emas are on and then plots.
ep8 = plot(ei8 and e8 and efp?e8:na, color= e8>=e100? green:red)
ep100 = plot(ei100 and e100 and efp?e100:na, color= e100>=e200? blue:purple)
ep200 = plot(ei200 and e200 and efp?e200:na, color= gray)
//---- now if i make this if statement here, then i can
fill(ep8, ep100, color=teal)
fill(ep100, ep200, color=olive)
fill(ep8, ep200, color=green)

fill(p8, p100, color=efp ? teal : na)
fill(p100, p200, color=efp ? olive : na)
fill(p8, p200, color=efp ? green : na)

Related

Trying to modify a code to capture an image every 15 minutes or so (time lapse)

Below code was taken from an existing post by Kieleth which I use as a subset of my larger codebase. I'm trying to leverage it to capture a list of frames taken once every thousand+ real time frames and later play in a time-lapse fashion. I've captured the frames but can't seem to view them when calling a simple function. I've seen in other posts that for loops are not recommended for this type of event but haven't figured out how to properly display. Any advise on this one would be appreciated?
from tkinter import ttk
import time
import cv2
from PIL import Image,ImageTk
#import threading
root = Tk()
def video_button1():# this flips between start and stop when video button pressed.
if root.video_btn1.cget('text') == "Stop Video":
root.video_btn1.configure(text = "Start Video")
root.cap.release()
elif root.video_btn1.cget('text') == "Start Video":
root.video_btn1.configure(text = "Stop Video")
root.cap = cv2.VideoCapture(0)
show_frame()
def show_frame():
# if video_btn1.cget('text') == "Stop Video":
global time_lapse_counter
ret, frame = root.cap.read()
if ret:
frame = cv2.flip(frame, 1) #flip image
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image=img) #converts img into tkinter readable format
root.video_label.imgtk = imgtk
if time_lapse_counter >= 20: # for Every 20 frames, capture one into time_lapse_list
time_lapse_list.append(imgtk)
time_lapse_counter = 0
root.video_label.configure(image=imgtk)
if len(time_lapse_list) == 5: # keep only 4 frames in the list *** debug purposes.
time_lapse_list.pop(0)
time_lapse_counter += 1
video_loop = root.after(40, show_frame)
else:
root.video_btn1.configure(text = "Start Video")
def time_lapse_play():
root.cap.release() #stop capturing video.
for image in time_lapse_list:
print (image, " ", len(time_lapse_list)," ",time_lapse_list) #
#*** I see the print of the pyimagexxx but nothing appears on the video***#
imgtk = image
root.video_label.imgtk = imgtk
root.video_label.configure(image=imgtk)
cv2.waitKey(500)
# video_loop = root.after(500, time_lapse_play)
def setup_widgets(): #simple label and 2 button widget setup
#Setup Top Right Window with pictures
f_width, f_height = 810, 475
root.rightframe= Frame(root, border=0, width=f_width, height = f_height)
root.rightframe.grid(row=0, column=0, padx=10, pady=0)
# Show video in Right Frame
root.cap = cv2.VideoCapture(0)
root.cap.set(cv2.CAP_PROP_FRAME_WIDTH, f_width)
root.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, f_height)
root.video_label = Label(root.rightframe)
root.video_label.grid(row=0, column = 0)
root.video_btn1 = Button(root.rightframe, fg='maroon', bg="yellow", text = "Stop Video", font=("Arial",10),height=0, width = 10, command=video_button1)
root.video_btn1.grid(row=0, column = 1)
root.video_btn2 = Button(root.rightframe, fg='maroon', bg="yellow", text="Time Lapse", font=("Arial",10),height=0, width = 10, command=time_lapse_play)
root.video_btn2.grid(row=1, column = 1)
# Main Code
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
screen_resolution = str(screen_width)+'x'+str(screen_height)
root.geometry(screen_resolution)
time_lapse_counter = 0
time_lapse_list=[]
setup_widgets()
show_frame()
root.mainloop()```
I've finally figure this one out. Seems that the for loop effectively doesn't work when using callback. I've modified the code to remove the for loop. I'm sure it could use some improvements but it works. I'm not sure how to reset the image count within the list as pop/append grows the list image number over time and I wonder about an overflow error. i.e after a few minutes, the list will contain [pyimage100 - pyimage200], after a few hours, [pyimage1000000 - pyimage1000100].
from tkinter import *
import cv2
from PIL import Image,ImageTk
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg)
import matplotlib.pyplot as plt
root = Tk()
def video_button1():# this flips between start and stop when video button pressed.
if root.video_btn1.cget('text') == "Stop Video":
root.video_btn1.configure(text = "Start Video")
root.cap.release()
elif root.video_btn1.cget('text') == "Start Video":
root.video_btn1.configure(text = "Stop Video")
root.cap = cv2.VideoCapture(0)
root.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 400)
root.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 400)
show_frame()
def show_frame():
# if video_btn1.cget('text') == "Stop Video":
global time_lapse_counter
ret, frame = root.cap.read()
if ret:
frame = cv2.flip(frame, 1) #flip image
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image=img) #converts img into tkinter readable format
root.video_label.imgtk = imgtk
root.video_label.configure(image=imgtk)
if time_lapse_counter >= 20: # for Every 20 frames, capture one into time_lapse_list
time_lapse_list.append(imgtk)
time_lapse_counter = 0
if len(time_lapse_list) == 100: # keep 99 frames in the list
time_lapse_list.pop(0)
time_lapse_counter += 1
video_loop = root.after(40, show_frame)
else:
root.video_btn1.configure(text = "Start Video")
def time_lapse_play():
root.cap.release() #stop capturing video.
global frame_counter
if frame_counter <= len(time_lapse_list)-1:
imgtk = time_lapse_list[frame_counter] # get image from list
root.video_label.configure(image=imgtk) # update label with image from list
frame_counter += 1
video_loop = root.after(250, time_lapse_play) #wait 250ms until next frame
else:
frame_counter = 0 #reset frame_counter
def setup_widgets(): #simple label and 2 button widget setup
#Setup Top Right Window with pictures
f_width, f_height = 1200, 500
root.rightframe= Frame(root, border=0, width=f_width, height = f_height)
root.rightframe.grid(row=0, column=0, padx=10, pady=0)
# Show video in Right Frame
root.cap = cv2.VideoCapture(0)
root.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 400)
root.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 400)
root.video_label = Label(root.rightframe)
root.video_label.grid(row=0, column = 0)
root.video_btn1 = Button(root.rightframe, fg='maroon', bg="yellow", text =
"Stop Video", font=("Arial",10),height=0, width = 10, command=video_button1)
root.video_btn1.grid(row=0, column = 1)
root.video_btn2 = Button(root.rightframe, fg='maroon', bg="yellow", text="Time Lapse", font=("Arial",10),height=0, width = 10, command=time_lapse_play)
root.video_btn2.grid(row=1, column = 1)
fig = plt.figure(1)
canvas = FigureCanvasTkAgg(fig, root.rightframe)
canvas.get_tk_widget().place(x=700,y=0)
canvas.get_tk_widget().config(border=2, bg="yellow", width=400, height=400)
# Main Code
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
screen_resolution = str(screen_width)+'x'+str(screen_height)
root.geometry(screen_resolution)
time_lapse_counter = 0
frame_counter = 0
time_lapse_list=[]
setup_widgets()
show_frame()
root.mainloop()
`

Sprites not aligning to boundaries correctly

I am creating a basic Pong-style game using Pygame, and I have gotten as far as moving the paddles. I have code that should prevent the paddles from moving beyond the edges of the screen, but if a player holds down a movement key, the paddle moves just slightly past the edge of the screen. Once the player releases the key, the paddle snaps back to where it ought to stop.
I am somewhat new to Python and coding in general, so my code may not be the tidiest or most efficient. While this problem may not affect gameplay at all, I would like to know why it behaves this way and how to change it to how I want it.
My code is:
import random
import pygame
from pygame.locals import *
from sys import exit
screen_size = 600, 600
w,h = screen_size
screen = pygame.display.set_mode(screen_size)
clock = pygame.time.Clock()
pic = pygame.image.load
class paddle(pygame.sprite.Sprite):
def __init__(self, pos):
pygame.sprite.Sprite.__init__(self)
self.pos = pos
self.posx, self.posy = self.pos
self.width = 10
self.height = 100
self.image = pygame.Surface((self.width, self.height))
self.image.fill((255,255,255))
self.rect = pygame.Rect((0,0), self.image.get_size())
self.speed = 150
def update(self, mov, tp):
self.posy += mov * self.speed * tp
self.rect.center = self.posx, self.posy
class box(pygame.sprite.Sprite):
def __init__(self, pos):
pygame.sprite.Sprite.__init__(self)
self.pos = pos
self.posx, self.posy = self.pos
self.width = 10
self.height = 10
self.image = pygame.Surface((self.width, self.height))
self.image.fill((255,255,255))
self.rect = pygame.Rect((0,0), self.image.get_size())
self.speed = 300
self.directionx = 0
self.directiony = 0
def update(self, mov, tp):
self.posx += mov[0] * self.speed * tp
self.posy += mov[1] * self.speed * tp
self.rect.center = self.posx, self.posy
reset = True
done = False
while done == False:
if reset == True:
p1 = paddle((0,0))
p1 = paddle((20,(h-p1.height)/2))
p2 = paddle((0,0))
p2 = paddle((w-20,(h-p2.height)/2))
paddle_group = pygame.sprite.Group()
paddle_group.add(p1)
paddle_group.add(p2)
ball = box(((w/2)-10,h/2))
ball_group = pygame.sprite.Group(ball)
reset = False
else:
pass
time_passed = clock.tick(60)
time_passed_seconds = time_passed/1000.0
for event in pygame.event.get():
if event.type == QUIT:
done = True
p1_movey = 0
p2_movey = 0
pressed_keys = pygame.key.get_pressed()
pressed_mb = pygame.mouse.get_pressed()
if pressed_keys[K_ESCAPE]:
done = True
if pressed_keys[K_w]:
p1_movey = -2
elif pressed_keys[K_s]:
p1_movey = +2
if pressed_keys[K_UP]:
p2_movey = -2
elif pressed_keys[K_DOWN]:
p2_movey = +2
p1.update(p1_movey, time_passed_seconds)
p2.update(p2_movey, time_passed_seconds)
# This is where the border check is
for PADDLE in paddle_group.sprites():
if PADDLE.posy > h - (PADDLE.height/2):
PADDLE.posy = h - (PADDLE.height/2)
elif PADDLE.posy < (PADDLE.height/2):
PADDLE.posy = (PADDLE.height/2)
screen.fill((0,0,0))
paddle_group.draw(screen)
pygame.display.update()
pygame.quit()
The boundary part is marked with a comment.
The problem is that you're correcting each paddle's posy without adjusting its rect at the same time. posx and posy store the location of your sprite-- in this case, it's center-- but the position of what you see on-screen is determined by the rect. Because you add p#_movey, then update (which adjusts the rect), then, finally, make the posy correction for out-of-bounds values, rect remains at it's invalid location. Because you have adjusted posy, though, future p#_movey changes effect the correct location, not the invalid one (which is why your sprite remains O.B. until the movement key is released).
In short, this is what's going on:
Determine p#_movey for each player.
Apply p#_movey to player #'s paddle's posy and rect via update.
Adjust PADDLE.posy to keep it in-bounds for each PADDLE in paddle_group, but do not update PADDLE.rect to reflect the adjustment. (And rect does need to be updated.)
Conclude the frame.
There are two solutions I can think of:
1) Modify your for PADDLE in paddle_group.sprites() loop so that PADDLE.rect.center is refreshed, that it looks something like this:
# on the main loop...
for PADDLE in paddle_group.sprites():
if PADDLE.posy > h - (PADDLE.height/2):
PADDLE.posy = h - (PADDLE.height/2)
elif PADDLE.posy < (PADDLE.height/2):
PADDLE.posy = (PADDLE.height/2)
PADDLE.rect.center = PADDLE.posx, PADDLE.posy
## ^ adding this line, which recenters the rect.
2) Alternatively, you could run the boundary check in paddle's update method and remove the for PADDLE in paddle_group.sprites() loop from the main loop all together. paddle.update(..) would then look something like this:
# in class paddle(..) ...
def update(self, mov, tp):
self.posy += mov * self.speed * tp
self.posy = max(self.height / 2, min(self.posy, h - (self.height / 2)))
## ^ Adding this line, which checks boundaries for posy.
## because you're doing it here, there's no need to do it again on the main loop.
self.rect.center = self.posx, self.posy
... as long as your boundaries are defined by h (screen height; the bottom of your window) and 0 (the top of the window) and the height of the paddle.
Either solution should work, though there are almost certainly third ways, too.
Hope that helps!

DX11 Alpha Blend Object Draw To Render Target

My problem is:
i can't draw an Alpha Blend object into render target with it's blend rightly,
i have a few experience on dx9 but not in dx11 so don't know what i miss in dx11.
please follow images...
Any flag must be set in dx 11 when create render target ? or add any code for blend or..
i don't know what i miss.
thanks.
Check out ID3D11Device::CreateBlendState. For standard alpha blending with preserved alpha, use the following parameters:
AlphaToCoverageEnable = FALSE;
IndependentBlendEnable = FALSE;
BlendEnable[0] = TRUE;
SrcBlend[0] = D3D11_BLEND_SRC_ALPHA;
DestBlend[0] = D3D11_BLEND_INV_SRC_ALPHA;
BlendOp[0] = D3D11_BLEND_OP_ADD;
SrcBlendAlpha[0] = D3D11_BLEND_ONE;
DestBlendAlpha[0] = D3D11_BLEND_INV_SRC_ALPHA;
BlendOpAlpha[0] = D3D11_BLEND_OP_ADD;
RenderTargetWriteMask[0] = D3D11_COLOR_WRITE_ENABLE_ALL;
And don't forget to call ID3D11DeviceContext::OMSetBlendState.

getting the value to the Entry using tkinter

I want to know how to display the values using Entry? i mean for instance if i have a function like:
def open():
path=tkFileDialog.askopenfilename(filetypes=[("Image File",'.jpg')])
blue, green, red = cv2.split(path)
total = path.size
B = sum(blue) / total
G = sum(green) / total
R = sum(red) / total
B_mean1.append(B)
G_mean1.append(G)
R_mean1.append(R)
blue.set(B_mean1)
green.set(G_mean1)
red.set(R_mean1)
root = Tk()
blue_label = Label(app,text = 'Blue Mean')
blue_label.place(x = 850,y = 140)
blue = IntVar(None)
blue_text = Entry(app,textvariable = blue)
blue_text.place(x = 1000,y = 140)
green_label = Label(app,text = 'Green Mean')
green_label.place(x = 850,y = 170)
green = IntVar(None)
green_text = Entry(app,textvariable = green)
green_text.place(x = 1000,y = 170)
red_label = Label(app,text = 'Red Mean')
red_label.place(x = 850,y = 200)
red = IntVar(None)
red_text = Entry(app,textvariable = red)
red_text.place(x = 1000,y = 200)
button = Button(app, text='Select an Image',command = open)
button.pack(padx = 1, pady = 1,anchor='ne')
button.place( x = 650, y = 60)
root.mainloop()
I have specified all the necessary imports and list variables. Still the value is not being displayed in the Entry field.
like if i get the value as :
blue mean = 37,
green mean = 36,
red mean = 41
and it will print in the console but not in the window. How can I achieve this?
Any suggestions are welcome!
Thanks for your supports!
Firstly I want to recommend that instead of using the place method you use the grid method. It is a lot faster and allows you to do things in a much more orderly fashion - especially in this application. Note that there are other geometry managers - like pack - which are good in yet other instances. Anyways, your GUI:
root = Tk()
blue_label = Label(root, text="Blue mean:")
blue_label.grid(row=1, column=1, sticky="w")
blue_entry = Entry(root)
blue_entry.grid(row=1, column=2)
green_label = Label(root, text="Green mean:")
green_label.grid(row=2, column=1, sticky="w")
green_entry = Entry(root)
green_entry.grid(row=2, column=2)
red_label = Label(root, text="Red mean:")
red_label.grid(row=3, column=1, sticky="w")
red_entry = Entry(root)
red_entry.grid(row=3, column=2)
root.mainloop()
That makes your GUI display nicely and without the manual geometry. Note that sticky just sets how the text is justified ("w" means west, and so the text justifies left).
Now, for actually displaying the text, all you have to do is:
blue_entry.insert(0, "blue-mean-value")
green_entry.insert(0, "green-mean-value")
red_entry.insert(0, "red-mean-value")
And if you are overwriting any text that is already there just do:
blue_entry.delete(0, END) # And green_entry and red_entry

cocos2d remove tint

I'm trying to implement a highlight animation to my sprites. The sprite should highlight to a given color and gradually reverse back to its original colors, with the following code:
- (void)highlight {
CCTintTo *tintAction = [CCTintTo actionWithDuration:0.1 red:255 green:255 blue:255];
CCTintTo *tintBackAction = [tintAction reverse];
CCSequence *sequence = [CCSequence actions: tintAction, tintBackAction, nil];
[self runAction:sequence];
}
Now this function raises an exception as CCTintTo doesn't seem to implement 'reverse', which makes sense. Is there any other way to implement removal of an added tint over an interval, using a CCAction?
CCSprite's default color is ccWhite, {255, 255, 255}, so if you
want to make sprite lighter, you'll have to subclass CCSprite/write shader to use additive coloring.
Just tint it back:
CCColor3B oldColor = sprite.color;
CCTintTo *tintTo = [CCTintTo actionWithDuration:t red:r green:g blue:b];
CCTintTo *tintBack = [CCTintTo actionWithDuration:t red:oldColor.r green:oldColor.g blue:oldColor.b];
[sprite runAction:[CCSequence actions: tintTo, tintBack, nil]];
You can store previous color before start tint, then just create CCTintTo with initial RGB values.
For Cocos2dx (C++)
ccColor3B oldColor = sprite->getColor();
CCTintTo* action = CCTintTo::create(0.5f, 127, 255, 127);
CCTintTo* actionReverse = CCTintTo::create(0.5f, oldColor.r, oldColor.g, oldColor.b);;
sprite->runAction(CCSequence::create(action, actionReverse, NULL));
Works fine Kreiri, thanks! I already gave a plus to you:).