datetime in selenium python throwing error - python

Below code gives error as 'friday' no defined. If anything is missing, please help me with the same. Also if I interchange the position of 'friday' and 'prev_day' variables with if else, i get the error message with 'prev_day' not defined.
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import datetime
d = datetime.date.today()
if d.weekday() == 0:
tdelta = datetime.timedelta(days=3)
friday = d - tdelta
elif d.weekday() in range(1,5):
tdelta1 = datetime.timedelta(days=1)
prev_day = d - tdelta1
class ClassName(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome(executable_path="C:\\Users\sameerj\IdeaProjects\chromedriver.exe")
def test_as_on_date(self):
driver = self.driver
driver.maximize_window()
driver.get("website")
login = driver.find_element_by_id("Email")
login.send_keys("email")
password = driver.find_element_by_id("Password")
password.send_keys("password")
password.send_keys(Keys.ENTER)
driver.find_element_by_id("menu_name").click()
driver.find_element_by_partial_link_text("page name").click()
date = driver.find_element_by_id("lblAsOn").text
new = datetime.datetime.strptime(date,'%m/%d/%Y')
data_date = new.date()
if data_date == friday:
print("Data as on", friday, "for page name")
elif data_date == prev_day:
print("Data as on", prev_day, "for page name")
else:
print("Data update required.")
driver.close()
if __name__ == '__main__':
unittest.main()

Its a common type of mistake
let me break it down your mistake
if d.weekday() == 0:
tdelta = datetime.timedelta(days=3)
friday = d - tdelta
elif d.weekday() in range(1,5):
tdelta1 = datetime.timedelta(days=1)
prev_day = d - tdelta1
if we execute your program
if d.weekday() == 0 holds false
then it will go to
elif d.weekday() in range(1,5):
but your friday = d - tdelta is in if condition. that's why its shows error
to solve that you must define friday outside if condition and reassign value in your if condition
you can solve it like this
friday = None
prev_day = None
d = datetime.date.today()
if d.weekday() == 0:
tdelta = datetime.timedelta(days=3)
friday = d - tdelta
elif d.weekday() in range(1,5):
tdelta1 = datetime.timedelta(days=1)
prev_day = d - tdelta1

new = datetime.datetime.strptime(date,'%m/%d/%Y')
data_date = new.strftime("%A")
This will give you the name of the day (Eg: Friday), then you can compare as you are doing,
if data_date == "Friday":
print("Data as on",data_date , "for page name")
And for previous days comparison, you have to do,
tdelta1 = datetime.timedelta(days=1)
prev_day = (new - tdelta1).strftime("%A")
before doing,
elif data_date == prev_day:
print("Data as on", prev_day, "for page name")
When you replaced Friday with prev_day, you are getting the error because of python interpreter is finding that variable first which is not defined.

You better write:
d = datetime.date.today()
if d.weekday() == 0:
tdelta = datetime.timedelta(days=3)
prev_day = None
friday = d - tdelta
elif d.weekday() in range(1, 5):
tdelta1 = datetime.timedelta(days=1)
prev_day = d - tdelta1
friday = None
And my suggestion for you is to use Python IDEs, they highlight such errors.
Also I believe this checks could be done using the calendar module

Related

Cognitive Complexity of functions should not be too high

When I use SonarLint to check code, it notifies Critical that Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.
I use a lot of if else statement, but can not use switch case.
This is my code:
str_time = str_time.lower()
if (bool(re.search(r'\d', str_time)) == True) and ('tối' or 'chiều' in str_time):
day = re.findall(r'\d+', str_time)[0]
if int(day) < datetime.date.today().day:
month = datetime.date.today().month + 1
else:
month = datetime.date.today().month
year = datetime.date.today().year
day = f'{year}-{month}-{day}'
return format_datetime(day)
elif 'hôm nay' in str_time or 'hn' in str_time or 'chiều nay' in str_time or 'tối nay' in str_time:
return format_datetime(datetime.date.today())
elif 'ngày mai' in str_time or 'mai' in str_time:
day = datetime.date.today() + datetime.timedelta(days=1)
elif 'ngày mốt' in str_time or 'mốt' in str_time:
day = datetime.date.today() + datetime.timedelta(days=2)
elif 'thứ 2 tuần sau' in str_time:
num = 7 - datetime.date.today().weekday() + 0
day = datetime.date.today() + datetime.timedelta(days=num)
elif 'thứ 3 tuần sau' in str_time:
num = 7 - datetime.date.today().weekday() + 1
day = datetime.date.today() + datetime.timedelta(days=num)
Sonar lint is right. It seems your code complexity is high. You should create smaller methods or change the logic. But if that is not possible, just ignore the linter.

Print something if the date changes

What exactly I am trying to do here is when Tomorrow comes (00:00) it should print Yes
import datetime
from datetime import date
r = True
rr = True
while r:
Today_Date = date.today()
while rr:
Tomorrow_Date = datetime.date.today() + datetime.timedelta(days=1)
if Today_Date == Tomorrow_Date:
print("Yes")
The way you have it now, your rr while loop will continually run and update Tomorrow_Date, and when the day rolls over, it will update before it has a chance to be compared to Today_Date. You should set both Today_Date and Tomorrow_Date outside that loop, and only update them when the dates change.
This should do the trick:
If you want two loops for other reasons:
import datetime
r = True
while r:
rr = True
Tomorrow_Date = datetime.date.today() + datetime.timedelta(days=1)
while rr:
if datetime.date.today() >= Tomorrow_Date:
print("Yes")
rr = False
Or as a single loop:
import datetime
r = True
Tomorrow_Date = datetime.date.today() + datetime.timedelta(days=1)
while r:
if datetime.date.today() >= Tomorrow_Date:
print("Yes")
Tomorrow_Date = datetime.date.today() + datetime.timedelta(days=1)
It might be a good idea to add a time.sleep() in to slow down the loops, depending on how accurate you need to be also.

trying to get an if statement to be triggered during certain times of day

im fairly new with python but im tring to get a device to turn on for one minute and off for 3 minutes repeatedly from the times of 9am to 5pm and i can't get the if statement to reference the updated time from the loop any help would be greatly appreciated!!!
import datetime
import time
n = "on" #to be replaced with GPIO output
f = "off" #to be replaced with GPIO output
nt = "tis not be the time" #used to see if working or not
tt = "tis be time" #used to see if working or not
now = datetime.datetime.now()
hour = now.hour
def count():
now = datetime.datetime.now()
hour = now.second
total = 1
if hour >= 8 and hour <= 16:
now = datetime.datetime.now()
hour = now.hour
for i in range(1,100):
total = total*2
print (tt)
print (n)
time.sleep(60)
print(f)
time.sleep(180)
now = datetime.datetime.now()
hour = now.second
print (hour)
else :
for i in range(1,100):
now = datetime.datetime.now()
hour = now.hour
print (nt)
print (hour)
time.sleep(10)
count()
You could fix it with a while loop instead, it would look like this, just put all of it inside your function
now = datetime.datetime.now()
hour = now.hour
if hour >= 8 and hour <= 16:
run = True
else:
run = False
while run:
total = total*2
print (tt)
print (n)
time.sleep(60)
print(f)
time.sleep(180)
now = datetime.datetime.now()
hour = now.second
print (hour)
if hour >= 8 and hour <= 16:
run = True
else:
run = False
while run == False:
now = datetime.datetime.now()
hour = now.hour
print (nt)
print (hour)
time.sleep(10)
if hour >= 8 and hour <= 16:
run = True
else:
run = False
Maybe using a while statement. In addition, you have hour = now.second on the second line of the function count and I think it should be hour = now.hour.
See the code with comments:
import datetime
import time
n = "on" #to be replaced with GPIO output
f = "off" #to be replaced with GPIO output
nt = "tis not be the time" #used to see if working or not
tt = "tis be time" #used to see if working or not
#Next lines are redundant, commented out.
#now = datetime.datetime.now()
#hour = now.hour
def count():
now = datetime.datetime.now()
hour = now.hour #now.second
total = 1
while hour >= 8 and hour <= 16:
now = datetime.datetime.now()
hour = now.hour
# for i in range(1,100): -> why you need this?
total = total*2
print (tt)
print (n)
time.sleep(60)
print(f)
time.sleep(180)
now = datetime.datetime.now()
hour = now.hour #now.second
print (hour)
for i in range(1,100): #I don't know why you need a loop here
now = datetime.datetime.now()
hour = now.hour
print (nt)
print (hour)
time.sleep(10)
count()
Edited for correcting another hour = now.second inside the while loop
I don't know how are you planning on running the code, but the main problem I see is that you do not have any loop for your code to run infinitely and check the time condition.
Also it's not clear for me why you need this total variable that gets doubled.
Another thing is your for loops - the condition is not clear. Why do you want to run it in this specific range?
What I would do is I would create an infinite loop and inside it make some decisions based on a clear time conditions - the conditions that are specified by you.
So if I understood your case correctly I'd rather write something like this:
# between 9am to 5pm turn on the device for 60 seconds and off for 180 seconds repeatedly
from datetime import datetime
import time
def update_device_state(state):
# TODO: implement GPIO output code
pass
def run():
device_state = 'off'
new_state = device_state
on_timer = 0
off_timer = time.time() - 180 # initial value must be over 180 seconds to trigger device on a first run
while True:
hour = datetime.now().hour
if 5 <= hour <= 17:
if device_state == 'off' and time.time() - off_timer > 180:
on_timer = time.time()
new_state = 'on'
off_timer = 0
elif device_state == 'on' and time.time() - on_timer > 60:
off_timer = time.time()
new_state = 'off'
on_timer = 0
else:
if device_state = 'on'
new_state = 'off'
on_timer = 0
off_timer = time.time()
if device_state != new_state:
update_device_state(new_state)
device_state = new_state
time.sleep(1)
run()
But the code requires some testing as I just quickly drafted it and I just briefly red it.

Update date in Python

so here is my problem, I am trying to do a little program that gives the user the next date when he will have to pay rent.
Here is my code:
curdate = datetime.date(2015, 01, 01)
rent_date = datetime.date(curdate.year, curdate.month+1, 01)
one_day = datetime.timedelta(days = 1)
one_week = datetime.timedelta(weeks = 1)
one_month = datetime.timedelta(weeks = 4)
def rent_date_calc(cd, rd):
if cd.month == 12:
rd.replace(cd.year+1, 01, 01)
else:
rd.replace(cd.year, cd.month+1, 01)
def time_pass(rd, cd, a, al):
if rd < cd:
for a in al:
a.finances -= a.rent
move_fwd = raw_input("Would you like to move forward one day(1), one week (2) or one month (3)?")
if move_fwd == "1":
curdate += one_day
elif move_fwd == "2":
curdate += one_week
else:
curdate += one_month
time_pass(rent_date, curdate, prodcomp, prodcomps)
rent_date_calc(curdate, rent_date)
print "Rent date: " + str(rent_date)
The problem I have is that rent_date always stays the same (2015-02-01)
Any idea why?
Your code is not altering anything because datetime is an immutable object, and when you call replace on it, it returns a new datetime, instead of modifying the first one.
You should return the new object from the function and assign it back to rent_date:
def rent_date_calc(cd, rd):
if cd.month == 12:
return rd.replace(cd.year+1, 01, 01)
else:
return rd.replace(cd.year, cd.month+1, 01)
...
rent_date = rent_date_calc(curdate, rent_date)
Your functions have to return a new rent date. You just need to add the following lines in your code:
return cd
new_rent_date = rent_date_calc(curdate, rent_date)
====================================================================
curdate = datetime.date(2015, 1, 1)
rent_date = datetime.date(curdate.year, curdate.month+1, 1)
one_day = datetime.timedelta(days = 1)
one_week = datetime.timedelta(weeks = 1)
one_month = datetime.timedelta(weeks = 4)
def rent_date_calc(cd, rd):
if cd.month == 12:
new_date = rd.replace(cd.year+1, 1, 1)
else:
new_date = rd.replace(cd.year, cd.month+1, 1)
return new_date
def time_pass(rd, cd, a, al):
if rd < cd:
for a in al:
a.finances -= a.rent
# Not sure what this function should return...
move_fwd = raw_input("Would you like to move forward one day(1), one week (2) or one month (3)?")
if move_fwd == "1":
curdate += one_day
elif move_fwd == "2":
curdate += one_week
else:
curdate += one_month
# time_pass(rent_date, curdate, prodcomp, prodcomps)
new_rent_date = rent_date_calc(curdate, rent_date)
print "Rent date: " + str(new_rent_date)

Checking the format/contents of a string

This program is intended to ask for the date as dd/mm/yyyy. It should then check to see if the user inputted the date in the correct format (dd/mm/yyyy). My program is not able to recognize the format correctly. This is my program:
date = (input("enter the date as dd/mm/yyyy: "))
date = day, month, year = date.split("/")
if date == (day + '/' + month + '/' + year):
print (date)
if len(day) == 1 or len(day) == 2:
print("1")
if len(month) == 1 or len(month) == 2:
print("2")
if len(year) == 4:
print ("3")
else:
if len(day) == 1 or len(day) == 2:
print("4")
if len(month) == 1 or len(month) == 2:
print("5")
if len(year) == 4:
print ("6")
The numbers being printed currently have no other purpose than to just check the validity of the date. So far, only 4,5, and 6 are being printed, meaning my program is not recognizing the formatting of the date.
Your solution doesn't work because date=day, month, year = date.split("/") sets date to a list, then you're comparing it to a string (day + '/' + month + '/' + year). However, your solution is a solved problem, do instead:
import datetime
date = (input("enter the date as dd/mm/yyyy: "))
try: datetime.datetime.strptime(date,"%d/%m/%Y")
except ValueError: # incorrect format
In addition, you probably are turning this into a datetime object later on anyway, so you can do so in the try block!
As a further optimization, be aware that many users won't WANT to enter their dates using / as a datesep! Do some introspection on your input, and adjust your datesep appropriately.
date = input("enter the date: ")
if "-" in date: datesep = "-"
elif "/" in date: datesep = "/"
elif "." in date: datesep = "."
else: datesep = ""
if len(date) < 6: yeartype = "%y"
elif date[-4:-2] not in ("19","20"): yeartype = "%y"
else: yeartype = "%Y"
try: date = datetime.datetime.strptime(date,"%d{0}%m{0}{1}".format(datesep,yeartype))
except ValueError: # invalid date
Now your code will end up with a valid datetime object of Feb 2nd 2014 for:
02022014
222014
0222014
222014
020214
02214
2214
02-02-2014
02/02/2014
2-2-14
2/2/2014
2/2/14
etc etc etc
You can use the datetime module:
import datetime
def checkdate(date):
try:
datelist = date.split('/')
datetime.datetime(year=int(datelist[2]), month=int(datelist[1]),day=int(datelist[0]))
return True
except:
return False

Categories

Resources