I would like to make a program that can copy one file(e.g. images) to another directory which contains several folders. By just copying all the images to another directory is easy but I wanted it to be one image copies to one folder.
I looped every single element in both directory and globalized them. I tried copying one file into folder but got errors. I think the main problem I cannot do it is because I lack of the idea how to just copy one file to one folder while looping. I hope you can give me some advice on this matter.
import os
import shutil
path = os.listdir('C:\\Users\\User\\Desktop\\img')
#dst1 = os.path.abspath('C:\\Users\\User\\Desktop\\abc')
idst = os.listdir('C:\\Users\\User\\Desktop\\abc')
def allimgs():
counter = 0
for imgs in path:
if imgs.endswith('.JPG'):
counter += 1
#if hits the 24th images then stop and
#copy the first until 24 to another 24 folders one by one
if counter > 24:
break
else:
src = os.path.join('C:\\Users\\User\\Desktop\\img',imgs)
def allfolders():
for folders in idst:
if folders.endswith('.db'):
continue #to skip the file ends with .db
dst = os.path.join('C:\\Users\\User\\Desktop\\abc',folders)
shutil.copy(allimgs(),allfolders()) #here is where i stuck
First of all, make both functions return lists of strings which contain the full paths of the images which will be copied, and the directories to where they will be copied. Afterwards, save the results of allimgs() and allfolders() into variables and loop through them.
Here is how the first function should look like:
def allimgs():
ret = []
counter = 0
for imgs in path:
if imgs.endswith('.JPG'):
counter += 1
#if hits the 24th images then stop and
#copy the first until 24 to another 24 folders one by one
if counter > 24:
break
else:
src = os.path.join('C:\\Users\\User\\Desktop\\img',imgs)
ret.append(src)
return ret
(I left the other one for you as an exercise)
Then loop over them:
for image_path in allimgs():
for folder_path in allfolders():
shutil.copy(image_path, folder_path)
Related
I am currently trying read a directory and determine how many files total are in each of its top level directory, including each of their subdirectory. The "folders check scan" function is supposed to reach further down into subdirectories and count the files in each by calling itself, but it only counts the files in the first level of subdirectories. Is there something I am missing?
import os
import csv
def folders_check_scan(value):
count = 0
for y in os.scandir(value):
if y.is_dir():
folders_check_scan(y)
elif y.is_file():
count += 1
return count
#function that takes summary of what is in repository
def list_files(startpath):
#get number of folders in the first level of this directory
print(len(next(os.walk(startpath))[1]))
#gets top level folders in directory
directory = next(os.walk(startpath))[1]
print(startpath)
directory_path = []
for b in directory:
newline = startpath + "\\" + b
directory_path.append(newline)
#call function to take record of number of files total in directory
for x in directory_path:
count = folders_check_scan(x)
print(x)
print(count)
It looks like you aren't storing the result of the recursive call:
if y.is_dir():
count += folders_check_scan(y)
elif y.is_file():
count += 1
This code is working well, but it keep replacing the previous snapshot in the location I dont want.
How can I keep taking the snapshot every second without replacing the previous shot, and how can I specify the folder for these png going to be saved?
player=vlc.MediaPlayer('rtsp://admin:888999#thesport.fujiko.biz:554/unicast/c3/s0/live')
player.play()
while 1:
time.sleep(1)
player.video_take_snapshot(0, '.snapshot.tmp.png', 0, 0)
It's easy, every time you get a frame, store it in different variable, like this
As the one comment says, you need to change the filename for each subsequent save. I would create a count in your loop and then format the value to the string that is the filename. For example:
player=vlc.MediaPlayer('rtsp://admin:888999#thesport.fujiko.biz:554/unicast/c3/s0/live')
player.play()
i = 0
while 1:
time.sleep(1)
player.video_take_snapshot(0, '.snapshot_{}.tmp.png'.format(i), 0, 0)
i += 1
If you simply specify a directory name, rather than a filename, vlc will create a unique file name for you, based on the date and time.
i.e.
file:///home/rolf/vlcsnap-2020-08-14-10h43m06s020.png
file:///home/rolf/vlcsnap-2020-08-14-10h43m08s936.png
#Video Snapshot
def OnSnapShot(self,evt):
media_state = self.player.get_state()
if media_state.value < 3 or media_state.value > 4:
return
if os.path.isfile(self.currentlyplaying):
dir_name = os.path.dirname(self.currentlyplaying)
else:
dir_name = self.home_dir
snapshot_size = self.player.video_get_size(0)
x=self.player.video_take_snapshot(0, dir_name,snapshot_size[0],snapshot_size[1])
if x == 0:
Notify(self,"Snapshot","Image saved in "+dir_name)
I am trying to make an experiment where a folder is scanned for images. For each trial, a target is shown and some (7) distractor images. Afterward, in half the trials people are shown the target image and in the other half, they are shown an image that wasn't in the previous display.
My current code sort of works, but only if there are fewer trials than objects:
repeats = 20
# Scan dir for images
jpgs = []
for path, dirs, files in os.walk(directory):
for f in files:
if f.endswith('.jpg'):
jpgs.append(f)
# Shuffle up jpgs
np.random.shuffle(jpgs)
# Create list with target and probe object, Half random, half identical
display = []
question = []
sameobject = []
position = np.repeat([0,1,2,3,4,5,6,7], repeats)
for x in range(1,(repeats*8)+1):
display.append(jpgs[x])
if x % 2 == 0:
question.append(jpgs[-x])
sameobject.append(0)
else:
question.append(jpgs[x])
sameobject.append(1)
# Concatonate objects together
together = np.c_[display,question,position,sameobject]
np.random.shuffle(together)
for x in together:
# Shuffle and set image
np.random.shuffle(jpgs)
myList = [i for i in jpgs if i != together[trial,0]]
myList = [i for i in myList if i != together[trial,1]]
# Set correct image for target
myList[int(together[trial,2])] = together[trial,0]
First of all, I am aware that this is horrible code. But it gets the job done coarsely. With 200 jpgs and a repeat of 20, it works. If repeat is set to 30 it crashes.
Here is an example with repeat too high:
File "H:\Code\Stims\BetaObjectPosition.py", line 214, in <module>
display.append(jpgs[x])
IndexError: list index out of range
Is there a way to update my code in a way that allows more trials while all objects are used as evenly as possible (one object should not be displayed 3 times while another is displayed 0) over an entire experiment?
Full, reproducible example
Bonus points if anyone can see an obvious way to balance the way the 7 distractor images are selected too.
Thanks for taking your time to read this. I hope you can help me onwards.
The solution that changes your code the least should be to change each call of jpgs[x] to jpgs[x % len(jpgs)]1. This should get rid of the IndexError; it basically wraps the list index "around the edges", making sure it's never to large. Although I'm not sure how it will interact with the jpgs[-x] call.
An alternative would be to implement a class that produces a longer sequence of objects from a shorter one.
Example:
from random import shuffle
class InfiniteRepeatingSequence(object):
def __init__(self, source_list):
self._source = source_list
self._current = []
def next(self):
if len(self._current) == 0:
# copy the source
self._current = self._source[:]
shuffle(self._current)
# get and remove an item from a list
return self._current.pop()
This class repeats the list indefinitely. It makes sure to use each element once before re-using the list.
It can easily be turned into an iterator (try changing next to __next__). But be careful since the class above produces an infinite sequence of elements.
1 See "How does % work in Python?" for an explanation about the modulo operator.
Edit: Added link to modulo question.
I have a folder structure as follows:
TestOpt > roll_1_oe_2017-03-10
> roll_2_oe_2017-03-05
: :
> roll_600_oe_2012-05-10
TestOpt is the main folder and roll__oe_ are the sub folders which hold .csv records that I am looking to interrogate if they are inside a certain range of rolls.
I am trying to analyse the file names as I only wish to interrogate records where he sub folder has a roll greater than say 500 (so I would like to interrogate the records in folder roll_500_oe_2012-05-10 to roll_600_oe_2012-05-10 inclusive)
I have tried splitting the folder name by "_" so I can retrieve the roll number, but I am having a problem in that I can't get the code past the TestOpt filename. Please see below for code:
rootdir = r'C:/Users/Stacey/Documents/TestOpt/'
#cycle through all the folders in the TestOpt directory
for dirName,sundirList, fileList in os.walk(rootdir):
#print('Found directory: %s' % dirName)
#split the file name by _
x = dirName.split("_")
print('list length ',len(x))
#If the length of the folder name is greater than 1 its not the TestOpt folder
if len(x) > 1:
#the second split list element is the roll number
roll = x[2]
#interrogate records in folder id roll is greater or equal to 500
if roll >= 500:
print('myroll1 ',roll)
for fname in fileList:
do something....
If anyone can offer any assistance I would be most grateful
Thanks
You'll need to explicitly state that roll is an integer, as the list made from the filename is a list of strings.
Use roll = int(x[2]).
I have a folder that holds a certain number of folders and they all contain a folder within a folder, I want to check the number of subdirectories in each of these folders. I tried using os.walk and adding +1 each time it comes across a folder. But this returns the sub-directory count of all the directories, I want them separately for each folder.
for eg, lets say I have folder A1 and A2.
A1: subfolder1 -(contains)-> subfolder2
A2: subfolder1 -(contains)-> subfolder2 -(contains)-> subfolder3 -(contains)-> subfolder4
Right now my code returns 6 instead of 2 and 4.
def count_folders(path):
count=0
for dir in os.listdir(path):
nDir = os.path.join(path,dir)
if os.path.isdir(nDir):
for dirs in os.walk(nDir):
if os.path.isdir(dirs[0]):
count+=1
print count
This works fine when I try it here:
def count_folders(path):
count = 0
for root, dirs, files in os.walk(pth):
count += len(dirs)
return count
To understand how this works try to print "root", "dirs" and "files" one by one.
Documentation
A short tutorial
Maybe you can comment out these three lines, that can prevent the count variable to count the number of 'subfolders of subfolder'.
import os
def count_folders(path):
count=0
for dir in os.listdir(path):
nDir = os.path.join(path,dir)
if os.path.isdir(nDir):
count+=1
# for dirs in os.walk(nDir):
# if os.path.isdir(dirs[0]):
# count+=1
print count
If you are looking for the count of subdirs inside each subdir in path you can try this function:
def count_folders(path):
count={}
for dir in os.listdir(path):
nDir = os.path.join(path,dir)
if os.path.isdir(nDir):
c = 0
for d in os.listdir(nDir):
if os.path.isdir(os.path.join(nDir, d)):
c+=1
count[nDir] = c
print count
It returns a dictionary with the count of subdirs inside each subdir of path.