黄焖馒头 发表于 2020-12-1 13:14:47

求助一道python作业~

本帖最后由 黄焖馒头 于 2020-12-1 13:21 编辑

两道连环题目请求解答,题目简单来说是这样的:
第一道题:is_decoy函数是用来判断一行的首字母是否包含A/C/M/E四个字母,如果包含则返回True。
第二道题:get_targets()函数可以搜索一系列在一个嵌套目录结构中的文档并将文件路径+文件名打印出来,修改get_targets()函数,在函数内运用is_decoy()函数,找出文件中任意一行首字母都不包含A/C/M/E四个字母的文件,并打印他们的路径+文件名。
import os
def get_targets(path):
    for file in os.listdir(path):
      if os.path.isfile(path+'/'+file):
            print(path+'/'+file)#This is a file, print out the path
      else:
            get_targets(path+'/'+file)#Go into a subdirectory

在第二题卡住了,只能成功一部分。每个文件的path不晓得怎么放在一个list里。每个文件对于的list不知道怎么放到一个大的list里。


def is_decoy(lines):
    if lines==[]:
      return False
    elif (lines).upper() == lines and lines == 'A' or lines == 'C' or lines =='M' or lines =='E':
      return True
    else:
      return is_decoy(lines)
      return False
      
#emm 我弄了两种,但还是不对
def get_targets(path):
lst = []
#lst2 = []
files = os.listdir(path)
for file in files:
    sub_path =path+'/'+file
    if os.path.isfile(sub_path):
      #print(sub_path)
      fp = open(sub_path)
      fp1 = fp.readlines()
      print(fp1)
      ##for ch in fp1:
      #print(ch)
      if is_decoy(fp1) == False:
      lst.append(sub_path)
      return lst
      
    else:
      get_targets(sub_path)

def get_targets(path):
lst = []
lst2 = []
files = os.listdir(path)
for file in files:
    sub_path =path+'/'+file
    if os.path.isfile(sub_path):
      #print(sub_path)
      lst.append(sub_path)
      #print(lst)
      
      fp = open(sub_path)
      fp1 = fp.readlines()
      
      lst2.append(fp1)
      
      #print(lst2)
      
      
    else:
      get_targets(sub_path)
      
for i in range(len(lst2)):
    if is_decoy(lst2) == True:
      lst.remove(lst)
return lst


————————————————————————————————————————————
以下是原问题:
Problem BChecking for Decoys
You are a detective trying to stop a powerful criminal organization from stealing some of the world’s treasures and monuments.How your enemies are capable of stealing entire buildings and even larger objects is not fully understood, but you have acquired documents containing information about their next potential targets.

First, though, you have learned that some of the documents are decoys.If any of the lines in the document start with the letters 'A', 'C', 'M', or 'E', then the document is a decoy and can be ignored.Write a recursive function called is_decoy(lines), which takes in a list of strings lines representing each line of some document, and returns the boolean value True if the document is a decoy (that is, if one of the strings in the list starts with 'A', 'C', 'M', or 'E'), or False otherwise.

You only need to check for the capital letters'A', 'C', 'M', or 'E': a line starting with the lowercase version of those letters does not flag the document as a decoy.

Hints:
●        You don’t have to do any File I/O for this problem, that’s handled in Part C.

Constraints:
●        The is_decoy function must be implemented using recursion.Do not use any loop constructs (while or for).

Examples:
>>> is_decoy(['One line\n', 'Two lines\n', 'Three lines\n', 'Four lines'])
False

>>> is_decoy(['Here is a line\n', 'Another line, starting with A\n', 'One more line'])
True

>>> is_decoy([])
False

>>> is_decoy(['More examples\n', 'Here there are two problem lines\n', 'Not this one\n', 'Or this one\n', 'Excellent'])
True






Problem CSearching all Files
Continuing from the previous question, you must now search through all of the documents and generate a list of the ones that represent targets of the evil organization.The problem is that the documents are not all in one directory: they’re in a nested directory structure, and could be in the top-level directory, or in subdirectories of that directory, or in subdirectories of those subdirectories, and so on.

The following code, given to you in the hw11.py template, uses recursion to print out all files in a nested directory structure, if given the filepath to the top-level directory:

import os
def get_targets(path):
    for file in os.listdir(path):
      if os.path.isfile(path+'/'+file):
            print(path+'/'+file)#This is a file, print out the path
      else:
            get_targets(path+'/'+file)#Go into a subdirectory


os.listdir generates a list of all of the names of all of the files and directories within some directory that we specify the filepath to, and os.path.isfile takes in the path to a file and returns True if it’s a file, or False if it’s a directory.For example, if given the directory structure below, with hw11.py in the same directory as root, then get_targets('root') would print out:

root/labs/lab1.txt
root/labs/lab2.txt
root/labs/lab3.txt
root/plans/vacation.txt
root/plans/evil/world_domination.txt
root/resume.txt
root/cat.jpg



Try out the function on some of the sample directories that were in the hw11.zip folder, to ensure that you understand what it currently does.If you’re not sure, ask a TA to explain it to you.

Then, alter the the get_targets function above so that rather than printing the paths to all of the files in the nested directory, it returns a list of the paths to all of the files that are NOT decoys (as defined in problem B).The order of the list does not matter.

Hints:
●        This problem uses both loops AND recursion: the loop is used to iterate through the files within each directory, while the recursive call is used to go deeper into one of the subdirectories.
●        You will need to open each file and read in the contents to determine whether or not it’s a decoy.
●        Use .readlines() to get all of the lines in each file to pass into your is_decoy function.

Constraints:
●        You must call your is_decoy function somewhere in get_targets.
●        Don’t import any modules other than os, and don’t use any os module methods other than those already used in the given function.

Examples (assumes that the directory structure given in hw11.zip is intact)
>>> get_targets('plans1')
['plans1/moon.txt', 'plans1/voyager1.txt']

>>> get_targets('plans2')
['plans2/South_America/amazon.txt']

>>> get_targets('plans3')
['plans3/Asia/India/taj_mahal.txt', 'plans3/Australia/sydney_opera_house.txt', 'plans3/North_America/Canada/Alberta/west_edmonton_mall.txt', 'plans3/North_America/Canada/Ontario/niagara_falls.txt', 'plans3/North_America/panama_canal.txt', 'plans3/North_America/United_States/Minnesota/lake_of_the_woods.txt']

sunrise085 发表于 2020-12-1 13:56:50

你把问题想复杂了。直接在get_targets函数的if下添加上打开文件、读取文件,判断文件每行首字母即可,其他的不用动。
is_decoy使用递归多累啊,直接一个循环搞定。
import os
def is_decoy(lines):
    if not lines:
      return False
    for line in lines:
      if line in ['A','C','M','E']:
            return True
    return False
def get_targets(path):
    for file in os.listdir(path):
      if os.path.isfile(path+'/'+file):
            thisfile=open(path+os.sep+file,'r')
            filelines=thisfile.readlines()
            thisfile.close()
            if is_decoy(filelines):
                print(path+'/'+file)#This is a file, print out the path
      else:
            get_targets(path+'/'+file)#Go into a subdirectory

jackz007 发表于 2020-12-1 13:57:42

import os
def get_targets(path):
    try:
      for each in os . listdir(path):
            x = os . path . join(path , each)
            if os . path . isfile(x):
                fn = x . split(os . path . sep)[- 1]
                if not fn in 'ACEM':
                  print(x)
            elif os . path . isdir(x):
                get_targets(x)               
    except:
      print("Can't access the path :" , path)
页: [1]
查看完整版本: 求助一道python作业~