I'm trying to count how many file are very young, young, old and very old in a directory passed by command line. I have some struggle counting the number of file in the directory and then to change the counter in function of the age of the file.
Here is what I did yet:
import sys
import os, os.path
import time
x = 7
file_count = 0
DIR = sys.argv[1]
age = 0
age_sum = 0
nb_vy = 0
nb_y = 0
nb_o = 0
nb_vo = 0
now = time.time()
for root, subFolders, files in os.walk(DIR):
for file in (files):
try:
file_count += 1
# here I want to do some if to add 1 in the counter nb_vy/nb_y/nb_o/nb_vo but I don't know how
age=now - os.stat(os.path.join(root,file)).st_mtime
age_sum+=age
if now-timedelta(hours=24) <= age <= now :
nb_vy += 1
elif now-timedelta(days=7) <= age :
nb_y += 1
elif now-timedelta(days=30) <= age :
nb_o += 1
else:
nb_vo += 1
except Exception:
pass
print("Filecount = %s" % file_count)
print("--------------------------------------------------------------------\n")
print("Scanned: "+ str(file_count) +" files\n")
print("Average age: "+ str(age/age_sum) + "\n")
print("--------------------------------------------------------------------\n")
print("Very young files (<= 1 day) | "+ str(nb_vy/file_count) +"% (" + str(nb_vy) + ")\n")
print("Young files (<= 1 week) | "+ str(nb_y/file_count) +"% (" + str(nb_v) + ")\n")
print("Old files (<= 30 days) | "+ str(nb_o/file_count) +"% (" + str(nb_o) + ")\n")
print("Very old files (> 30 days | "+ str(nb_vo/file_count) +"% (" + str(nb_vo) + ")\n")
print("--------------------------------------------------------------------\n")
How can I manage the if cascade to increment the right counter ?
You had the sides of the comparison swapped and the unneeded now - was still there. Once those are fixed and the timedelta converted to a duration of seconds for comparison:
if age <= timedelta(hours=24).total_seconds():
nb_vy += 1
elif age <= timedelta(days=7).total_seconds():
nb_y += 1
elif age <= timedelta(days=30).total_seconds():
nb_o += 1
else:
nb_vo += 1
You should be using age < max_age_for_group as the condition. age is already now - mtime. age is in seconds.
Also except Exception: pass will harm debugging. If you must have it at least use:
except Exception:
logging.exception('')
This will eat the exception but still print it. And then you can turn the printing off by changing the level on the root logger.
You correctly calculate the age of the file with calculating the difference in time using:
now = time.time()
mt = os.stat(os.path.join(root,file)).st_mtime
age = now - mt
All of the above variable are stored as float and represent the time in seconds ellapsed since January 1st 1970. So the difference age is a time difference in seconds!
In order to categorize into the intervals specified, you need to convert this time difference to days, e.g. with:
# import datetime
td = datetime.timedelta(0, age)
print(td.days) # Prints the time delta in days (integer)
I think, this is exactly what you need for you comparison, as if the time difference is, e.g. 72000 seconds (=20 hours), td.days will be evalutated to 0.
Related
I have another program which is meant to get information and then write it into a separate text doc. For this program, I want to take the data on the text doc and format it into an output. I have managed to get the formatting correct as well as the loop to read the information correctly but am struggling to get three more variables: 1) Find the total amount due between all employees added together. 2) Find the total amount of hours all the employees worked added. 3) Find the average hours worked per week. I cannot figure out how to get these variables as the information from the text doc must be in string format (to my knowledge), and i need them to be in float to do the calculations.
Thanks for any help in advance!
def main():
employeeCount = 0
infile = open("BillingTEST.txt","r")
print("Employee Name\t\t" +
"Rate\t" +
"Week 1\t" +
"Week 2\t" +
"Week 3\t" +
"Week 4\t" +
"Hours\t" + "Total")
name = readAsString(infile)
while name != "":
employeeCount += 1
rate = readAsFloat(infile)
week1 = readAsFloat(infile)
week2 = readAsFloat(infile)
week3 = readAsFloat(infile)
week4 = readAsFloat(infile)
empHours = week1+week2+week3+week4
empMoney = empHours * rate
print(name + "\t\t\t$" +
str(rate)+ "\t" +
str(week1)+"\t" +
str(week2)+"\t" +
str(week3)+"\t" +
str(week4)+"\t" +
str(empHours)+"\t" +
str(empMoney))
name = readAsString(infile)
print("\nTotal Billable Due:\t"+
"\nTotal Billable Hours:"+
"\nAverage Billable Hours:\t"+
"\nEmployee Count: ",employeeCount)
def readAsString(file):
return file.readline().rstrip("\n")
def readAsFloat(file):
return float(file.readline().rstrip("n"))
main()
I have the following data in a text file.
Intium II,2.8,24,128
Celerisc I,1.6,32,256
Ethloan III,2.6,32,128
Powerup II,1.9,64,512
Mitduo III,3.1,24,128
I am doing the following:
Allocating points to each processor
Points will be awarded to each processor as follows:
Clock speed is less than 2 GHz, award 10 points.
Clock speed is between 2 GHz and 3 GHz inclusive, award 20 points.
Clock speed is greater than 3 GHz, award 30 points.
Data Bus Points
1 point for each line on the data bus e.g. 24 bit data bus, award 24 points.
Cache Size Points
1 point for each whole 10 Kb of cache e.g. 128Kb cache, award 12 points.
(128/10 = 12ยท8, which should be rounded down to 12)
The output from the program should be similar to the following:
John Doe your order code is JD3f
Processor Points
Intium II 56
Celerisc I 67
Ethloan III 64
Powerup II 125
Mitduo III 66
Here is my code
import random
import string
def getDetails():
forename = input("Enter first name: ")
surname = input("Enter last name: ")
number = random.randint(0,9)
character = random.choice(string.ascii_letters).lower()
code = (forename[:1] + str(surname[:1]) + str(number) + str(character))
return forename, surname, code
def readProcessorDetails():
processorName = []*5
clockSpeed = []*5
dataBusWidth = []*5
cacheSize = []*5
file = open("processors.txt","r")
for line in file:
data = line.split(",")
processorName.append(data[0])
clockSpeed.append(float(data[1]))
dataBusWidth.append(data[2])
cacheSize.append(data[3])
input("file read successfully.. Press any key to continue")
return processorName, clockSpeed, dataBusWidth, cacheSize
def allocatePoints(clockSpeed, dataBusWidth, cacheSize):
proPoints = 0.0
processorPoints = []
for counter in range(len(clockSpeed)):
if clockSpeed[counter] < 2.0 or dataBusWidth[counter] == 24 or dataBusWidth[counter] == 128:
proPoints = proPoints + 10 + 24 + 12
processorPoints.append(proPoints)
elif clockSpeed[counter] > 2.0 or clockSpeed[counter] <= 3.0 or dataBusWidth[counter] == 24 or dataBusWidth[counter] == 128:
proPoints = proPoints + 20 + 24 + 12
processorPoints.append(proPoints)
elif clockSpeed[counter] > 3.0 or dataBusWidth[counter] == 24 or dataBusWidth[counter] == 128:
proPoints = proPoints + 30 + 24 + 12
processorPoints.append(proPoints)
return processorPoints
def display(processorName, processorPoints):
print(f"Processor \t Points")
for counter in range(len(processorPoints)):
print(f"{processorName[counter]}\t {processorPoints[counter]}\n")
def main():
forename, surname, code = getDetails()
processorName, clockSpeed, dataBusWidth, cacheSize = readProcessorDetails()
processorPoints = allocatePoints(clockSpeed, dataBusWidth, cacheSize)
print()
print(forename + " " + surname + " your order code is " + code)
print()
display(processorName, processorPoints)
main()
Here is my code output
Enter first name: John
Enter last name: Doe
file read successfully.. Press any key to continue
John Doe your order code is JD8z
Processor Points
Intium II 56.0
Celerisc I 102.0
Ethloan III 158.0
Powerup II 204.0
Mitduo III 260.0
I am not sure what I am doing wrong in my allocatePoints() function where I have used complex if statements and running total to add processor points.
Consider keeping all of the data in one list, rather than trying to coordinate multiple lists. This lets you avoid the unPythonic "for x in range(len(x))" construct, and iterate through the list directly.
I also fixed your root problem, which is that you weren't resetting the points to zero for every new processor.
import random
import string
def getDetails():
forename = input("Enter first name: ")
surname = input("Enter last name: ")
number = random.randint(0,9)
character = random.choice(string.ascii_letters).lower()
code = (forename[:1] + str(surname[:1]) + str(number) + str(character))
return forename, surname, code
def readProcessorDetails():
pdata = []
for line in open("processors.txt"):
data = line.split(",")
pdata.append( [data[0], float(data[1]), int(data[2]), int(data[3])] )
return pdata
def allocatePoints(pdata):
for row in pdata:
points = 0
if row[1] < 2.0:
points += 10
elif row[1] <= 3.0:
points += 20
else:
points += 30
points += row[2]
points += row[3] // 10
row.append( points )
def display(pdata):
print("Processor\tPoints")
for row in pdata:
print(f"{row[0]}\t{row[-1]}")
def main():
forename, surname, code = getDetails()
processorData = readProcessorDetails()
allocatePoints(processorData)
print()
print(forename + " " + surname + " your order code is " + code)
print()
display(processorData)
main()
So basically, i needed to write a program that takes the time of how fast you run a kilometer, and turn it into how long it takes to run a marathon. I got that done, but the problem is that it is supposed to handle if someone inputs the time incorrectly (ex 888 or 5:2555 instead of 8:30)
print "Marathon Time Calculator"
str_pace = raw_input("At what pace do you run a km? (e.g. 5:30): ")
if str_pace.isalpha():
print 'invalid time'
split_pace = str_pace.split(":")
minutes = int(split_pace[0])
seconds = int(split_pace[1])
str_pace = minutes * 60 + seconds
totalTime = str_pace * 42
hours = totalTime // 3600
timeLeft = totalTime % 3600
minutes = timeLeft // 60
seconds = timeLeft % 60
if len(split_pace[1]) >= 3:
print "Too many digits"
else:
print "You should complete a marathon in " + str(hours) + ":" + str(minutes) + ":" + str(seconds)
I have done this in python3
import re
import sys
print("Marathon Time Calculator")
str_pace = input("At what pace do you run a km? (e.g. 5:30): ")
# this is looking for a decimal value of 1 number, then a colon then another decimal value of 1 - 2 numbers
pattern = '\d{1}\:\d{1,2}'
# this is doing the actual check against the pattern for us
match = re.match(pattern, str_pace)
# we now check if there is a match to our pattern
if not match:
print('Invalid Time Input Try Again')
sys.exit
else:
# yes we are entering the value correctly continue the code
split_pace = str_pace.split(":")
minutes = int(split_pace[0])
seconds = int(split_pace[1])
str_pace = minutes * 60 + seconds
totalTime = str_pace * 42
hours = totalTime // 3600
timeLeft = totalTime % 3600
minutes = timeLeft // 60
seconds = timeLeft % 60
print("You should complete a marathon in {}:{}:{}".format(hours, minutes, seconds))
I am wondering how to calculate the amount of time it would take to example:
Complete a brute force word list.
I know how to use the time function and measure in time,
but the problem is i need to find out how long it would take in the program itself...
Here is the code i made this yesterday
import itertools, math
import os
Alphabet = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") # Add or remove whatevs you think will be in the password you're cracking (example, [symbols])
counter = 1
CharLength = 1
range_num = int(raw_input("Enter range: "))
stopper = range_num + 1
filename = "bruteforce_%r.txt" % (range_num)
f = open(filename, 'a')
#n_1 = len(Alphabet)
#n_2 = n_1 - 1 # <-- total useless peice of garbage that could of been great in vurtual life
#n_3 = '0' * n_2
#n = '1' + n_3
x = range_num
y = len(Alphabet)
amount = math.pow(y, x)
total_items = math.pow(y, x)
for CharLength in range(range_num, stopper):
passwords = (itertools.product(Alphabet, repeat = CharLength))
for i in passwords:
counter += 1
percentage = (counter / total_items) * 100
amount -= 1
i = str(i)
i = i.replace("[", "")
i = i.replace("]", "")
i = i.replace("'", "")
i = i.replace(" ", "")
i = i.replace(",", "")
i = i.replace("(", "")
i = i.replace(")", "")
f.write(i)
f.write('\n')
print "Password: %r\tPercentage: %r/100\tAmount left: %r" % (i, int(percentage), amount)
if i == '0'* range_num:
print "*Done"
f.close()
exit(0)
else:
pass
This is my timer function i managed to make
#import winsound # Comment this out if your using linux
import os
import time
from sys import exit
print "This is the timer\nHit CTRL-C to stop the timer\nOtherwise just let it rip untill the time's up"
hours = int(raw_input('Enter the hours.\n>>> '))
os.system('clear') # Linux
#os.system('cls') # Windows
minutes = int(raw_input('Enter the minutes.\n>>> '))
os.system('clear') # linux
#os.system('cls') # Windows
seconds = int(raw_input('Enter the seconds.\n>>> '))
os.system('clear') # Linux
#os.system('cls') # Windows
stop_time = '%r:%r:%r' % (hours, minutes, seconds)
t_hours = 00
t_minutes = 00
t_seconds = 00
while t_seconds <= 60:
try:
os.system('clear') # Linux
#os.system('cls') # Windows
current_time = '%r:%r:%r' % (t_hours, t_minutes, t_seconds)
print current_time
time.sleep(1)
t_seconds+=1
if current_time == stop_time:
print "// Done"
#winsound.Beep(500,1000)
#winsound.Beep(400,1000)
break
elif t_seconds == 60:
t_minutes+=1
t_seconds=0
elif t_minutes == 60:
t_hours+=1
t_minutes = 00
except KeyboardInterrupt:
print "Stopped at: %r:%r:%r" % (t_hours, t_minutes, t_seconds)
raw_input("Hit enter to continue\nHit CTRL-C to end")
try:
pass
except KeyboardInterrupt:
exit(0)
Now i just cant figure out how to make this again but to calculate how long it will take rather than how long it is taking...
You cannot predict the time a script is going to take.
Firstly because two machines wouldn't run the script in the same time, and secondly, because the execution time on one machine can vary from on take to another.
What you can do, however, is compute the percentage of execution.
You need to figure out, for example, how many iterations your main loop will do, and calculate at each iteration the ratio current iteration count / total number of iterations.
Here is a minimalist example of what you can do:
n = 10000
for i in range(n):
print("Processing file {} ({}%)".format(i, 100*i//n))
process_file(i)
You can take it further and add the time as an additional info:
n = 10000
t0 = time.time()
for i in range(n):
t1 = time.time()
print("Processing file {} ({}%)".format(i, 100*i//n), end="")
process_file(i)
t2 = time.time()
print(" {}s (total: {}s)".format(t2-t1, t2-t0))
The output will look like this:
...
Processing file 2597 (25%) 0.2s (total: 519.4s)
Processing file 2598 (25%) 0.3s (total: 519.7s)
Processing file 2599 (25%) 0.1s (total: 519.8s)
Processing file 2600 (25%)
This is my implementation, which returns time elapsed, time left, and finish time in H:M:S format.
def calcProcessTime(starttime, cur_iter, max_iter):
telapsed = time.time() - starttime
testimated = (telapsed/cur_iter)*(max_iter)
finishtime = starttime + testimated
finishtime = dt.datetime.fromtimestamp(finishtime).strftime("%H:%M:%S") # in time
lefttime = testimated-telapsed # in seconds
return (int(telapsed), int(lefttime), finishtime)
Example:
import time
import datetime as dt
start = time.time()
cur_iter = 0
max_iter = 10
for i in range(max_iter):
time.sleep(5)
cur_iter += 1
prstime = calcProcessTime(start,cur_iter ,max_iter)
print("time elapsed: %s(s), time left: %s(s), estimated finish time: %s"%prstime)
Output:
time elapsed: 5(s), time left: 45(s), estimated finish time: 14:28:18
time elapsed: 10(s), time left: 40(s), estimated finish time: 14:28:18
time elapsed: 15(s), time left: 35(s), estimated finish time: 14:28:18
....
You will never ever be able to know exactly how long it is going to take to finish. The best you can do is calculate was percentage of the work you have finished and how long that has taken you and then project that out.
For example if you are doing some work on the range of numbers from 1 to 100 you could do something such as
start_time = get the current time
for i in range(1, 101):
# Do some work
current_time = get the current time
elapsed_time = current_time - start_time
time_left = 100 * elapsed_time / i - elapsed_time
print(time_left)
Please understand that the above is largely pseudo-code
The following function will calculate the remaining time:
last_times = []
def get_remaining_time(i, total, time):
last_times.append(time)
len_last_t = len(last_times)
if len_last_t > 5:
last_times.pop(0)
mean_t = sum(last_times) // len_last_t
remain_s_tot = mean_t * (total - i + 1)
remain_m = remain_s_tot // 60
remain_s = remain_s_tot % 60
return f"{remain_m}m{remain_s}s"
The parameters are:
i : The current iteration
total : the total number of iterations
time : the duration of the last iteration
It uses the average time taken by the last 5 iterations to calculate the remaining time. You can the use it in your code as follows:
last_t = 0
iterations = range(1,1000)
for i in iterations:
t = time.time()
# Do your task here
last_t = time.time() - t
get_remaining_time(i, len(iterations), last_t)
I have a database column the holds timestamps in UNIX format, I am looking for a way to compare those timestamps to a timestamp from the time right now and print how many seconds/hours/days since the original timestamp.
Just to confirm I am NOT looking for a conversion from 1489757456 to 03/17/2017 # 1:30pm. I AM looking for a conversion from 1489757456 to 1m ago/2hr ago/3d ago ect.
datetime.datetime.fromtimestamp()
to convert your unix timestamp to a datetitme
datetime.datetime.now()
to get the current datetime
dateutil.relativedelta.relativedelta(dt1, dt2, ...)
to get the difference with respect to leap years.
References:
https://docs.python.org/3.6/library/datetime.html
http://dateutil.readthedocs.io/en/stable/relativedelta.html
Function, like this will generate output for hours, mins and seconds from seconds number.
def secondsToHms(d):
d = int(d);
h = math.floor(d / 3600)
m = math.floor(d % 3600 / 60)
s = math.floor(d % 3600 % 60)
htext = " hour, " if h == 1 else " hours, "
hDisplay = str(h) + htext if h > 0 else ""
mtext = " minute, " if m == 1 else " minutes, "
mDisplay = str(m) + mtext if m > 0 else ""
stext = " second" if s == 1 else " seconds"
sDisplay = str(s) + stext if s > 0 else ""
return hDisplay + mDisplay + sDisplay;
For example:
secondsToHms(344334)
>> 95.0 hours, 38.0 minutes, 54.0 seconds
So you can add your preferred formatting and also add days/months if needed in similar fashion.