Imported Variable not defined - python-3.x

Currently trying to import my code from "Original Program" which is working fine independently into "Import". I am getting the error "Date is not defined". I assume the error is to do with global variables. I am knew to this and have spent some time trying to solve the issue myself to no avail. Any help appreciated :)
**Original Program**
def validDate(date, month, day):
months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
leapyear = ((date % 4) == 0) and ((date % 100) != 0) or ((date % 4) ==
0) and ((date % 100) == 0) and ((date % 4000) == 0)
if leapyear:
days[1] += 1
valid = (day <= days[months.index(month)] and day > 0 and (1753 <=
date))
print(valid)
date = int(input("Enter year: "))
month = int(input("Enter month: "))
day = int(input("Enter day: "))
validDate(date, month, day)
**Import**
from libHWDate import validDate
validDate(date, month, day)

remove the import command
from libHWDate import validDate

Related

Add/deduct month taking into account unequal days in calendar month

I am trying to come up with a way to create a list of dates n months back from given date dt. However, it seems to tricky based on what dt is. Below I am illustrating the dilemma through a few examples (esp. look at tricky case-3 below):
from datetime import datetime
from dateutil.relativedelta import relativedelta
# Simple case.
dt = datetime(2021, 2, 15)
dt - relativedelta(months=1) # n=1 gives datetime.datetime(2021, 1, 15, 0, 0)
dt - relativedelta(months=2) # n=2 gives datetime.datetime(2020, 12, 15, 0, 0)
# Simple case-2
dt = datetime(2021, 3, 31)
dt - relativedelta(months=1) # n=1 gives datetime.datetime(2021, 2, 28, 0, 0)
dt - relativedelta(months=2) # n=2 gives datetime.datetime(2021, 1, 31, 0, 0)
dt - relativedelta(months=3) # n=3 gives datetime.datetime(2020, 12, 31, 0, 0)
dt - relativedelta(months=4) # n=4 gives datetime.datetime(2020, 11, 30, 0, 0)
# Tricky case-3
dt = datetime(2021, 2, 28)
dt - relativedelta(months=1) # n=1 gives datetime.datetime(2021, 1, 28, 0, 0) and not datetime.datetime(2021, 1, 31, 0, 0)
dt - relativedelta(months=2) # n=2 gives datetime.datetime(2020, 12, 28, 0, 0) and not datetime.datetime(2020, 12, 31, 0, 0)
dt - relativedelta(months=3) # n=3 gives datetime.datetime(2020, 11, 28, 0, 0) and not datetime.datetime(2020, 11, 30, 0, 0)
dt - relativedelta(months=4) # n=4 gives datetime.datetime(2020, 10, 28, 0, 0) and not datetime.datetime(2020, 10, 31, 0, 0)
relativedelta seems to fail on the corner case of date is end of month while month has less than 31 days. Here's a work-around:
check if date is end of month
if not, simply use relativedelta
if so, use relativedelta but make sure the day is the last of the month by setting the day attribute explicitly
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
# add_month adds n months to datetime object dt
def add_month(dt, n):
# we can add a day without month changing - not end of month:
if (dt + timedelta(1)).month == dt.month:
return dt + relativedelta(months=n)
# implicit else: end of month
return (dt + relativedelta(months=n+1)).replace(day=1) - timedelta(1)
Examples:
d = datetime(2021, 3, 15)
print(add_month(d, -1).date(), d.date(), add_month(d, 1).date())
# 2021-02-15 2021-03-15 2021-04-15
d = datetime(2021, 3, 31)
print(add_month(d, -1).date(), d.date(), add_month(d, 1).date())
# 2021-02-28 2021-03-31 2021-04-30
d = datetime(2021,2,28)
print(add_month(d, -1).date(), d.date(), add_month(d, 1).date())
# 2021-01-31 2021-02-28 2021-03-31
d = datetime(2021,11,30)
print(add_month(d, -1).date(), d.date(), add_month(d, 1).date())
# 2021-10-31 2021-11-30 2021-12-31

return statement showing abnormality while using elif instead of else in function definition

I used elif instead of else in my function definition (day_in_month) and it showed an error while executing the function :
UnboundLocalError: local variable 'month_days' referenced before assignment
But after using else instead of elif , it didn't showed any error.
Code giving error is below !!!
def is_leap(year):
if year % 4 == 0:
if year % 100 == 0:
if year % 400 == 0:
return True
else:
return False
else:
return True
else:
return False
def days_in_month(year,month):
if is_leap == True:
month_days = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
elif is_leap == False:
month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
return month_days[month-1]
year = int(input("Enter a year: "))
month = int(input("Enter a month: "))
days = days_in_month(year, month)
print(days)
Now I have fixed my code , but what is the reason behind this anomaly ??
it's because you didn't call function is_leap properly..
if is_leap == True:
function is_leap is parameterized it takes one argument year, but while calling you didn't pass it
at both position if and elif, it must be like this,
if is_leap(year) == True:
this error occured because no any block executed neither if nor elif,
so your month_days list doesn't created ,
to avoid errors like this, code something like below i did,
def is_leap(year):
if year % 4 == 0:
if year % 100 == 0:
if year % 400 == 0:
return True
else:
return False
else:
return True
else:
return False
def days_in_month(year,month):
month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
if is_leap(year) == True:
month_days[1] = 29
return month_days[month-1]
year = int(input("Enter a year: "))
month = int(input("Enter a month: "))
days = days_in_month(year, month)
print(days)
def foo1(year: int) -> bool:
"find a year is leapyear or not"
if year % 4 == 0 and year % 100 != 0:
return True
return year % 4 == 0 and year % 100 == 0 and year % 400 == 0
def foo2(year: int, month: int):
"find max days in a month"
if foo1(year) and month == 2:
return 29
return [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month - 1]

Construct date based on week_of_month and day_of_week criteria

I am not sure how to go about constructing datetime object given year, month, week_of_month and day_of_week. Any clues? Using this I am trying to achieve following:
From (start_month, start_year) to (end_month, end_year) find monthly dates as specified by week_of_month and day_of_week parameters. Here 1 <= week_of_month <= 5 and 1 <= day_of_week <= 7. Now,
Each month may not have 5 weeks (eg. February in non-leap year)
1st and 5th week may not have 7 days.
In such cases, based on boolean is_to_next_day, if True then specify next calendar day, if False then skip it.
Sample input/outputs:
Input parameters: start_month=1 start_year=2020, end_month=12, end_year=2020, week_of_month=5, day_of_week=3, is_to_next_day=True
Desired output: [datetime(2020, 1, 29), datetime(2020, 2, 26), datetime(2020, 3, 25), datetime(2020, 4, 29), datetime(2020, 5, 27), datetime(2020, 7, 1), datetime(2020, 7, 29), datetime(2020, 8, 26), datetime(2020, 9, 30), datetime(2020, 10, 28), datetime(2020, 11, 25), datetime(2020, 12, 30)]
Input parameters: start_month=1 start_year=2020, end_month=12, end_year=2020, week_of_month=5, day_of_week=3, is_to_next_day=False
Desired output: [datetime(2020, 1, 29), datetime(2020, 2, 26), datetime(2020, 3, 25), datetime(2020, 4, 29), datetime(2020, 5, 27), datetime(2020, 7, 29), datetime(2020, 8, 26), datetime(2020, 9, 30), datetime(2020, 10, 28), datetime(2020, 11, 25), datetime(2020, 12, 30)]
import calendar
from datetime import datetime
def get_date(year, month, week_of_month, day_of_week, is_to_next_day):
mnth = calendar.monthcalendar(year, month)
if (week_of_month > 1) and (week_of_month < 5):
day = mnth[week_of_month - 1][day_of_week - 1]
return datetime(year, month, day)
elif week_of_month == 1:
last_day_of_first_week = mnth[0][6]
if day_of_week <= last_day_of_first_week:
return datetime(year, month, day_of_week)
elif is_to_next_day:
return datetime(year, month, mnth[1][0])
else:
return None
else:
if (len(mnth) >= week_of_month):
day = mnth[week_of_month - 1][day_of_week - 1]
if(day==0) and is_to_next_day:
return datetime(year + int((month + 1)/12), (month + 1)%12, 1)
elif(day==0):
return None
else:
return datetime(year, month, day)
if (len(mnth) < week_of_month):
if is_to_next_day:
return datetime(year + int((month + 1)/12), (month + 1)%12, 1)
else:
return None
# First output
[get_date(yy, mm, 5, 3, True) for mm in range(1, 13) for yy in [2020]]
# Second output
[get_date(yy, mm, 5, 3, False) for mm in range(1, 13) for yy in [2020]] # Iterate again to drop None.

Question on loopinbg - trying to find a prime number from a list

I am given a list of numbers and using python, I need to find the prime numbers in the list and print them out
I have tried several different things but can't quite get it to work. My latest attempt is below but that just returns all the numbers with the message saying that it is a prime number except for the last one.
odd_numbers = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29]
x = 0
y = len(odd_numbers) - 1
# If given number is greater than 1
#if odd_numbers[x] > 2:
# Iterate from 2 to n / 2
for i in range(0, y):
# If num is divisible by any number between
# 2 and n / 2, it is not prime
if (odd_numbers[x] % 2) == 0:
break
else:
pr_no = odd_numbers[x]
print(odd_numbers[x], "is a prime number")
x = x + 1
else:
print(odd_numbers[x], "is not a prime number")
What it should do is print out:
2 is a prime number
3 is a prime number etc for all prime numbers in the list
odd_numbers = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29]
for x in odd_numbers:
if x > 1:
for y in range(2,x):
if (x % y) == 0:
# print(x,"is not a prime number")
# print(y,"times",x//y,"is",x)
break
else:
print(y,"is a prime number")
# else:
# print(x, "is not a prime number")

Python: Calculate the last digit of a large Fibonacci Number with less time

# Uses python3
# Compute the Last Digit of a Large Fibonacci Number
def Fib_Last_Digit(n):
if n == 0 : return 0
elif n == 1: return 1
else:
a,b = 0,1
for i in range(1,n):
c = a + b;
a = b;
b = c;
# Calculate the last digit of the final number
lastdigit = int(repr(c)[-1]);
print(lastdigit);
n = int(input(""));
Fib_Last_Digit(n);
This code works very well. However, I want to revise the algorithm to save more time and memory. By the way, the input and output should be kept the same with the previous version.
Only keeping the last digit during calculation saves a lot of time:
def fib_last_digit(n):
if n < 2: return n
else:
a, b = 0, 1
for i in range(1,n):
a, b = b, (a+b) % 10
print(b)
n = int(input())
fib_last_digit(n)
Handling numbers that fit in fewer bytes saves time.
When you're working with huge numbers, you can save a lot of time using the answer described here, slightly modified to only keep track of the last digit:
def fib_last_digit(n):
v1, v2, v3 = 1, 1, 0 # initialise a matrix [[1,1],[1,0]]
for rec in bin(n)[3:]: # perform fast exponentiation of the matrix (quickly raise it to the nth power)
calc = (v2*v2) % 10
v1, v2, v3 = (v1*v1+calc) % 10, ((v1+v3)*v2) % 10, (calc+v3*v3) % 10
if rec == '1': v1, v2, v3 = (v1+v2) % 10, v1, v2
return v2
And finally, based on the concept described in Eugene Yarmash's answer (the last digits repeat every 60 steps) we can make an even faster solution (O(1)):
def fib_last_digit(n):
return (
[1, 1, 2, 3, 5, 8, 3, 1, 4, 5, 9, 4, 3, 7, 0, 7, 7, 4, 1, 5, 6, 1, 7, 8, 5, 3, 8, 1, 9, 0, 9, 9, 8, 7, 5, 2, 7, 9, 6, 5, 1, 6, 7, 3, 0, 3, 3, 6, 9, 5, 4, 9, 3, 2, 5, 7, 2, 9, 1, 0]
[n % 60 - 1]
)
The series of final digits of Fibonacci numbers repeats with a cycle length of 60. Therefore, the Nth Fibonacci number has the same last digit as the (N % 60)th, which should be pretty fast to calculate. As an additional optimization, you can keep only the last digit of each term:
def fib_last_digit(n):
a, b = 0, 1
for i in range(n % 60):
a, b = b, (a + b) % 10
return a
print([fib_last_digit(n) for n in range(1, 11)])
Output:
[1, 1, 2, 3, 5, 8, 3, 1, 4, 5]
def fib(n):
phi = (1 + 5 ** 0.5) / 2
fib_n = round(((phi** n) - (phi**-n) )/(5 ** .5))
return fib_n % 10
Phi is your friend.
def fib_digit(n):
f=[1,1]
for i in range(2,n):
f.append((f[i-1]+f[i-2]) % 10 )
return f[-1]
n = int(input())
print(fib_digit(n))
This is one of the simplest answers,i'm sure, there is a faster algorithm.
Here is what I found:
f1, f2 = 0, 1
for i in range(int(input())-1):
f1, f2 = f2, (f1+f2)%10
print(f2)
It took only --- 0.002832174301147461 seconds --- to complete the code.
import time
n = 100000000000000000000000000000000000000000
def printfib(previous, latest, n):
if(latest > n):
return
print(', ', latest, end='')
printfib(latest, previous + latest, n)
start_time = time.time()
print(0, end='')
printfib(0, 1, n)
print(" ")
print("--- %s seconds ---" % (time.time() - start_time))

Resources