How to remove list element using while loop - python-3.x

I open a web page to get the names of the cluster1(p1, p2). I am not sure how many times I need to open a web page to get these cluster1 names. So, I am using a while loop, it will remove the p1 or p2 whichever the value is obtained from web page.
When I open a web page, I'll get p1 or p2 and that value will be stored in new[-1]. If this value is in cluster1, it will execute the other test functions and that value will be removed from cluster1.
new = ['some', 'list' 'items', 'p1'] # last element of list is either p1 or p2. So, new[-1] will give p1 or p2.
cluster1 =[ 'p1', 'p2']
while len(cluster1) != 0:
print("Length of cluster1 before:", len(cluster1))
# for i in range(10):
if new[-1] in cluster1:
print(new[-1] + " is in cluster1.")
test1()
test2()
new_ver_names.append(new[-1])
cluster1.remove(new[-1])
print("Length of cluster1 after:", len(cluster1))
else:
print(new[-1] + " portal version is not listed.")
driver.quit()
break
My exception is, when value is removed, control should go back to while loop and start again until len(cluster1) is 0. And, if the value is not in cluster1, else past should execute. But, when I remove cluster1.remove(new[-1]), else part also gets executed.
I checked other answers where it is mentioned we can't remove items from a list while iterating over it and tried list comprehension. But, couldn't make it work.
I tried lst = [(teset1(), test2()) for i in range(len(cluster1)) if new[-1] in cluster1]
Any help is really appreciated.
Thank you.
Edit:
def login1():
ChromeDriver = 'C:\\PortalTesting\\Drivers\\chromedriver.exe'
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument("--incognito")
chrome_options.add_argument("--window-size=1920x1080")
driver = webdriver.Chrome(executable_path=ChromeDriver, chrome_options=chrome_options)
driver.maximize_window()
driver.implicitly_wait(130)
driver.get("MY_URL")
print("session id ", driver.session_id)
username = driver.find_element_by_css_selector("#uid")
username.send_keys("username")
password = driver.find_element_by_css_selector("#pid")
password.send_keys("password")
login_button = driver.find_element_by_class_name("secondarybtnlabel")
login_button.click()
# time.sleep(10)
cluster1 = ['p1', 'p2']
dc_elm = driver.find_element_by_xpath('/html/body/div[4]/div/div[2]/span[2]').text
new = unicodedata.normalize('NFKD', dc_elm).encode('ascii', 'ignore').split()
print("Portal version: ", new[-1])
logout_btn = driver.find_element_by_xpath('/html/body/div[4]/div[2]/div/div[4]/div/div[2]/div/header/div[2]/table/tbody/tr/td[3]/div/li')
logout_btn.click()
driver.delete_all_cookies()
print("Clearing cookies")
new_ver_names = []
time.sleep(3)
while len(cluster1) != 0:
print("Length of cluster1 before:", len(cluster1))
# for i in range(10):
if new[-1] in cluster1:
print(new[-1] + " is in cluster1.")
test1()
test2()
new_ver_names.append(new[-1])
# cluster1.remove(new[-1])
print("Length of cluster1 after:", len(cluster1))
else:
print(new[-1] + " portal version is not listed.")
driver.quit()
break
# cluster1.remove(new[-1])

It is hard (for me) to understand what happens in the current code, but why not try sets?
new = {'some', 'list' 'items', 'p1'}
cluster1 ={'p1', 'p2'}
in_both = new & cluster1
not_found = cluster1 - new
# do stuff with values in `in_both` and `not_found`....

Related

Discord.PY Help Command

Ok, so I'm having an issue with my bot. I know what it is, but I don't know what the string to fix it is.
Basically I have it set to store config and prefixes and such in a json but the help command which is loading one of my commands multiple times.
I've checked the help command and i don't think that's it. Because after redoing my setprefix command (which is being displayed multiple times) it added yet another one on so now it's even worse.
Here is my storage system that I believe to be causing the issue.
with open("./config/config.json", "r") as configjsonFile:
configData = json.load(configjsonFile)
login_token = configData["discordtoken"]
with open("./config/prefixes.json") as f:
prefixes = json.load(f)
default_prefix = "-"
def prefix(client, message):
id = message.guild.id
return prefixes.get(id, default_prefix)
client = commands.Bot(command_prefix=prefix)
client.remove_command('help')
#client.command(name="setprefix", aliases=["Prefix", "prefix"])
#commands.has_permissions(administrator=True)
async def setprefix(ctx, new_prefix):
"""Change the server prefix for the bot.
Alt : Prefix, prefix
Usage : prefix <custom prefix>"""
prefixes[ctx.message.guild.id] = new_prefix
with open("./config/prefixes.json", "w") as f:
json.dump(prefixes, f, indent=4)
embed = discord.Embed(color=0x4a3d9a, timestamp=ctx.message.created_at)
embed.set_author(name=f"{client.user.name}", icon_url=client.user.avatar_url)
embed.add_field(name="Success", value=f"Successfully changed prefix changed to `{new_prefix}`")
embed.set_thumbnail(url=client.user.avatar_url)
embed.set_footer(text="NewHorizon Development | https://newhorizon-development.netlify.app", icon_url=client.user.avatar_url)
await ctx.message.delete()
await ctx.send(embed=embed, delete_after=4)
and here is my custom help command just in case I'm wrong about what is causing the issue.
#commands.command(name="help", aliases=["Help", "H", "h"])
#commands.has_permissions(add_reactions=True, embed_links=True)
async def help(self, ctx, *cog):
"""Gets all cogs and commands.
Alt : h, H, Help
Usage : [h]elp <cog or command>"""
try:
if not cog:
"""Cog listing. What more?"""
embed = discord.Embed(title='Cog Listing and Uncatergorized Commands',
description='Use `help <cog>` to find out more about them!\n(BTW, the Cog Name Must Be in Title Case, Just Like this Sentence.)')
cogs_desc = ''
for x in self.client.cogs:
cogs_desc += ('{} - {}'.format(x, self.client.cogs[x].__doc__) + '\n')
embed.add_field(name='Cogs', value=cogs_desc[0:len(cogs_desc) - 1], inline=False)
cmds_desc = ''
for y in self.client.walk_commands():
if not y.cog_name and not y.hidden:
cmds_desc += ('{} - {}'.format(y.name, y.help) + '\n')
embed.add_field(name='Uncatergorized Commands', value=cmds_desc[0:len(cmds_desc) - 1], inline=False)
await ctx.message.add_reaction(emoji='✉')
await ctx.message.author.send('', embed=embed)
else:
"""Helps me remind you if you pass too many args."""
if len(cog) > 1:
embed = discord.Embed(title='Error!', description='That is way too many cogs!', color=discord.Color.red())
await ctx.message.author.send('', embed=embed)
else:
"""Command listing within a cog."""
found = False
for x in self.client.cogs:
for y in cog:
if x == y:
embed = discord.Embed(title=cog[0] + ' Command Listing', description=self.client.cogs[cog[0]].__doc__)
for c in self.client.get_cog(y).get_commands():
if not c.hidden:
embed.add_field(name=c.name, value=c.help, inline=False)
found = True
if not found:
"""Reminds you if that cog doesn't exist."""
embed = discord.Embed(title='Error!', description='How do you even use "' + cog[0] + '"?', color=discord.Color.red())
else:
await ctx.message.add_reaction(emoji='✉')
await ctx.message.author.send('', embed=embed)
except:
await ctx.send("Excuse me, I can't send embeds.")
I am using the rewrite branch if it helps. And my setprefix command IS NOT in a cog, unlike the rest of my commands. Thus why they appear a slight bit different.
Now I'm ASSUMING my issue is that the json are not closing, which I need to know how to make them close, but if that's not the issue, I would very much appreciate someone helping me figure out what's going wrong.

How to pick out the second to last line from a telnet command

like the many other threads I've opened, I am trying to create a multi-feature instant replay system utilizing the blackmagic hyperdeck which operates over Telnet. The current feature I am trying to implement is an in-out replay which requires storing two timecode variables in the format of hh:mm:ss;ff where h=hours, m=minutes, s=seconds, and f=frames #30fps. the telnet command for this is transport info, and the response returns 9 lines of which I only want the timecode from the 7th. Any idea on how to do this, as it is way out of my league?
status: stopped
speed: 0
slot id: 1
clip id: 1
single clip: false
display timecode: 00:00:09;22
timecode: 00:00:09;22
video format: 1080i5994
loop: false
Here's ideally what I would like it to look like
import telnetlib
host = "192.168.1.13" #changes for each device
port = 9993 #specific for hyperdecks
timeout = 10
session = telnetlib.Telnet(host, port, timeout)
def In():
session.write(b"transport info \n")
line = session.read_until(b";00",.5)
print(line)
#code to take response and store given line as variable IOin
def out():
session.write(b"transport info \n")
line = session.read_until(b";00",.5)
print(line)
#code to take response and store given line as variable IOout
def IOplay():
IOtc = "playrange set: in: " + str(IOin) + " out: " + str(IOout) + " \n"
session.write( IOtc.encode() )
speed = "play: speed: " + str(Pspeed.get() ) + "\n"
session.write(speed.encode() )
For the most part here's what I got to at least partially work
TCi = 1
TCo = 1
def In():
global TCi
session.write(b"transport info \n")
by = session.read_until(b";00",.5)
print(by)
s = by.find(b"00:")
TCi = by[s:s+11]
def Out():
global TCo
session.write(b"transport info \n")
by = session.read_until(b";00",.5)
print(by)
s = by.find(b"00:")
TCo = by[s:s+11]
def IOplay():
IOtc = "playrange set: in: " + str(TCi) + " out: " + str(TCo) + " \n"
print(IOtc.encode() )
session.write(IOtc.encode() )
speed = "play: speed: 2 \n"
session.write(speed.encode() )
except that its encoding as
b"playrange set: in: b'00:00:01;11' out: b'00:00:03;10' \n"
rather than
"playrange set: in: 00:00:01;11 out: 00:00:03;10 \n"
I need to get rid of the apostrophe's and b prefix in front of the variables
Any ideas?
def get_timecode(text):
tc = ''
lines = text.split('\r\n')
for line in lines:
var, val = line.split(': ', maxsplit=1)
if var == 'timecode':
tc = val
return tc
You could choose to go directly to lines[6], without scanning,
but that would be more fragile if client got out of sync with server,
or if server's output formatting changed in a later release.
EDIT:
You wrote:
session.write(b"transport info \n")
#code to take response and store given line as variable IOin
You don't appear to be reading anything from the session.
I don't use telnetlib, but the docs suggest you'll
never obtain those nine lines of text if you don't do something like:
expect = b"foo" # some prompt string returned by server that you never described in your question
session.write(b"transport info\n")
bytes = session.read_until(expect, timeout)
text = bytes.decode()
print(text)
print('Timecode is', get_timecode(text))

Python selenium - "No modal dialog is currently open exception in selenium"

I am getting input url's and trying to load it in the browser (Firefox - Updated version). The script has been working for all the url's. Except few URLs return this error
"No modal dialog is currently open"
I tried adding driver.switch_to_alert().accept() but no help. I usually end up closing browser and restart it all over again.
Please find the code :
capabilities = DesiredCapabilities.FIREFOX.copy()
capabilities['marionette'] = True
capabilities['acceptSslCerts'] = True
driver = webdriver.Firefox(capabilities=capabilities)
driver.implicitly_wait(3)
print ("Number of rows to be processed is:" + str(ws1.max_row))
for row in range(2,ws1.max_row+1):
try:
region = ws1["E"+str(row)].value
# Reading Row 'row'
print("Reading row #"+str(row))
url = ws1["C"+str(row)].value
regex = df[df['Country'] == region]['Regex'].values[0]
#Load mainpage or input URL
i = 0
while i < 3:
try:
driver.get("http://"+url)
driver.switch_to_alert().accept()
time.sleep(5)
break
except (TimeoutException,WebDriverException,NoSuchElementException) as e:
print(e,'Retrying...',i+1)
i += 1
Sample URLs :
afilias.info
www.nuwavenow.com
www.IntoTomorrow.com
www.picobrew.com

How to Infinitely Update Labels with while loop tkinter

Hi I have some simple code here. https://pastebin.com/97uuqKQD
I would simply like to add something like this, to the button function, so while the root window is open the datetime and exrates are constantly regotten from the xe website and displayed.
amount = '1'
def continuousUpdate():
while amount == '0':
results()
def results():
#Get xe data put to labels etc here
btnConvert = tk.Button(root, text="Get Exchange Rates",command=continuousUpdate).place(x=5,y=102)
Once I input the two exrates and they then display on there respective labels I would like the program to continuously grab the data from xe over and over again.
Like this code here which runs in IPython no problems,
import requests
from bs4 import BeautifulSoup
from datetime import datetime
amount = '1'
while amount != '0':
t = datetime.utcnow()
url1 = "http://www.xe.com/currencyconverter/convert/" + "?Amount=" + amount + "&From=" + cur1 + "&To=" + cur2
url2 = "http://www.xe.com/currencyconverter/convert/" + "?Amount=" + amount + "&From=" + cur2 + "&To=" + cur1
#url = "http://www.xe.com/currencycharts/" + "?from=" + cur1 + "&to=" + cur2
html_code1 = requests.get(url1).text
html_code2 = requests.get(url2).text
soup1 = BeautifulSoup(html_code1, 'html.parser')
soup2 = BeautifulSoup(html_code2, 'html.parser')
i = i + 1
rate1 = soup1.find('span', {'class', 'uccResultAmount'})
rate2 = soup2.find('span', {'class', 'uccResultAmount'})
print ('#',i, t,'\n', cur1,'-',cur2, rate1.contents[0], cur2,'-',cur1, rate2.contents[0], '\n')
I thought I would just be able to throw the entire results function into a while loop function then simply call that function but no luck any help would be appreciated.???
Put this at the end of your results function without the while loop:
after_id = root.after(milliseconds,results)
This way it just keeps running itself after that time you specified. And this code will cancel it.
root.after_cancel(after_id)
Answering your other question in the comments:
To make a cancel button make sure after_id is global. Also if the time you specify is very low (very fast recall) it might restart again before you can cancel it. So to be safe better make a global boolean and put .after in an if boolean==True. And you can set that boolean to False whenever you hit cancel button or to True whenever you hit the start button, here's how you can do it:
# button_call default will be True so if you click on the button
# this will be True (no need to pass var through). You can use this to set
# your restart boolean to True
def func(button_call=True):
global restart
global after_id
if button_call:
restart = True
if restart:
after_id = root.after(ms,lambda: func(button_call=False) )
# This way you know that func was called by after and not the button
Now you can put this in your cancel button function:
def cancel():
global restart
global after_id
root.after_cancel(after_id)
restart = False
Let me know if this works (haven't tested it myself).

Unknown column added in user input form

I have a simple data entry form that writes the inputs to a csv file. Everything seems to be working ok, except that there are extra columns being added to the file in the process somewhere, seems to be during the user input phase. Here is the code:
import pandas as pd
#adds all spreadsheets into one list
Batteries= ["MAT0001.csv","MAT0002.csv", "MAT0003.csv", "MAT0004.csv",
"MAT0005.csv", "MAT0006.csv", "MAT0007.csv", "MAT0008.csv"]
#User selects battery to log
choice = (int(input("Which battery? (1-8):")))
def choosebattery(c):
done = False
while not done:
if(c in range(1,9)):
return Batteries[c]
done = True
else:
print('Sorry, selection must be between 1-8')
cfile = choosebattery(choice)
cbat = pd.read_csv(cfile)
#Collect Cycle input
print ("Enter Current Cycle")
response = None
while response not in {"Y", "N", "y", "n"}:
response = input("Please enter Y or N: ")
cy = response
#Charger input
print ("Enter Current Charger")
response = None
while response not in {"SC-G", "QS", "Bosca", "off", "other"}:
response = input("Please enter one: 'SC-G', 'QS', 'Bosca', 'off', 'other'")
if response == "other":
explain = input("Please explain")
ch = response + ":" + explain
else:
ch = response
#Location
print ("Enter Current Location")
response = None
while response not in {"Rack 1", "Rack 2", "Rack 3", "Rack 4", "EV001", "EV002", "EV003", "EV004", "Floor", "other"}:
response = input("Please enter one: 'Rack 1 - 4', 'EV001 - 004', 'Floor' or 'other'")
if response == "other":
explain = input("Please explain")
lo = response + ":" + explain
else:
lo = response
#Voltage
done = False
while not done:
choice = (float(input("Enter Current Voltage:")))
modchoice = choice * 10
if(modchoice in range(500,700)):
vo = choice
done = True
else:
print('Sorry, selection must be between 50 and 70')
#add inputs to current battery dataframe
log = pd.DataFrame([[cy,ch,lo,vo]],columns=["Cycle", "Charger", "Location", "Voltage"])
clog = pd.concat([cbat,log], axis=0)
clog.to_csv(cfile, index = False)
pd.read_csv(cfile)
And I receive:
Out[18]:
Charger Cycle Location Unnamed: 0 Voltage
0 off n Floor NaN 50.0
Where is the "Unnamed" column coming from?
There's an 'unnamed' column coming from your csv. The reason most likely is that the lines in your input csv files end with a comma (i.e. your separator), so pandas interprets that as an additional (nameless) column. If that's the case, check whether your lines end with your separator. For example, if your files are separated by commas:
Column1,Column2,Column3,
val_11, val12, val12,
...
Into:
Column1,Column2,Column3
val_11, val12, val12
...
Alternatively, try specifying the index column explicitly as in this answer. I believe some of the confusion stems from pandas concat reordering your columns .

Resources