python 追踪
Some people want to gain weight while others want to lose it. I have been in the former group for as long as I can remember myself. Even after learning martial arts for about 10 years, my weight did not increase drastically. It made my body fitter and my mind stronger. But still, it was not enough to increase my Body Mass Index. I have always been in the lower limit of the “healthy” BMI range.
有些人想增加体重,而另一些人想减轻体重。 只要记得我,我就一直在前一组。 即使学习了大约10年的武术,我的体重也没有急剧增加。 它使我的身体更健康,头脑更坚强。 但是,仍然不足以增加我的体重指数。 我一直处于“健康” BMI范围的下限。
There might be many reasons for that. Maybe, my love for sweets and snacks (fast energy). Perhaps, my high metabolic rate. Maybe, something else. Or, most probably, everything altogether. Who knows but the fact is the fact.
可能有很多原因。 也许,我对糖果和零食(快速能量)的热爱。 也许,我的新陈代谢率很高。 也许还有别的。 或者,很可能是所有的一切 。 谁知道,但事实是事实。
Looking years back, the only thing left is my memory that I have been somewhat underweight and no data to support or track down the weight changes over the years.
回顾几年,剩下的唯一一件事情就是我的记忆,我的体重一直偏低,多年来没有数据支持或追踪体重的变化。
I often say that when you can measure what you are speaking about, and express it in numbers, you know something about it; but when you cannot measure it, when you cannot express it in numbers, your knowledge is of a meager and unsatisfactory kind.- Lord Kelvin, 3 May 1883
我经常说,当您能够衡量自己所说的话并用数字表达时,您就会知道一些。 但是当您无法衡量它时,当您无法以数字来表达它时,您的知识是微不足道的。-开尔文勋爵,1883年5月3日
In Data Science, we know that the most time-consuming part of the data analysis is data collection and preparation. Because without (good) data, there is no analysis. So, I got an idea of picking up on my weight and improving some Python skills down the road. Besides, this might be an interesting project to keep sanity while staying indoors due to the horrific pandemic. This post is meant to encourage people to use Python in day-to-day life.
在数据科学中,我们知道数据分析中最耗时的部分是数据收集和准备。 因为没有(好的)数据,就没有分析。 因此,我想到了继续增加体重并提高一些Python技能的想法。 此外,由于大流行病的流行,这可能是一个有趣的项目,可以让人们在室内保持理智。 这篇文章旨在鼓励人们在日常生活中使用Python。
(Let us begin.)
(The idea)
We want to record the data of our weight measurements on a specific day (ideally, every day). We take the measurement, then write it down in a simple manner to save it in a tabular/table format (or something similar to that). In other words, we want the code to generate the output file for us and append its content with a given input. So, we would do as minimum work as possible in the long-run.
我们想在特定的一天(最好是每天)记录体重测量数据。 我们进行测量,然后以简单的方式将其记录下来,以表格/表格格式(或类似格式)保存。 换句话说,我们希望代码为我们生成输出文件,并将其内容附加给定的输入。 因此,从长远来看,我们将尽可能减少工作量。
Let us break down the process into objectives — what we need (and will) to learn in this post step by step.
让我们将过程分解为目标,这是我们在这篇文章中需要(并将要)逐步学习的内容。
(The objectives)
By the end of this article, you will learn how to:
在本文结束时,您将学习如何:
- interact with the python code using command-line arguments sys.argv; 使用命令行参数sys.argv与python代码进行交互;
- check if the file already exists using the operating system OS module; 使用操作系统OS模块检查文件是否已经存在;
- manipulate files usingwith open(); 使用with open()处理文件;
- handle some errors using try-catch block (bonus); 使用try-catch块(奖励)处理一些错误;
- add your own documentation (docstring) to any function (bonus); 将您自己的文档(文档字符串)添加到任何函数(奖金)中 ;
(The code)
We want to call the code with some additional (command-line) arguments to input the measured weight. The easiest way would be to work with the raw python code with .py extension (instead of an alternative interactive notebook).
我们想用一些附加的(命令行)参数调用代码以输入测得的体重。 最简单的方法是使用扩展名为.py的原始python代码(而不是替代的交互式笔记本)。
We start by creating a text document with the extension .py, for example, WeightTracker.py.
我们首先创建一个扩展名为.py的文本文档,例如WeightTracker.py 。
(Let us dive in!)
First of all, we import some libraries
首先,我们导入一些库
import numpy as np
import datetime
import os, sys
Get today’s date/time. Remove a comment # if you want only a date value (without a time)
获取今天的日期/时间。 如果只需要日期值(无时间),请删除注释#
currentDT = datetime.datetime.now()#.date()
(Part 1 (sys.argv))
Typically, when we run the python code from a command line (terminal) it looks like python WeightTracker.py if the code is called “WeightTracker.py”. By default, the name of the code is assigned to the zeroth system’s argument sys.argv[0] — zero, because in Python indices start from 0, not from 1. In this case, sys.argv[0] = WeightTracker.py. To check it out, you can print itprint(sys.argv[0]).
通常,当我们从命令行(终端)运行python代码时,如果代码称为“ WeightTracker.py”,则它看起来像python WeightTracker.py 。 默认情况下,代码名称分配给第零个系统的参数sys.argv[0] -零,因为在Python中索引从0开始,而不是从1开始。在这种情况下, sys.argv[0] = WeightTracker.py 。 要签出,可以将其打印为print(sys.argv[0]) 。
If we want to supply a list of additional arguments we could run the code as following python WeightTracker.py arg1 arg2 arg3 …. In the simplest case, we want to get only our own weight, e.g., use only one additional argument. Thus, for example, to run our code and record weight of 68.4 (units, e.g., kg), we will type python WeightTracker.py 68.4 in the terminal.
如果我们要提供其他参数列表,则可以按照python WeightTracker.py arg1 arg2 arg3 …运行代码。 在最简单的情况下,我们只想获得自己的权重,例如,仅使用一个附加参数。 因此,例如,要运行代码并记录68.4的重量(单位,例如kg),我们将输入python WeightTracker.py 68.4 在终端。
We read that value and append it to the empty array. Then, we define the filename to save the date and weight measurement
我们读取该值并将其附加到空数组。 然后,我们定义文件名以保存日期和体重测量值
daily_kg = sys.argv[1]mass_array = []
mass_array.append(daily_kg)filename = “My_weight_gain.txt”
(Part 2 (os module))
The module os allows us to use our operating system functionalities. Such as getting a current working directory with os.getcwd(), or displaying a list of files in the directory with os.listdir(<directory>), etc.
os模块允许我们使用我们的操作系统功能。 例如使用os.getcwd()获取当前工作目录,或使用os.listdir(<directory>)显示目录中的文件列表,等等。
Here, we are interested in checking if a given file exists with os.path.isfile(<file>). If it does (which might be because we ran this code before) we just update that file with today’s values. Otherwise, we need to create a new file. This is a simple if-else statement
在这里,我们感兴趣的是使用os.path.isfile(<file>)检查给定文件是否存在。 如果确实如此(可能是因为我们之前运行过此代码),我们只是用今天的值更新该文件。 否则,我们需要创建一个新文件。 这是一个简单的if-else语句
if os.path.isfile(filename):
print("\n file exists \n appending with provided data ... ")
# append an existing fileelse:
print("\n file does not exists \n creating {}".format(filename))
# create a new file
(Part 3 (creating files))
In Python, we can write (create) or read files using the built-in open function. In short, it provides a file object that contains the methods and attributes for reading, saving, and manipulating the files. The function open takes two parameters: filename (or path+filename) and the mode argument (reading "r", writing "w", or appending "a").
在Python中,我们可以使用内置的open函数编写(创建)或读取文件。 简而言之,它提供了一个文件对象,其中包含用于读取,保存和操作文件的方法和属性。 函数open具有两个参数:filename(或path + filename)和mode参数(读取"r" ,写入"w"或附加"a" )。
Note: it is always important to close a file after opening because every open file keeps eating resources.
注意: 打开文件后关闭文件始终很重要,因为每个打开的文件都会占用资源。
A way around it is to us the with statement. It automatically closes the file even if the code encounters an error. The code runs everything in the indented block, then closes the file object.
解决它的方法是with语句。 即使代码遇到错误,它也会自动关闭文件。 该代码运行缩进块中的所有内容,然后关闭文件对象。
For example, to create (write) a file called “Hello.txt” and write down a line “Hello World!”, we can use the statement with as follows
例如,创建(写)一个名为“hello.txt的”文件并写下一行的“Hello World!”,我们可以使用的语句with如下
with open('Hello.txt', 'w') as file:
file.write("Hello World!")
So, back to our code. We modify our if-else statement as
因此,回到我们的代码。 我们将if-else语句修改为
if os.path.isfile(filename):
print("\n file exists \n appending with provided data ... ")
with open(filename, "a") as file:
file.write("{:>20} {:>20}\n".format(str(currentDT), daily_kg))
else:
print("\n file does not exists \n creating {}".format(filename)) with open(filename, "w") as file:
file.write("{:>20} {:>20}\n".format("Time", "Mass (kg)"))
file.write("{:>20} {:>10}\n".format(str(currentDT), daily_kg))
In principle, this tutorial can be finished here because our program works. It records today’s date and our weight measurement.
原则上,由于我们的程序可以正常工作,因此可以在此处完成本教程。 它记录了今天的日期和我们的体重测量。
But we are not quite happy yet. We want to be able to handle the rising exception(s). For instance, when the user does not provide any weight value — we want to exit a program nicely and give a short clear message on what should be done (part 4). Also, we want to give a user some hints on how to run the program correctly or just describe the program in general (part 5).
但是我们还不太高兴。 我们希望能够处理不断上升的异常。 例如,当用户未提供任何权重值时,我们希望很好地退出程序,并简短说明要做什么(第4部分)。 另外,我们还想向用户提供一些有关如何正确运行该程序的提示,或者只是在总体上描述该程序(第5部分)。
(Part 4 (try-catch block))
The topic of rising and handling exceptions deserves its own article. What are exceptions and why should we care about them?
引发和处理异常的主题值得一读。 有什么例外情况,为什么我们要关心它们?
Very briefly and simply, exceptions are detected errors during the execution of the program. To handle them it is common to use a try-catch block. Inside a try: block, we run the code. If it fails, the program goes to except: block, where we decide what to do next.
非常简短,简单地,在程序执行期间会检测到异常 。 要处理它们,通常使用try-catch块。 在try:块中,我们运行代码。 如果失败,程序将转到except:块,在此我们决定下一步。
Let us see how it works by calling a simple function, which divides one variable by another. We will on purpose divide a number by zero to create an error — and we will catch it.
让我们通过调用一个简单的函数来查看其工作原理,该函数将一个变量除以另一个。 我们将故意将数字除以零以产生错误-我们将抓住它。
Here is a function. We define and call it. In the second case, we divide by zero.
这是一个功能。 我们定义并调用它。 在第二种情况下,我们除以零。
def div(x, y):
result = x / yreturn resultdiv(5,6) # result => 0.8333333333333334div(5,0) # result => ZeroDivisionError: division by zero
We know that the operation of division by zero is not defined. Here, we can easily see where the error occurred. But what if our program has dozens of definitions and separated into different files? Then, it might be not so easy to find what caused the error. It might be wise to think about it in advance.
我们知道没有定义被零除的运算。 在这里,我们可以轻松查看错误发生的位置。 但是,如果我们的程序具有数十个定义并分成不同的文件,该怎么办? 然后,可能很难找到导致错误的原因。 事先考虑一下可能是明智的。
Besides, a given block of code might perform some additional operation, so the whole result of the program does not strongly depend on it. Then, even if a given block fails and returns a None (empty) value or NaN (not a number) value, the whole program still will be executed.
此外,给定的代码块可能会执行一些附加操作,因此程序的整个结果并不强烈依赖于此。 然后,即使给定的块失败并返回None (空)值或NaN (非数字)值,整个程序仍将执行。
In general, learning how to handle exceptions is a good idea. In our example of div function, it might look like
通常,学习如何处理异常是一个好主意。 在我们的div函数示例中,它看起来像
def div(x, y):try:
result = x / yexcept:
print('Division by zero is not allowed! Exiting ...')
result = Nonereturn result
Calling this function now will give us a personal message, which explains what happened and returns theNone object. We do not get the result but our program does not crush either.
现在调用此函数将给我们一条个人消息,该消息说明发生了什么并返回None对象。 我们没有得到结果,但是我们的程序也没有崩溃。
There is much more to this. Such as, what types of exceptions exist, how to rise and re-rise exceptions, etc. These questions are beyond the scope of this article. If you want to learn more about it, please visit my short tutorial on GitHub.
还有更多的东西。 例如,存在什么类型的异常,如何引发和重新引发异常,等等。这些问题不在本文的讨论范围之内。 如果您想了解更多信息,请访问我在GitHub上的简短教程 。
In my opinion, the most essential part of handling exceptions is to always provide some information on the spot and never pass the exception. Otherwise, it might not be possible to trace back to the cause of the error.
我认为,处理异常的最重要部分是始终在现场提供一些信息,并且永远不要pass异常。 否则,可能无法追溯到错误原因。
Coming back to our program, we want to accommodate it by putting all of the previous code in the try: indented block. And inside the except: block, we will print out the error name and a short instruction on how to write a program correctly, such as
回到我们的程序,我们想通过将所有先前的代码放入try:indented块中来容纳它。 在except:块中,我们将打印出错误名称和有关如何正确编写程序的简短说明,例如
try:
except Exception as e:
# in case an Exception/Error arises, do the following:
print("\nError: {}\n".format(e))
messageFromDeveloper = "You need to provide the weight measurement as the first argument as following \npython <this code>.py <weight> \n for example \npython WeightTracker.py 75"
print(messageFromDeveloper.ljust(40, '-'))
By author 按作者
If we want to get a general idea about a given function/method, we usually use help() method. Let us see how we can manually define ourselves what is shown upon calling a help function.
如果我们想对给定的函数/方法有一个大概的了解,我们通常使用help()方法。 让我们看看如何在调用帮助功能时手动定义自己所显示的内容。
(Part 5 (creating our docstring))
In principle, every class, module, or function should have a documentation string (docstring). The docstring describes what the function does and it looks like a comment, inside triple-single or triple-double quotes.
原则上,每个类,模块或函数都应有一个文档字符串(docstring)。 该文档字符串描述了函数的功能,并且看起来像注释,在三重单引号或三重双引号中。
Again, there is a lot of information to this, from the exact format of the string to the common styles of the documentation. Here, we want to see how to create a simple docstring for our function. Even if it might not correspond to a global format of docstrings, you can do this as follows
同样,从字符串的确切格式到文档的常见样式,都有很多信息。 在这里,我们想看看如何为我们的函数创建一个简单的文档字符串。 即使它可能不对应于文档字符串的全局格式,也可以按照以下步骤进行操作
"""
This is a help doc
To EXIT/QUIT interactive mode - press "q"
This function is waiting for additional
command-line (terminal) argument upon call.
python <this code>.py <weight>
e.g.,
python WeightTracker.py 75.0
Otherwise an exception is thrown.
~~~
Good luck and have a nice day!
"""
To see this in action, you can call either print(WeightTracker.__doc__) or help(WeightTracker). In the last case, we will enter some kind of interactive shell, which we can quit by pressing ‘q’.
要查看实际效果,可以调用print(WeightTracker.__doc__)或help(WeightTracker) 。 在最后一种情况下,我们将输入某种交互式外壳,可以通过按“ q”退出。
Congratulations! Now, our program is finished. We can happily record our weight for future reference. The next part would be to read that file and analyze the weight changes. For example, using visualization and maybe even predict our future weight with machine learning.
恭喜你! 现在,我们的程序完成了。 我们可以愉快地记录体重,以备将来参考。 下一部分将是读取该文件并分析重量变化。 例如,使用可视化,甚至可以通过机器学习预测我们的未来重量。
To find the complete code of this program, please visit my GitHub page. The resulting output .txt file looks like
要找到该程序的完整代码,请访问我的GitHub页面 。 生成的输出.txt文件看起来像
By author
按作者
Thanks for your attention and reading until the end.
翻译自: https://medium.com/swlh/track-your-weight-with-python-4bf0cae42ef3
python 追踪