So to figure out the day of the week from any date since 15 of october you can use a simple piece of arithmetic my problem is that i have read from a file the date (for e.g. 2009-06-12) and i have put the equation in:
w = (d + [2.6 * m - 0.2] + Y + [Y / 4] + 5 * C + [C / 4] ) % 7
The dates are in the format yyyy-mm-dd and my code looks like this:
count = 5
f = open('/Users/student/Desktop/Harry.txt').readlines()[count]
Y = f[2:4]
C = f[:2]
m = f[5:7]
d = f[8:10]
w = (d + [2.6 * m - 0.2] + Y + [Y / 4] + 5 * C + [C / 4] ) % 7
if w == 0:
print (f, "is a Sunday")
elif w == 1:
print (f, "is a Monday")
elif w == 2:
print (f, "is a Tuesday")
elif w == 3:
print (f, "is a Wednesday")
elif w == 4:
print (f, "is a Thursday")
elif w == 5:
print (f, "is a Friday")
elif w == 6:
print (f, "is a Saturday")
to clarify:
w = day of the week counting from Sunday = 0 Monday = 1
d = the day of the month (for e.g. 28th 13th)
m = month number where March = 1 etc.
Y = last 2 digits of year
C = first 2 digits of year
Yet i get this error
Traceback (most recent call last):
File "/Users/student/Documents/workspace/Tutorial Challenges/src/Day_Of_The_Week.py", line 7, in <module>
w = (d + [2.6 * m - 0.2] + Y + [Y / 4] + 5 * C + [C / 4] ) % 7
TypeError: can't multiply sequence by non-int of type 'float'
Help would be greatly appreciated.
Y, C, m, and d are all strings. You want to convert them into ints first:
Y = int(f[2:4])
C = int(f[:2])
...
Are you sure that equation even works, though? It looks like it'd produce a lot of non-integer weekdays. You might've miscopied it. Also, brackets aren't a grouping operator in Python; they're the list construction syntax. You'll want to replace those brackets with parentheses in the expression for w. (Or were those brackets supposed to be the floor operator? If so, you'll want math.floor, from the math module, or just int if truncation is fine.)
As the above user has said, you want to convert from string to int. However, this is the ideal place to use the datetime module. You can use this to specify that your datetime is of the format: yyyy-mm-dd, and use the module to load up the info as datetime.
http://docs.python.org/2/library/datetime.html
Related
Imagine I have o1=pdandas.tseries.frequencies.to_offset('M') (a MonthEnd object) and o2=pdandas.tseries.frequencies.to_offset('Y') (a YearEnd object).
How to compute how many o1s there are inside 1 o2?
So in my example, I should get the number 12, which means there are 12 MonthEnd (M) periods in 1 YearEnd (Y or A) period.
Between Day (D) and Week (W) I should get the number 7.
Between QuarterEnd (Q) and YearEnd (Y or A) I should get the number 4.
And so on...
The easiest is for fixed frequencies. Here you can simply use .nanos:
>>> m = pd.tseries.frequencies.to_offset('5min')
>>> n = pd.tseries.frequencies.to_offset('1h')
>>> n.nanos / m.nanos
12.0
With non-fixed frequencies, this throws an error:
>>> y = pd.tseries.frequencies.to_offset('1Y')
>>> y.nanos
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "pandas/_libs/tslibs/offsets.pyx", line 690, in pandas._libs.tslibs.offsets.BaseOffset.nanos.__get__
ValueError: <YearEnd: month=12> is a non-fixed frequency
You can always use a specific date to find out what this frequency can convert to as a timedelta:
>>> d = pd.Timestamp(0)
>>> (d + y) - d
Timedelta('364 days 00:00:00')
>>> ((d + y) - d).delta
31449600000000000
Now of course dividing these nanoseconds obtained that way is not going to give you exact results − by definition of the frequencies being non fixed. However it should be close enough to round:
>>> yns = ((d + y) - d).delta
>>> qns = ((d + q) - d).delta
>>> q = pd.tseries.frequencies.to_offset('1Q')
>>> yns / qns
4.089887640449438
>>> round(yns / qns)
4
Then you could of course verify that this rounded result holds for your chosen start date:
>>> d + q * 4 == d + y
True
Of course the choice of the date your use for your computations is important, 4 quarters don’t always match 1 year if you don’t start in january:
>>> d = pd.Timestamp('1970-4-01')
>>> d + q * 4 == d + y
False
So that’s something to keep in mind if you use for example frequencies of multiple years.
def div_offsets(a, b, date=pd.Timestamp(0)):
''' Compute pandas dateoffset ratios using nanosecond conversion
'''
try:
return a.nanos / b.nanos
except ValueError:
pass
ans = ((date + a) - date).delta
bns = ((date + b) - date).delta
if ans > bns:
ratio = round(ans / bns)
assert date + ratio * b == date + a
return ratio
else:
ratio = round(bns / ans)
assert date + b == date + ratio * a
return 1 / ratio
Can't think of a straighforward way, but you could try leveraging pandas.date_range:
def get_ratio(offset_a, offset_b, rounding=False):
START = pd.Timestamp.today() # any random day
LARGER_OFFSET = offset_a if START+offset_a > START+offset_b else offset_b
freq_a = pd.date_range(START-LARGER_OFFSET, START+LARGER_OFFSET,
freq=offset_a, closed='left').size
freq_b = pd.date_range(START-LARGER_OFFSET, START+LARGER_OFFSET,
freq=offset_b, closed='left').size
return freq_a / freq_b
offset = pd.tseries.frequencies.to_offset
>>> get_ratio(offset('M'), offset('Y'))
12
>>> get_ratio(offset('Q'), offset('Y'))
4
>>> get_ratio(offset('D'), offset('W'))
7
I have already seen a couple of programs for this. Just wanted to know what's wrong with this logic. It keeps on returning 'str' object does not support item assignment. I looked this up but still couldn't find a reason this occurs.I'm just a newbie so apologies in advance if I'm just overthinking things.
x = dec
a = 5
n = 1
remainder = str()
binary = str()
while a != 1:
a = x // 2
b = x % 2
x = a
z = str(b)
remainder = str(remainder + z)
if a == 1:
b = 1
z = str(b)
remainder = str(remainder + z)
print(remainder)
asd = len(remainder)
for y in range(1, asd + 1):
binary[y:y + 1] = remainder[-y:-y - 1]
print("It's binary form is ", binary)
The problem is here:
for y in range(1, asd + 1):
binary[y:y + 1] = remainder[-y:-y - 1]
# ^^^^^^^^^^^^^ error
What do you expect this to do? Python strings are immutable: you cannot assign to a string slice. You can only use the value (right-hand side of an assignment, for example), or replace the variable's entire value.
I suspect that you're trying to reverse the string. Do it like this:
rev = remainder[::-1] # Whole string, but in reverse order
This script has a formula where at the beginning the numbers x1 and x2 in the code are set, and
I need to change the code so that the value x1 is taken from the list
pre-prepared text document
For example, from a document: 'List.txt'
That is, it turns out I need to enter:
with open ("List.txt '", "r") as f:
into place the value x1 = 6 in the code. But how to systematize it? Just not very rich in knowledge of Python.
List of numbers:
1
4
2
15
6
8
13
3
12
5
10
7
14
9
11
Code: (Powered by Python 2.7)
import sys
a=0
b=7
p=37
x1=6
x2=8
if (len(sys.argv)>1):
x1=int(sys.argv[1])
if (len(sys.argv)>2):
x2=int(sys.argv[2])
if (len(sys.argv)>3):
p=int(sys.argv[3])
if (len(sys.argv)>4):
a=int(sys.argv[4])
if (len(sys.argv)>5):
b=int(sys.argv[5])
def modular_sqrt(a, p):
""" Find a quadratic residue (mod p) of 'a'. p
must be an odd prime.
Solve the congruence of the form:
x^2 = a (mod p)
And returns x. Note that p - x is also a root.
0 is returned is no square root exists for
these a and p.
The Tonelli-Shanks algorithm is used (except
for some simple cases in which the solution
is known from an identity). This algorithm
runs in polynomial time (unless the
generalized Riemann hypothesis is false).
"""
# Simple cases
#
if legendre_symbol(a, p) != 1:
return 0
elif a == 0:
return 0
elif p == 2:
return p
elif p % 4 == 3:
return pow(a, (p + 1) / 4, p)
# Partition p-1 to s * 2^e for an odd s (i.e.
# reduce all the powers of 2 from p-1)
#
s = p - 1
e = 0
while s % 2 == 0:
s /= 2
e += 1
# Find some 'n' with a legendre symbol n|p = -1.
# Shouldn't take long.
#
n = 2
while legendre_symbol(n, p) != -1:
n += 1
x = pow(a, (s + 1) / 2, p)
b = pow(a, s, p)
g = pow(n, s, p)
r = e
while True:
t = b
m = 0
for m in xrange(r):
if t == 1:
break
t = pow(t, 2, p)
if m == 0:
return x
gs = pow(g, 2 ** (r - m - 1), p)
g = (gs * gs) % p
x = (x * gs) % p
b = (b * g) % p
r = m
def legendre_symbol(a, p):
""" Compute the Legendre symbol a|p using
Euler's criterion. p is a prime, a is
relatively prime to p (if p divides
a, then a|p = 0)
Returns 1 if a has a square root modulo
p, -1 otherwise.
"""
ls = pow(a, (p - 1) / 2, p)
return -1 if ls == p - 1 else ls
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
print ("x")
else:
return x % m
print "a=",a
print "b=",b
print "p=",p
print "x-point=",x1
print "x-point=",x2
z=(x1**3 + a*x1 +b) % p
y1=modular_sqrt(z, p)
z=(x2**3 + a*x2 +b) % p
y2=modular_sqrt(z, p)
print "\nP1\t(%d,%d)" % (x1,y1)
print "P2\t(%d,%d)" % (x2,y2)
s=((-y2)-y1)* modinv(x2-x1,p)
x3=(s**2-x2-x1) % p
y3=((s*(x2-x3)+y2)) % p
result = "Q\t(%d,%d)" % (x3,y3)
f = open('Result01.txt', 'w')
f.write(result)
f.close()
Earlier, I saw scripts where numbers are taken from one text document, perform a function, and the result is saved in another text document.
Try using the pandas library to read, process and write your numbers.
import pandas as pd # import pandas module and call it pd for short
x2 = 6
df = pd.read_csv('input_file.txt') # read the data from a text file into a dataframe
df['x1 times x2'] = df['x1'] * x2 # create new column in your dataframe with result of your function
df.to_csv('output_file.txt', index=False) # output result of your calculations (dropping the dataframe index column)
Although you're hard coding the values of x1, x2, in your code, they can be redefined, as you're doing here:
if (len(sys.argv)>1):
x1=int(sys.argv[1])
if (len(sys.argv)>2):
x2=int(sys.argv[2])
So if you call your script from command line, like C:\Users\test.py x1value x2value you can redefine x1 and x2. If you really want a text file to contain your x1 and x2, just use the following snippet somewhere at the top
import json
with open("input.json","r",encoding="utf-8") as stream:
parsed = json.load(stream)
x1,x2 = parsed["x1"],parsed["x2"]
Contents of "input.json":
{"x1":1,"x2"=2}
With only python without extra dependencies, your can read List.txt as follow
with open("List.txt","r") as f:
arrX1 = list(map(int,f.readlines()))
print (arrX1)
The above reads all the lines in f and converts/maps them to integers. The list function then gives you an array you can loop through to generate x2 and write to the Result.txt file.
The above prints
[1, 4, 2, 15, 6, 8, 13, 5, 3, 10, 7, 14, 9, 11]
So for your code replace all lines from 125 downward with
# Read numbers from file and put them in an array
with open("List.txt","r") as f:
arrX1 = list(map(int,f.readlines()))
f.close()
# Open the result file to write to
f = open('Result01.txt', 'w')
# Now get x1 for each item in the list of numbers from the file
# then do the calculations
# and write the result
for x1 in arrX1:
z=(x1**3 + a*x1 +b) % p
y1=modular_sqrt(z, p)
z=(x2**3 + a*x2 +b) % p
y2=modular_sqrt(z, p)
print "\nP1\t(%d,%d)" % (x1,y1)
print "P2\t(%d,%d)" % (x2,y2)
s=((-y2)-y1)* modinv(x2-x1,p)
x3=(s**2-x2-x1) % p
y3=((s*(x2-x3)+y2)) % p
result = "Q\t(%d,%d)" % (x3,y3)
f.write(result)
f.close()
My goal with this code was to write a code that measures the degree measure of the sun having that at 6:00 the angle is 0 and at 18:00 the angle is 180 degrees. I tried to make the time input a string and then loop through its characters and pick out the integers and put it into the list that way I could avoid the colon. It seems that this is still a problem. Can someone explain to me what's wrong with this code? Why do I keep getting an "unsupported operand type error"?
def sun_angle(time):
lis = []
time = str(time)
for i in time:
if i.isdigit():
lis.append(i)
else:
continue
a = int(lis[0]*10 + lis[1] + ((lis[2] + lis[3])/60))
b = a - 6
if b < 6 or b > 18:
return "I can't see the sun!"
else:
return b * 15
print(sun_angle("12:12"))
Michael's answer is a great explanation for why what you're doing isn't working (need to convert string to int before manipulating with * and +).
However, there are a lot of ways to parse the time that will be easier to work with than what you're doing here. I'd consider splitting and then parsing the two parts, or you could use the datetime library for more complexity:
# option 1
def parse_time_as_hour(time_str):
hour_str, min_str = time_str.split(':')
return int(hour_str) + int(min_str) / 60.0
# option 2
import datetime
def parse_time_as_hour(time_str):
parsed = datetime.datetime.strptime(time_str, '%H:%M')
return parsed.hour + parsed.minute / 60.0
def sun_angle(time):
fractional_hour = parse_time_as_hour(time)
if fractional_hour < 6 or fractional_hour >= 18:
return "I can't see the sun!"
else:
return (fractional_hour - 6) * 15
If you change the above similar line to:
a = int(lis[0]) * 10 + int(lis[1]) + ((int(lis[2]) + int(lis[3]))/60)
then you get a result. The problem on that line is that you're mixing int and str types. And since you're already passing in a string you can change time = str(time) to time = time. Casting time to a string is redundant.
Your error line is:
a = int(lis[0]*10 + lis[1] + ((lis[2] + lis[3])/60))
since time is a string type
def sun_angle(time):
lis = []
time = str(time)
for i in time:
if i.isdigit():
lis.append(int(i)) #cast it to type int
else:
continue
a = int(lis[0]*10 + lis[1] + ((lis[2] + lis[3])/60))
b = a - 6
if b < 0 or b >= 12:
return "I can't see the sun!"
else:
return b * 15
print(sun_angle("12:12"))
output: 90
You need to cast lis[i] to integer when you're calculating the value of a. 07:00 means sun is up, your logic fails and 18:01 means sun is down.
def sun_angle(time_):
lis = []
time_ = str(time_)
for i in time_:
if i.isdigit():
lis.append(i)
else:
continue
a = int(lis[0])*10
a += int(lis[1])
bb = (int(lis[2])*10 + int(lis[3]))
#print a
#print bb
#b = a - 6
if (a < 6 or a > 18) or (a == 18 and bb > 0):
return "I can't see the sun!"
else:
return (float(a)-6.0) * 15.0 + (15.0*float(bb))/60.0
My algorithm to find the HCF of two numbers, with displayed justification in the form r = a*aqr + b*bqr, is only partially working, even though I'm pretty sure that I have entered all the correct formulae - basically, it can and will find the HCF, but I am also trying to provide a demonstration of Bezout's Lemma, so I need to display the aforementioned displayed justification. The program:
# twonumbers.py
inp = 0
a = 0
b = 0
mul = 0
s = 1
r = 1
q = 0
res = 0
aqc = 1
bqc = 0
aqd = 0
bqd = 1
aqr = 0
bqr = 0
res = 0
temp = 0
fin_hcf = 0
fin_lcd = 0
seq = []
inp = input('Please enter the first number, "a":\n')
a = inp
inp = input('Please enter the second number, "b":\n')
b = inp
mul = a * b # Will come in handy later!
if a < b:
print 'As you have entered the first number as smaller than the second, the program will swap a and b before proceeding.'
temp = a
a = b
b = temp
else:
print 'As the inputted value a is larger than or equal to b, the program has not swapped the values a and b.'
print 'Thank you. The program will now compute the HCF and simultaneously demonstrate Bezout\'s Lemma.'
print `a`+' = ('+`aqc`+' x '+`a`+') + ('+`bqc`+' x '+`b`+').'
print `b`+' = ('+`aqd`+' x '+`a`+') + ('+`bqd`+' x '+`b`+').'
seq.append(a)
seq.append(b)
c = a
d = b
while r != 0:
if s != 1:
c = seq[s-1]
d = seq[s]
res = divmod(c,d)
q = res[0]
r = res[1]
aqr = aqc - (q * aqd)#These two lines are the main part of the justification
bqr = bqc - (q * aqd)#-/
print `r`+' = ('+`aqr`+' x '+`a`+') + ('+`bqr`+' x '+`b`+').'
aqd = aqr
bqd = bqr
aqc = aqd
bqc = bqd
s = s + 1
seq.append(r)
fin_hcf = seq[-2] # Finally, the HCF.
fin_lcd = mul / fin_hcf
print 'Using Euclid\'s Algorithm, we have now found the HCF of '+`a`+' and '+`b`+': it is '+`fin_hcf`+'.'
print 'We can now also find the LCD (LCM) of '+`a`+' and '+`b`+' using the following method:'
print `a`+' x '+`b`+' = '+`mul`+';'
print `mul`+' / '+`fin_hcf`+' (the HCF) = '+`fin_lcd`+'.'
print 'So, to conclude, the HCF of '+`a`+' and '+`b`+' is '+`fin_hcf`+' and the LCD (LCM) of '+`a`+' and '+`b`+' is '+`fin_lcd`+'.'
I would greatly appreciate it if you could help me to find out what is going wrong with this.
Hmm, your program is rather verbose and hence hard to read. For example, you don't need to initialise lots of those variables in the first few lines. And there is no need to assign to the inp variable and then copy that into a and then b. And you don't use the seq list or the s variable at all.
Anyway that's not the problem. There are two bugs. I think that if you had compared the printed intermediate answers to a hand-worked example you should have found the problems.
The first problem is that you have a typo in the second line here:
aqr = aqc - (q * aqd)#These two lines are the main part of the justification
bqr = bqc - (q * aqd)#-/
in the second line, aqd should be bqd
The second problem is that in this bit of code
aqd = aqr
bqd = bqr
aqc = aqd
bqc = bqd
you make aqd be aqr and then aqc be aqd. So aqc and aqd end up the same. Whereas you actually want the assignments in the other order:
aqc = aqd
bqc = bqd
aqd = aqr
bqd = bqr
Then the code works. But I would prefer to see it written more like this which is I think a lot clearer. I have left out the prints but I'm sure you can add them back:
a = input('Please enter the first number, "a":\n')
b = input('Please enter the second number, "b":\n')
if a < b:
a,b = b,a
r1,r2 = a,b
s1,s2 = 1,0
t1,t2 = 0,1
while r2 > 0:
q,r = divmod(r1,r2)
r1,r2 = r2,r
s1,s2 = s2,s1 - q * s2
t1,t2 = t2,t1 - q * t2
print r1,s1,t1
Finally, it might be worth looking at a recursive version which expresses the structure of the solution even more clearly, I think.
Hope this helps.
Here is a simple version of Bezout's identity; given a and b, it returns x, y, and g = gcd(a, b):
function bezout(a, b)
if b == 0
return 1, 0, a
else
q, r := divide(a, b)
x, y, g := bezout(b, r)
return y, x - q * y, g
The divide function returns both the quotient and remainder.
The python program that does what you want (please note that extended Euclid algorithm gives only one pair of Bezout coefficients) might be:
import sys
def egcd(a, b):
if a == 0:
return (b, 0, 1)
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def main():
if len(sys.argv) != 3:
's program caluclates LCF, LCM and Bezout identity of two integers
usage %s a b''' % (sys.argv[0], sys.argv[0])
sys.exit(1)
a = int(sys.argv[1])
b = int(sys.argv[2])
g, x, y = egcd(a, b)
print 'HCF =', g
print 'LCM =', a*b/g
print 'Bezout identity: %i * (%i) + %i * (%i) = %i' % (a, x, b, y, g)
main()