鱼C论坛

 找回密码
 立即注册
查看: 1336|回复: 2

[已解决]求助一道python作业~

[复制链接]
发表于 2020-12-1 13:14:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

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

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


  1. def is_decoy(lines):
  2.     if lines==[]:
  3.         return False
  4.     elif (lines[0][0]).upper() == lines[0][0] and lines[0][0] == 'A' or lines[0][0] == 'C' or lines[0][0] =='M' or lines[0][0] =='E':
  5.         return True
  6.     else:
  7.         return is_decoy(lines[1:])
  8.         return False
  9.         
  10. #emm 我弄了两种,但还是不对
  11. def get_targets(path):
  12.   lst = []
  13.   #lst2 = []
  14.   files = os.listdir(path)
  15.   for file in files:
  16.     sub_path =  path+'/'+file
  17.     if os.path.isfile(sub_path):
  18.       #print(sub_path)
  19.       fp = open(sub_path)
  20.       fp1 = fp.readlines()
  21.       print(fp1)
  22.       ##for ch in fp1:
  23.         #print(ch)
  24.       if is_decoy(fp1) == False:
  25.         lst.append(sub_path)
  26.         return lst
  27.       
  28.     else:
  29.       get_targets(sub_path)

  30. def get_targets(path):
  31.   lst = []
  32.   lst2 = []
  33.   files = os.listdir(path)
  34.   for file in files:
  35.     sub_path =  path+'/'+file
  36.     if os.path.isfile(sub_path):
  37.       #print(sub_path)
  38.       lst.append(sub_path)
  39.       #print(lst)
  40.       
  41.       fp = open(sub_path)
  42.       fp1 = fp.readlines()
  43.       
  44.       lst2.append(fp1)
  45.       
  46.       #print(lst2)
  47.       
  48.         
  49.     else:
  50.       get_targets(sub_path)
  51.       
  52.   for i in range(len(lst2)):
  53.     if is_decoy(lst2[i]) == True:
  54.       lst.remove(lst[i])
  55.   return lst
复制代码


————————————————————————————————————————————
以下是原问题:
Problem B  Checking 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 C  Searching 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']

最佳答案
2020-12-1 13:56:50
你把问题想复杂了。直接在get_targets函数的if下添加上打开文件、读取文件,判断文件每行首字母即可,其他的不用动。
is_decoy使用递归多累啊,直接一个循环搞定。
  1. import os
  2. def is_decoy(lines):
  3.     if not lines:
  4.         return False
  5.     for line in lines:
  6.         if line[0] in ['A','C','M','E']:
  7.             return True
  8.     return False
  9. def get_targets(path):
  10.     for file in os.listdir(path):
  11.         if os.path.isfile(path+'/'+file):
  12.             thisfile=open(path+os.sep+file,'r')
  13.             filelines=thisfile.readlines()
  14.             thisfile.close()
  15.             if is_decoy(filelines):
  16.                 print(path+'/'+file)  #This is a file, print out the path
  17.         else:
  18.             get_targets(path+'/'+file)  #Go into a subdirectory
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-12-1 13:56:50 | 显示全部楼层    本楼为最佳答案   
你把问题想复杂了。直接在get_targets函数的if下添加上打开文件、读取文件,判断文件每行首字母即可,其他的不用动。
is_decoy使用递归多累啊,直接一个循环搞定。
  1. import os
  2. def is_decoy(lines):
  3.     if not lines:
  4.         return False
  5.     for line in lines:
  6.         if line[0] in ['A','C','M','E']:
  7.             return True
  8.     return False
  9. def get_targets(path):
  10.     for file in os.listdir(path):
  11.         if os.path.isfile(path+'/'+file):
  12.             thisfile=open(path+os.sep+file,'r')
  13.             filelines=thisfile.readlines()
  14.             thisfile.close()
  15.             if is_decoy(filelines):
  16.                 print(path+'/'+file)  #This is a file, print out the path
  17.         else:
  18.             get_targets(path+'/'+file)  #Go into a subdirectory
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2020-12-1 13:57:42 | 显示全部楼层
  1. import os
  2. def get_targets(path):
  3.     try:
  4.         for each in os . listdir(path):
  5.             x = os . path . join(path , each)
  6.             if os . path . isfile(x):
  7.                 fn = x . split(os . path . sep)[- 1]
  8.                 if not fn[0] in 'ACEM':
  9.                     print(x)
  10.             elif os . path . isdir(x):
  11.                 get_targets(x)               
  12.     except:
  13.         print("Can't access the path :" , path)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-20 17:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表