Creating and naming files with a while function - python

i'm trying to create files, one for each day of the year, and I was thinking I would use while or for for this. but it doesn't seem to work since I'm mixing numbers and letters.
def CreateFile():
date = 101
#this is supposed to be 0101 (first of januar, but since i can't start with a 0 this had to be the other option)
while date <= 131:
name = (date)+'.txt'
date += 1
CreateFile()

You can't concatenate strings and integers:
name = date + '.txt' # TypeError
but you can use str.format to create the filename:
name = "{0}.txt".format(date)
Using str.format also allows you to force four digits, including the leading zero:
>>> "{0:04d}.txt".format(101)
'0101.txt'
(see the documentation for more on formatting options).
Finally, given that you know how many times you will loop, I would recommend a for loop with range here, to avoid initialising and incrementing date manually:
for date in range(101, 132):
name = "{0:04d}.txt".format(date)
...

Related

sorting according to time sequence [duplicate]

I'm just starting out with Python and wondering how I would go about sorting this
list from the earliest time to the latest.
('5:00PM','2:00PM','7:00AM','8:45PM','12:00PM')
Any help is appreciated.
In python3 with standard library only:
import time
hours = ('5:00PM','2:00PM','7:00AM','8:45PM','12:00PM')
format = '%I:%M%p'
time_hours = [time.strptime(t, format) for t in hours]
result = [time.strftime(format, h) for h in sorted(time_hours)]
assert result == ['07:00AM', '12:00PM', '02:00PM', '05:00PM', '08:45PM']
I recommend that you install the PyPi DateTime package and use those facilities for whatever manipulation you desire. The problem at hand would look something like:
stamps = ('5:00PM','2:00PM','7:00AM','8:45PM','12:00PM')
DT_stamps = [DateTime(s) for s in stamps]
DT_stamps.sort()
Implementation details are left as an exercise for the student. :-)
If the times are always going to be in that format, you could split the times into subsections.
x = "12:30PM"
# Use python's string slicing to split on the last two characters
time, day_half = x[:-2], x[-2:]
# Use python's string.split() function to get the difference between hours and minutes
# Because "11" < "2" for strings, we need to convert them to integers
hour, minute = [int(t) for t in time.split(":")]
# Get the remainder because 12 should actually be 0
hour = hour % 12
# Output it as a tuple, which sorts based on each element from left to right
sortable = (day_half, hour, minute)
#: ("PM", 12, 30)
To wrap it all up, use something like:
def sortable_time(time_str):
time, day_half = time_str[:-2], time_str[-2:]
hour, minute = [int(t) for t in time.split(":")]
hour = hour % 12
return day_half, hour, minute
# When sorting, use `key` to define the method we're sorting with
# (The returned list however, will be filled with the original strings)
result = sorted(your_time_list, key=sortable_time)
#: ['7:00AM', '12:00PM', '2:00PM', '5:00PM', '8:45PM']
If you're not guaranteed to have the two letters at the end, or the colon in the middle, you're best off using a library like what is suggested by Prune.
What you're showing isn't a list of times, it's a tuple of strings. Tuples are immutable and can't be sorted, only mutable collections like lists can be. So first you need to convert your tuple to a list:
times = ['5:00PM','2:00PM','7:00AM','8:45PM','12:00PM']
You could try sorting this list now, but the strings won't sort the way you expect. Instead, you need to create a custom sort function that will temporarily convert the values in the list to struct_time objects and sort using those.
import time
time_format = '%I:%M%p' # match hours, minutes and AM/PM
def compare_as_time(time_str1, time_str2):
# parse time strings to time objects
time1 = time.strptime(time_str1, time_format)
time2 = time.strptime(time_str2, time_format)
# return comparison, sort expects -1, 1 or 0 to determine order
if time1 < time2:
return -1
elif time1 > time2:
return 1
else:
return 0
Now you can call sorted() and pass in your list and your custom comparison function and you'll get a list of strings back, sorted by the time in those strings:
sorted_times = sorted(times, compare_as_time)
Note for Python 3: The previous example assumes Python 2. If you're using Python 3, you'll need to convert the comparison function to a key function. This can be done using functools.cmp_to_key() as follows:
form functools import cmp_to_key
sorted_times = sorted(times, key=cmp_to_key(compare_as_time))

Extract numbers from a string in python without the use of isdigit or re. tools

Let's say I have a string of integers generated by user input, where each integer is separated by a space (Code below for example)...
How can I search through that string and store each integer separately for use later on in the program? (I.E. Assigning each integer to its own variable) I can't use isdigit and cant use re tools, and I can't store the ints into a list.
userEntry = input("Please enter a Fahrenheit temperature: ")
for i in range(4):
userEntry += " " + input("Please enter another fahrenheit:")
Things I AM allowed to use: string methods, index find/search methods, for loops, if statements, while loops.
Something like this will parse the string into space-separated strings, using slices... (I notice the first answer came in while I was working on this, but this is slightly different, so...)
def extractor(mystr):
start = 0
for a in range(len(mystr)):
if mystr[a] == ' ' or mystr[a] == len(mystr) - 1:
temp = mystr[start:a]
print(temp)
start = a + 1
This is more like a C approach, very un-Pythonic, but standard programming fare. If you will only ever have 5 user entries, this is perhaps manageable. If you can't use a list of those variables, or if you have an unknown number of user entries, or if you have to check to make sure the user actually entered a digit and not a letter, then more work is required, but that's the basic C-string parser. Useful to know if you ever want to dive into Python internals I suppose.
If you need to convert each extracted string to an int, and exceptions are allowed, place this inside the if statement to check for type correctness:
try:
myvar1 = int(temp)
except ValueError:
print("Not an int")
Note that if you absolutely cannot use lists, (*or exec as in the above answer) then the only likely option is to keep slicing off the end of the string, i.e you'd have to do something like the following at the end of each if statement, then write that for loop out 4 more times, changing the variable name each time manually.
mystr = mystr[start:len(mystr)]
break
This will of course not work if you have a variable number of user entries. And is incredibly tedious... I suspect the instructor may have intended something different. Note that the real-world process for all that is just:
result = [int(x) for x in mystr.split(' ') if x.isdigit()]
I am not sure what your use case is, and I can not think of a way where you can assign the numbers to variable in a loop, which is what you have to do if you are not allowed to use a loop. The only way I can think of is exec and I do not feel that is allowed for your task. Regardless, I am posting the answer, in case it is usable:
last_space_index = 0
characters_checked = 0
var_num = 1
userEntry = "12.8 -15.8 125.9 0 -40.0"
for character in userEntry:
characters_checked += 1
if character == ' ':
number = float(userEntry[last_space_index:characters_checked])
var_name = 'var'+str(var_num)
var_num += 1
expression = var_name + ' = number'
# expression becomes 'var1 = number'
exec(expression)
last_space_index = characters_checked
last_number = float(userEntry[last_space_index:])
var_name = 'var'+str(var_num)
expression = var_name + ' = last_number'
exec(expression)
# if you know the number of variables you are going to get
print(var1, var2, var3, var4, var5)
# else:
# for i in range(1,var_num+1):
# var_name = 'var'+str(i)
# command = 'print('+var_name+')'
# exec(command)
Output:
>>> 12.8 -15.8 125.9 0 -40.0
You can replace print with whatever you actually want to do.
And this is completely futile if you are allowed to use dictionary, sets or tuple.

How to sort a list of times

I'm just starting out with Python and wondering how I would go about sorting this
list from the earliest time to the latest.
('5:00PM','2:00PM','7:00AM','8:45PM','12:00PM')
Any help is appreciated.
In python3 with standard library only:
import time
hours = ('5:00PM','2:00PM','7:00AM','8:45PM','12:00PM')
format = '%I:%M%p'
time_hours = [time.strptime(t, format) for t in hours]
result = [time.strftime(format, h) for h in sorted(time_hours)]
assert result == ['07:00AM', '12:00PM', '02:00PM', '05:00PM', '08:45PM']
I recommend that you install the PyPi DateTime package and use those facilities for whatever manipulation you desire. The problem at hand would look something like:
stamps = ('5:00PM','2:00PM','7:00AM','8:45PM','12:00PM')
DT_stamps = [DateTime(s) for s in stamps]
DT_stamps.sort()
Implementation details are left as an exercise for the student. :-)
If the times are always going to be in that format, you could split the times into subsections.
x = "12:30PM"
# Use python's string slicing to split on the last two characters
time, day_half = x[:-2], x[-2:]
# Use python's string.split() function to get the difference between hours and minutes
# Because "11" < "2" for strings, we need to convert them to integers
hour, minute = [int(t) for t in time.split(":")]
# Get the remainder because 12 should actually be 0
hour = hour % 12
# Output it as a tuple, which sorts based on each element from left to right
sortable = (day_half, hour, minute)
#: ("PM", 12, 30)
To wrap it all up, use something like:
def sortable_time(time_str):
time, day_half = time_str[:-2], time_str[-2:]
hour, minute = [int(t) for t in time.split(":")]
hour = hour % 12
return day_half, hour, minute
# When sorting, use `key` to define the method we're sorting with
# (The returned list however, will be filled with the original strings)
result = sorted(your_time_list, key=sortable_time)
#: ['7:00AM', '12:00PM', '2:00PM', '5:00PM', '8:45PM']
If you're not guaranteed to have the two letters at the end, or the colon in the middle, you're best off using a library like what is suggested by Prune.
What you're showing isn't a list of times, it's a tuple of strings. Tuples are immutable and can't be sorted, only mutable collections like lists can be. So first you need to convert your tuple to a list:
times = ['5:00PM','2:00PM','7:00AM','8:45PM','12:00PM']
You could try sorting this list now, but the strings won't sort the way you expect. Instead, you need to create a custom sort function that will temporarily convert the values in the list to struct_time objects and sort using those.
import time
time_format = '%I:%M%p' # match hours, minutes and AM/PM
def compare_as_time(time_str1, time_str2):
# parse time strings to time objects
time1 = time.strptime(time_str1, time_format)
time2 = time.strptime(time_str2, time_format)
# return comparison, sort expects -1, 1 or 0 to determine order
if time1 < time2:
return -1
elif time1 > time2:
return 1
else:
return 0
Now you can call sorted() and pass in your list and your custom comparison function and you'll get a list of strings back, sorted by the time in those strings:
sorted_times = sorted(times, compare_as_time)
Note for Python 3: The previous example assumes Python 2. If you're using Python 3, you'll need to convert the comparison function to a key function. This can be done using functools.cmp_to_key() as follows:
form functools import cmp_to_key
sorted_times = sorted(times, key=cmp_to_key(compare_as_time))

Python Dynamic value in text

count = 1
maxcount = 6
while(count <= maxcount):
print locals()["test_"+str(count)]+str(".png")
count += 1
I was hoping for the output
test_1.png
test_2.png
test_3.png
test_4.png
test_5.png
test_6.png
Instead I get an error
KeyError: 'test_1'
Also, is it possible to add a 0 after the _ if the value is less than 10?
I am using this loop for saving files, but figured that this MWE would be less labour and would easily apply to my issue
You are getting that error because you have not created a variable named 'test_1' in your local scope. Instead of using a while loop, it is easier to use a for loop. Also, there's a thing called string formatting, which is easier to use than string concatenation.
maxcount = 6
for i in range(1, maxcount+1):
filename = 'test_{}.png'.format(i)
with open(filename, 'r') as f:
# do stuff

Making string series in Python

I have a problem in Python I simply can't wrap my head around, even though it's fairly simple (I think).
I'm trying to make "string series". I don't really know what it's called, but it goes like this:
I want a function that makes strings that run in series, so that every time the functions get called it "counts" up once.
I have a list with "a-z0-9._-" (a to z, 0 to 9, dot, underscore, dash). And the first string I should receive from my method is aaaa, next time I call it, it should return aaab, next time aaac etc. until I reach ----
Also the length of the string is fixed for the script, but should be fairly easy to change.
(Before you look at my code, I would like to apologize if my code doesn't adhere to conventions; I started coding Python some days ago so I'm still a noob).
What I've got:
Generating my list of available characters
chars = []
for i in range(26):
chars.append(str(chr(i + 97)))
for i in range(10):
chars.append(str(i))
chars.append('.')
chars.append('_')
chars.append('-')
Getting the next string in the sequence
iterationCount = 0
nameLen = 3
charCounter = 1
def getString():
global charCounter, iterationCount
name = ''
for i in range(nameLen):
name += chars[((charCounter + (iterationCount % (nameLen - i) )) % len(chars))]
charCounter += 1
iterationCount += 1
return name
And it's the getString() function that needs to be fixed, specifically the way name gets build.
I have this feeling that it's possible by using the right "modulu hack" in the index, but I can't make it work as intended!
What you try to do can be done very easily using generators and itertools.product:
import itertools
def getString(length=4, characters='abcdefghijklmnopqrstuvwxyz0123456789._-'):
for s in itertools.product(characters, repeat=length):
yield ''.join(s)
for s in getString():
print(s)
aaaa
aaab
aaac
aaad
aaae
aaaf
...

Categories