python随机抽取人名_python实现艾宾浩斯背单词功能,实现自动提取单词、邮件发送,再也不用担心背单词啦...

已经完成了利用python爬虫实现定时QQ邮箱推送英文文章,辅助学习英语的项目,索性就一口气利用python多做一些自动化辅助英语学习的项目,对自己的编程能力和英文水评也有一定的帮助,于是在两天的努力下,我完成了今天的项目。

首先是艾宾浩斯记忆法,大家了解一下真的非常有效果(至少对于我来讲啦┑( ̄Д  ̄)┍)

当然,我也会把自己的项目上传到github上供大家指正,由于本人非常喜欢python和英语,所以后期也做很多将两者结合起来的项目。所以,如果大家对本项目有兴趣,希望体验或加入开发,又或者对它有一定的想法与意见,欢迎加入我最近组建的交流群。谢谢大家啦~~

https://qm.qq.com/cgi-bin/qm/qr?k=yWHTRdPppmHE_YiNeTbTlCtqiD2qPm97&authKey=2tcLazZwqjqHuUpnrpJR2DalP/izfPw9xw7g6CQnZHYe9ZEoB4p0kbkgQ/aSa/nq (二维码自动识别)

本项目主要是通过在事先准备好的excel单词文件中每天抽取单词,并反复使用QQ邮箱发送到自己的邮箱里提醒自己有一定规律的背单词,项目最大的难点有三。


  1. 对于csv文件的对应切片任务等操作
  2. 对于日志的记录
  3. 艾宾浩斯记忆法是一个周期性的过程,需要反复的计算。

当然,由于这个项目的文件还是比较多的,所以为了简化这个项目,我就先按照自己的开发思路来说,当然如果要自己来使用本项目还是要费一番心思读一读代码才好,因为在dataframe数据的处理部分随便拿一个小坑讲一下都是一篇文章( )所以,各位一定要耐心读下去鸭。


好了 show me the code


开发环境 :python3.6 IDEA : pycharm2019 阿里云ECS: centos7

接下来我们看一下项目路径,并注意对应进行解释: (忽略我拙略的变量英文,就是因为这样所以才好好学习英语鸭)

6fc13cebb27c646c60bd2954d86d8eee.png

分别来解释一下

data 目录: 用于存放日志文件,分别有data_log.csv和word.csv data_log.csv 用于每天随机抽取单词的时候避免抽取到重复的单词。 word.csv 是每天将每个单词的time时间数据记录进去进而用于计算单词复习的时间。

0502d97d6376529ebe497798dcf09596.png

*every_day_word* 目录: 用于存储每天随机抽取的单词机器词义等相关信息,并将其存储为csv格式,以对应的时间为文件名存储,同步在上面的data_log.csv的time索引内。

00a7eeb00c8a4080063a7dd966fc1901.png

___ word 目录 : 存储总的单词大表数据的目录,很简单。

059501f08c2cb983db97f64e0e1736e6.png

接下来就是我们的项目代码部分,如你所见项目代码都在项目的根目录处,

bc270d6841a18192cd126b6e7103ad6a.png

接下来我会一 一的说明这些代码,当然是以我自己的顺序,对了代码的详细解释在代码的注释里面,有任何疑问和想法可以加入上面的群来交流。


word_read_project.py


这一部包含了多个函数与变量,是项目文件处理的第一核心部分,主要难点在于dataframe的控制问题以及日志的读写问题,需要耐心的看完,推荐搭配pycharm专业版使用,非常方便。

#auther :keepython
import pandas as pd
import numpy as np
import os
import time
import randomword_file_path = 'word/六级核心词汇表(EXCEL表格).xls'
data_log_path = 'data/data_log.csv'
# data_log = pd.read_csv(data_log_path)
words = pd.read_excel(word_file_path,header=0)
# print(len(words)+1)#求出一共多少列,从1开始算
# print(words.columns)#列索引名称
# print(words.index)#行索引名称words_index = words.index#函数功能:传入随机生成的单词索引,返回单词dataframe相关信息
def find_word(random_word_index,words):print(type(random_word_index))#根据随机单词的索引导出单词的相关信息random_words = words.loc[list(random_word_index)]# print(random_words)return random_words#函数功能: 在进行random_80函数操作以后对word.csv进行同步记录,注意传进来的必须是列表的形式
def word_csv_log(random_words,time_stamp):word_path = 'data/word.csv'word_log = pd.read_csv(word_path,index_col=0)#读取单词日志文件,同时将索引设置为对应的时间for random_word in random_words:#将对应的随机抽取的单词5min,30min,12hour分别标记为1word_log.loc['time'][random_word] = time_stampword_log.iloc[0:3][random_word][0] = 1word_log.iloc[0:3][random_word][1] = 1word_log.iloc[0:3][random_word][2] = 1word_log.to_csv(word_path)print('标记完成'.center(40,'='))#函数功能:读取日志已经选择的单词索引内容返回列表
def data_log_read(data_log_path):data_logs = pd.read_csv(data_log_path)data_log_index = np.array(data_logs).tolist()return data_log_index#函数功能:通过索引提取dataframe中的行,返回对应的dataframe数据方便生成csv文件
def random_80_word_to_csv(random_index,words):random_80_word_df = words.iloc[random_index,:]return random_80_word_df#函数功能:随机从传入的单词索引列表中抽取80个词
def random_80_word(words_indexs,words):data_log_path = 'data/data_log.csv'# print(type(words_index))#显示传入索引格式try:data_log_index = data_log_read(data_log_path)#返回日志中的索引words_index = [i for  i in words_indexs if i not in data_log_index]except :words_index= list(words_indexs)random_word = random.sample(list(words_index),80)#同时记录被选中的索引数据print(len(random_word))random_words = find_word(random_word,words)[['单词']]random_words = np.array(random_words).tolist()#这里是列表嵌套的形式需要解套random_words = [i[0] for i in random_words]#将随机抽取的#time模块的使用还要考虑到后面everyday_word.csv文件命名的问题,文件名称中不能有特殊符号time_stamp = time.strftime("%Y-%m-%d-%H-%M", time.localtime())#使用time模块以对应的年-月-日-小时-分钟的形式返回的数据为字符串every_day_word_path = 'every_day_word/'+str(time_stamp)+'.csv'random_80_word_df = random_80_word_to_csv(random_word,words)#在这一步调用函数同时生成对应random文件数据word_csv_log(random_words,time_stamp)print(type(random_80_word_df))random_80_word_df.to_csv(every_day_word_path)data = {time_stamp: random_word}#用于data_log.csv路径不存在情况if os.path.exists(data_log_path):#将今天生成的随机单词存入日志csv文件中备用datas = pd.read_csv(data_log_path)datas.loc[:, str(time_stamp)] = pd.Series(random_word)# datas[time_stamp] = random_word #注意,由于日期的原因无法输入列索引相同的数据,dataframe本质有点像优化的数据库datas.to_csv(data_log_path,index=False)#注意这里的mode的设置,必须设置为覆盖模式else:datas = pd.DataFrame(data)datas.to_csv(data_log_path, index=False)return random_word,every_day_word_path#将随机索引的80个词返回random_word_index,every_day_word_path = random_80_word(words_indexs=words_index,words= words)
# print(random_word_index)random_words_df = find_word(random_word_index,words)#返回的依然是dataframe格式的数据
# print(type(random_words))#返回索引到的单词数据用于建立日期表
random_words = random_words_df[['单词']]#对列进行操作这里还是dataframe格式
random_words_lists = np.array(random_words).tolist()#注意这里的random_words_list每一个random_word都是单独的列表,迭代时需要[0]for random_word in random_words_lists:print('今日随机单词'.center(80,'='))print(random_word[0])
#这里借助numpy将dataframe转换为list格式方便后面进行文件重组时间文件#word_read_pro.py的最终目的就是提供80个随机单词,不具备判断能力,但是记录随机筛选的单词的索引#在随后的返回函数中根据csv时间文件判断是否需要call_back
# random_words_lists = np.array(random_words).tolist()#注意这里的random_words_list每一个random_word都是单独的列表,迭代时需要[0]

temp_word_write_pro.py

暂时文件读写模块 主要用于将word中的单词数据转化为data日志的方式,方便后面的存储与数据处理。这一模块需要单独运行,可以在部署服务器之前运行一遍就好,当然还是要注意centos7的绝对路径的问题。 show me the code

# auther : keepython
import pandas as pd
import numpy as np
import random
file_name = '六级核心词汇表(EXCEL表格)'
word_file_path = '/word_recording_project/word/' + file_name+'.xls'
words = pd.read_excel(word_file_path,header=0)
words_index = words.indexwords = words[['单词']]
print(len(np.array(words).tolist()))
words = np.array(words).tolist()#将所有单词转换为列索引,行索引转换为天数
print(len(words))
datas = {}
for word in words :datas[word[0]] = {"5min":0,"30min":0,'12hour':0,'day1':0,'day2':0,'day4':0,'day7':0,'day15':0,'time':'1111-11-11-11-11'}words_df = pd.DataFrame(data=datas)
print(words_df)
words_df.to_csv('/word_recording_project/data/word.csv')
# print(words_df)

every_day_count_pro.py

这一部分从标题来看就是用于对every_day_word中的文件与data中的日志文件配合计时并返回对应的文件路径用于后面的邮件发送调用。

import time
import datetime
import pandas as pd
import numpy as np
from  word_read_project import every_day_word_path
from mail_send_project import mail_send_fuc#函数功能:负责time时间的相减,并分别返回时间间隔时间为1day 2day 4day 7day 15day 的路径列表
def read_log_remind():word_log_path = '/word_recording_project/data/word.csv'word_log = pd.read_csv(word_log_path,index_col=0)word_log = word_log.Tword_log = word_log[word_log.time != '1111-11-11-11-11']  # 提取word.csv文件中time所有不等于‘1111-11-11-11-11’的模块#将矩阵转置方便使用index提取路径time_stamp = time.strftime("%Y-%m-%d-%H-%M", time.localtime()).split('-')log_times = np.array(word_log['time']).tolist()today = datetime.datetime(int(time_stamp[0]),int(time_stamp[1]),int(time_stamp[2]),int(time_stamp[3]),int(time_stamp[4]))#分别设置对应天数的路径列表day_1_path = []day_2_path = []day_4_path = []day_7_path = []day_15_path = []for log_time in log_times:log_timed = log_time.split('-')# print(log_timed)last_day = datetime.datetime(int(log_timed[0]),int(log_timed[1]),int(log_timed[2]),int(log_timed[3]),int(log_timed[4]))reduce = today - last_day#用于判断天数if reduce.days == 1:path  = '/word_recording_project/every_day_word/'+log_time+'.csv'day_1_path.append(path)elif reduce.days == 2:path = '/word_recording_project/every_day_word/' + log_time+'.csv'day_2_path.append(path)elif reduce.days == 4:path = '/word_recording_project/every_day_word/' + log_time+'.csv'day_4_path.append(path)elif reduce.days == 7:path = '/word_recording_project/every_day_word/' + log_time+'.csv'day_7_path.append(path)elif reduce.days == 15:path = '/word_recording_project/every_day_word/' + log_time+'.csv'day_15_path.append(path)#列表收集完路径后还需要去重day_1_path = list(set(day_1_path))day_2_path = list(set(day_2_path))day_4_path = list(set(day_4_path))day_7_path = list(set(day_7_path))day_15_path = list(set(day_15_path))return day_1_path,day_2_path,day_4_path,day_7_path,day_15_path#负责当天的推进5 min 30 min 12小时
def today_word_count():today_path = every_day_word_pathprint('今日要推送的地址是: ',today_path)time_stamp = time.strftime("%Y-%m-%d", time.localtime())subject = '艾宾浩斯 '+time_stamp+' 第一次单词提醒'mail_send_fuc(today_path,subject)time.sleep(300)#5min提醒mail_send_fuc(today_path,subject)time.sleep(1500)#30min提醒mail_send_fuc(today_path,subject)time.sleep(41400)#12小时提醒mail_send_fuc(today_path,subject)

mail_send_project.py

邮件发送,输入邮件主题和对应的附件路径直接发送,注意使用的时候修改一下对应的一些变量。

import smtplib
from email.header import Header
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
#从word.csv文件传入文件everyday文件路径就可以直接发送邮件
# everyday_file_path = '2020-02-02.csv'#函数功能:传入附件路径,邮件的主题发送邮件并返回发送状态def mail_send_fuc(everyday_file_path,subject):message = MIMEMultipart()msg_from = '***********'  # 发送方邮箱地址。password = '***************'  # 发送方QQ邮箱授权码,不是QQ邮箱密码。msg_to = '*************'msg_to_1 = '******************'  # 收件人邮箱地址。message = MIMEMultipart()message['From'] = msg_from  # 发送者message['To'] = msg_to  # 接收者# 邮件标题message['Subject'] = Header(subject, 'utf-8')# 邮件正文内容message.attach(MIMEText('艾宾浩斯根据你的遗忘曲线提醒单词'.center(20,'+'), 'plain', 'utf-8'))#打开文件part = MIMEApplication(open(everyday_file_path, 'rb').read())part.add_header('Content-Disposition', 'attachment', filename=everyday_file_path)message.attach(part)#添加文件try:client = smtplib.SMTP_SSL('smtp.qq.com', smtplib.SMTP_SSL_PORT)print("连接到邮件服务器成功")client.login(msg_from, password)print("登录成功")client.sendmail(msg_from, msg_to, message.as_string())print("发送成功")except smtplib.SMTPException as e:print("发送邮件异常")finally:client.quit()# mail_send_fuc(everyday_file_path)

main_code.py

调用所有模块和函数,将之组合起来实现最终的功能。项目在调用的时候也只需要调用main_dode.py就可以了。

import pandas as pd
import numpy as np
import os
import time
import random
from every_day_count_pro import *#总的执行函数包括写入word.csv日志的功能if __name__ == '__main__':day_1_paths, day_2_paths, day_4_paths, day_7_paths, day_15_paths = read_log_remind()today_word_count()time.sleep(3600)#1小时后再复习昨天的知识if len(day_1_paths) != False:for day_1_path in day_1_paths:subject = '1 天前的单词复习'.center(20,'=')mail_send_fuc(day_1_path,subject)time.sleep(900)if len(day_2_paths) != False:for day_2_path in day_2_paths:subject = '2 天前的单词复习'.center(20,'=')mail_send_fuc(day_2_path,subject)time.sleep(900)if len(day_4_paths) != False:for day_4_path in day_4_paths:subject = '4 天前的单词复习'.center(20,'=')mail_send_fuc(day_4_path,subject)time.sleep(900)if len(day_7_paths) != False:for day_7_path in day_7_paths:subject = '4 天前的单词复习'.center(20,'=')mail_send_fuc(day_7_path,subject)time.sleep(900)if len(day_15_paths) != False:for day_15_path in day_15_paths:subject = '15 天前的单词复习'.center(20,'=')mail_send_fuc(day_15_path,subject)

项目到这里就算开发完成啦,注意这里面的dataframe数据的操作真的非常高效,但是坑也很多希望有需要的同学一定要认真看。┑( ̄Д  ̄)┍


服务器定时任务部署

这一部分一定要修改好代码里面对应的路径,还是那句话centos7里面的绝对路径的问题。

编辑crontab配置这一步详细解释可以看这里:

Linux-Centos 用crontab定时运行python脚本详细步骤

crontab -e

编写配置文件

当打开配置文件的时候,我们可以看到类似的配置代码。每一行都代表一个定时任务 , 我们要做的就是新添加一行配置代码。

重启服务

service crond restart

最终就完成啦

欢迎留言交流学习,有什么疑问也可以交流,如果聊的开心还可以多一个朋友。

30867d4feb976c7ea7f9a34d6078109a.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/337421.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用不到125行C语言代码就可以编写一个简单的16位虚拟机?

点击蓝字关注我们一位国外的软件工程师分享了这么一篇博文:Writing a simple 16 bit VM in less than 125 lines of C(用不到 125 行 C 语言编写一个简单的 16 位虚拟机)。博文地址:https://www.andreinc.net/2021/12/01/writing-…

用一个程序生成另一个程序_还有另一个报告生成器?

用一个程序生成另一个程序如果您具有业务应用程序开发的经验,那么很可能会遇到要求该应用程序具有灵活的报告机制的需求。 我工作的公司主要专注于开发业务解决方案,而报告是必不可少的,实际上,它必须包含我们开发的所有企业系统的…

CocosCreator1.x实现水流动的效果

CocosCreator1.x实现水流动的效果Cocos Creator版本:1.10.2 运行结果:(H5和原生都支持) 场景: 脚本: HelloWorld.js: let shader require(shader);cc.Class({extends: cc.Component,properties: {water: cc.Node,waterNorm…

python爬虫xpath教程_使用 Xpath 进行爬虫开发

使用 Xpath 进行爬虫开发 Xpath( XML Path Language, XML路径语言),是一种在 XML 数据中查找信息的语言,现在,我们也可以使用它在 HTML 中查找需要的信息。 既然谈到 Xpath 是一门语言,当然它就会有自己的一些特定的语法。我们这里…

用C语言写烟花,给心中的那个人看!

点击蓝字关注我们前言程序员不懂浪漫? 大错特错!今天就让你们看看什么是程序员的浪漫!你向窗外看烟花,我在窗边看你,这时,你比烟花好看的多,你的眼眸倒映满天的烟火,我的瞳孔倒映你温柔的脸庞…

手把手教你做一个线程池--C语言版

点击蓝字关注我们1、线程池原理我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低…

oracle 48小时内_缺血性脑梗死后48小时内使用阿替普酶能够降低脑损伤程度

一项刊登在影响因子7.6杂志Neurology上题为“Effect of IV alteplase on the ischemic brain lesion at 24–48 hours after ischemic stroke”的研究报告中,来自爱丁堡大学的科学家们发现,alteplase与病变可视性的短期进展降低相关。在荟萃分析中&#…

MySQL夺命16问,你能坚持到第几问?

点击蓝字关注我们1、数据库三大范式是什么?第一范式:每个列都不可以再拆分。第二范式:在第一范式的基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分。第三范式:在第二范式的基础上,非…

美图手机投射功能在哪_在Java 8中进行投射(还有其他功能?)

美图手机投射功能在哪将实例转换为设计不良的类型。 尽管如此,在某些情况下没有其他选择。 从第一天开始,执行此功能就已成为Java的一部分。 我认为Java 8提出了对这种古老技术稍加改进的需求。 静态铸造 Java中最常见的转换方法如下: 静态…

js箭头函数和普通函数区别

js箭头函数和普通函数区别实验环境:nodejs v12.16.1 箭头函数不能作为构造函数,而普通函数可以 箭头函数没有原型,而普通函数有 箭头函数return可以省略语句块。(如果>右边不是语句块,则代表return右边的表达式或对象) 箭…

git 更新_[技术分享T.191212]GitLab使用方法及git命令常见问题(不断更新)

该文章用于记录一些GitLab的使用指南,以及在实际版本控制过程中遇到的问题及解决方法,会尽量及时的更新~GitLab简介:GitLab和GitHub很相似都属于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来…

记一次开发实战-对提供接口的C/C++进行二次开发

点击蓝字关注我们一、需求描述我有一个USB5538的库和头文件,并通过头文件提供了接口,我想把它更改一下,编译成python可调用的模块。二、创建工程及其目录1、创建空项目2、创建目录三、创建文件1、复制文件并添加2、添加新文件并写入四、环境配…

C++是如何实现多态的

C是如何实现多态的结论:C通过虚函数来实现多态的,根本原因是派生类和基类的虚函数表的不同。 构成多态的必要条件有如下3点: 存在继承关系基类存在虚函数,且派生类有相同原型的函数遮蔽它存在基类类型的指针指向派生类对象&…

C语言实现通讯录附详细代码(动态+静态)

点击蓝字关注我们一、通讯录简介实现一个通讯录;通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址提供方法:添加联系人信息删除指定联系人信息查找指定联系人信息修改指定联系人信息显示所有联系…

Lua协程Coroutine是什么

Lua协程Coroutine是什么协程和线程不同: 同一时刻,一个多线程程序可以用多个线程同时执行;而协程只能有一个在执行多线程是抢占式的;而协程是非抢占式的,只有协程显示被挂起,才会被挂起 协程和线程的相同…

C++程序的内存分区模型-栈区堆区

点击蓝字关注我们1、栈区:由编译器自动分配释放,存放函数的参数值,局部变量等(由编译器管理其“生死”)注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放栈区代码演示&#xff…

CocosStudio的节点如何使用自定义shader

CocosStudio的节点如何使用自定义shader问题:我想对CocosStudio 的 某个UI 里的 某个图片(如下图所示的Image类型)使用自定义shader。但是,我把 对传统的cc.Sprite应用自定义shader的方式 应用于它时,并不生效&#xf…

excel随机抽取_简单随机抽样及其进阶分层随机抽样方法展示

一、分享简单随机抽样的几种方法1、抽样分析工具抽样2、INDIRECTRANDBETWEEN函数抽样3、RAND排序抽样4、SAS抽样二、分层抽样方法1、Python分层抽样2、SAS分层抽样3、EXCEL函数及功能分层抽样简单随机抽样的几种方法方法一抽样分析工具抽样如果你的EXCEL尚未安装数据分析&#…

为什么存在动态内存分配,动态内存函数(malloc函数,free函数,calloc函数,realloc函数)...

点击蓝字关注我们1.当前我们知道的内存的使用方法2.为什么存在动态内存分配如上我们已学的开辟空间的方式有两个特点:空间开辟的大小是固定的必须指定数组的长度所以就产生了空间开大了浪费开小了不够用的问题,所以使用动态内存分配3.动态内存函数&#…

C++ vector类的模拟实现

点击蓝字关注我们1.前言vector和string虽然底层都是通过顺序表来实现的,但是他们利用顺序表的方式不同,string是指定好了类型,通过使用顺序表来存储并对数据进行操作,而vector是利用了C中的泛型模板,可以存储任何类型的…