如何制作营养膳食计算器

使用Google Calendar和Google Sheets API在正确的日子选择正确的食谱。 (Use the Google Calendar and Google Sheets APIs to select the right recipe on the right day.)

Do you also get stressed out when you get the question “what’s for dinner tonight?” You’re not alone. I guess it’s the most asked question as the clock strikes 4 p.m. Deciding what to eat can be a tedious chore. Especially when you have small children with various after-school activities.

当您收到“今晚晚餐时间是什么”这个问题时,您还会感到压力吗? 你不是一个人。 我猜这是最常见的问题,因为时钟是下午4点钟。决定吃什么可能是一件繁琐的工作。 特别是当您的孩子有各种各样的课余活动时。

To avoid going to the supermarket every day, we usually write up a menu with recipes for the coming week. That way we can buy all our groceries in one supermarket visit. This saves us a lot of time. Besides that, it also saves us money. That is because we are less exposed to all the selling tricks supermarkets use.

为了避免每天去超市,我们通常会在下周写一张包含食谱的菜单。 这样,我们可以在一次超市访问中购买所有杂货。 这为我们节省了很多时间。 除此之外,它还为我们节省了金钱。 这是因为我们对超市使用的所有销售技巧的了解较少。

Finding recipes for a whole week requires some thinking and planning. We have to take into account the eating preferences of all family members. Besides that, we have a limited time available for cooking each day. To make this easier, I built an automatic meal planner with these features:

寻找整整一周的食谱需要一些思考和计划。 我们必须考虑所有家庭成员的饮食偏好。 除此之外,我们每天都有有限的时间做饭。 为了简化此过程,我构建了具有以下功能的自动膳食计划器:

  • extract the work planning for me and my wife from our shared Google calendars从我们共享的Google日历中提取我和我妻子的工作计划
  • extract our preferred recipes from a Google spreadsheet,从Google电子表格中提取我们首选的食谱,
  • repeat some recipes each week on the same day每周在同一天重复一些食谱
  • leave one week in between before repeating the other recipes间隔一星期再重复其他食谱
  • I like cooking more than my wife. So on days that I can’t cook the recipes should be short in time我比老婆更喜欢做饭。 所以在我无法煮菜的日子里,食谱应该很短
  • upload the week menu in a Google calendar将周菜单上传到Google日历中

Let’s jump right in.

让我们跳进去。

使用Google日历API和Google表格API (Using the Google calendar API and Google sheets API)

First, we’ll need to create a new Google Cloud project. Before we can use the Google calendar and sheets in this project, we need to enable the API’s. This is very well explained on the web pages below:

首先,我们需要创建一个新的Google Cloud项目 。 在此项目中使用Google日历和工作表之前,我们需要启用API。 以下网页对此进行了很好的解释:

  • Enabling the Google Calendar API

    启用Google Calendar API

  • Enabling the Google Sheets API

    启用Google Sheets API

When that’s done, we continue by importing the necessary Python packages.

完成后,我们将导入必要的Python包。

import config as cfg
import pandas as pd
import numpy as np
from pathlib import Path
from datetime import datetime
from datetime import timedelta
from googleapiclient.discovery import build
from google.oauth2 import service_account

组态 (Configuration)

For privacy and security reasons, I keep some parameters in a separate config.py file. We import the file with the alias cfg. I will discuss these parameters further below with fictitious values. You can include them for your own app with values relevant to your case.

出于隐私和安全原因,我将一些参数保存在单独的config.py文件中。 我们使用别名cfg导入文件。 我将在下面用虚拟值进一步讨论这些参数。 您可以将它们包含在自己的应用程序中,并提供与案例相关的值。

范围 (Scopes)

With scopes, we define the access levels for the Google calendars and sheets. We will need read and write access to both the calendars and sheet. Thus we use the URLs below.

通过范围,我们定义了Google日历和工作表的访问级别。 我们将需要同时访问日历和工作表 。 因此,我们使用下面的URL。

SCOPES = ['https://www.googleapis.com/auth/calendar', 'https://www.googleapis.com/auth/spreadsheets']

Google工作表ID和范围 (Google sheet ID and range)

SPREADSHEET_ID = <Your Google sheet ID>
RANGE = 'recepten!A:G'

We need to specify the ID of the Google sheet with the recipes. Additionally, we specify the sheet range containing the recipes.

我们需要使用食谱指定Google工作表的ID。 此外,我们指定包含配方的图纸范围。

You can find the ID of your Google sheets by right-clicking on the sheet in Google Drive. Then select “Get shareable link”. You can find the ID after “https://drive.google.com/open?id=”.

您可以找到自己的Google表格的ID 右键单击Google云端硬盘中的工作表。 然后选择“获取共享链接”。 您可以在“ https://drive.google.com/open?id=”之后找到ID。

In my Google sheet “recepten”, columns A to G contain information on each recipe. The screenshot below shows some sample content. So RANGE needs to be set to “recepten!A:G”.

在我的Google工作表“接收器”中,列A至G包含每个食谱的信息。 下面的屏幕快照显示了一些示例内容。 因此需要将RANGE设置为“ recepten!A:G”

Google日历ID (Google Calendar IDs)

CALENDARID_1 = <Your Google Calendar ID>
CALENDARID_2 = <Your partner's Google Calendar ID>
CALENDARID_WEEKMENU = <Google Calendar ID for the week menu>

We need to specify the Google Calendar IDs to get the events from. Make sure you have access to all calendars you want to include. You can find the ID by executing this script from the APIs Explorer.

我们需要指定Google日历ID来获取事件。 确保您有权访问要包括的所有日历。 您可以通过在API Explorer中执行此脚本来找到ID。

For this project, we will extract the events of only two calendars. But you could adapt the code to loop over more calendars. I’ve also created a separate calendar to upload the recipes.

对于此项目,我们将仅提取两个日历的事件。 但是您可以修改代码以遍历更多日历。 我还创建了一个单独的日历来上传食谱。

活动标签 (Event labels)

BUSY_EVENTS = [<Labels of busy calendar events>]
FREE_EVENTS = [<Labels of free calendar events>]
ALL_EVENTS = BUSY_EVENTS + FREE_EVENTS

My wife works in shifts and adds them to her Google Calendar by using letter codes. For example: “B” stands for the afternoon shift. This event is one of the BUSY_EVENTS.

我的妻子轮班工作,并使用字母代码将其添加到她的Google日历中。 例如:“ B”代表下午班次。 此事件是BUSY_EVENTS

When I have a day off, I add “HOLIDAY” to my calendar. This event is one of the FREE_EVENTS.

休息日后,将“ HOLIDAY”添加到日历中。 此事件是FREE_EVENTS.

All the events are full-day events in the Google Calendars. You can use your own event labels scheme.

所有活动都是Google日历中的全天活动。 您可以使用自己的事件标签方案。

传统 (Traditions)

TRADITIONS = {   'Thursday' : 'fries'}

With TRADITIONS, I mean that our family has a few days in the week on which we prepare a certain recipe. As we are from Belgium, this means eating fries once a week (for us on Thursday). And yes, before you’d ask, that is fries with mayonnaise.

使用TRADITIONS ,我的意思是我们一家人在一周中的几天里会准备一些食谱。 因为我们来自比利时,所以这意味着每周要吃一次薯条(对我们来说是星期四)。 是的,在您问之前,那就是蛋黄酱。

You can specify your own traditions in a dictionary, with the name of the day as the key and the recipe as the value.

您可以在字典中指定自己的传统,以日期名称为键,配方为值。

提前计划的天数 (Number of days to plan ahead)

Sometimes we can’t go to the supermarket on the day a new week menu is created. We might need some days to plan ahead. With NB_DAYS_BEFORE we give ourselves some slack. This means that the new week menu will be generated a certain number of days before the previous week menu has finished.

有时,我们在创建新周菜单的那天就不能去超市。 我们可能需要几天的时间来计划。 使用NB_DAYS_BEFORE我们可以放松一些。 这意味着新周菜单将在上周菜单完成之前的一定天数内生成。

NB_DAYS_BEFORE = 3

使用服务帐户 (Using a service account)

We will use a service account to make use of the APIs in the project. The credentials.json file is the file that you can download when enabling the APIs.

我们将使用服务帐户来利用项目中的API。 certificate.json文件是启用API时可以下载的文件。

We create the credentials creds with the code below. These credentials enable authentication in the Google Calendars and Google sheet.

我们创建凭据creds与下面的代码。 这些凭据可在Google日历和Google工作表中启用身份验证。

creds = service_account.Credentials.from_service_account_file("credentials.json", scopes=cfg.SCOPES)

获取Google日历活动 (Getting the Google Calendar events)

We start by creating the service object with the build method.

我们首先使用build方法创建服务对象。

service_cal = build('calendar', 'v3', credentials=creds)

We are only interested in the events for the coming week. To filter these events, we specify the dates and format them with isoformat(). The parameters timeMin and timeMax need this format.

我们只对下一周的活动感兴趣。 要过滤这些事件,我们指定日期并使用isoformat()对其进行格式化。 参数timeMintimeMax需要这种格式。

def format_date(date):date_time = datetime.combine(date, datetime.min.time())date_time_utc = date_time.isoformat() + 'Z'return date_time_utc

With the method events().list of the service object, we extract the events. The extracted events are then filtered for the BUSY and FREE events. All other events on the Google Calendars are not relevant in this project. We keep the start and end date and the summary of the events.

通过服务对象的events()。list方法,我们可以提取事件。 然后,将提取的事件过滤为BUSY和FREE事件。 Google日历上的所有其他事件与该项目无关。 我们保留事件的开始和结束日期以及摘要。

def get_event_date(event, timepoint):return event[timepoint].get('dateTime', event[timepoint].get('date'))def get_events_by_calendarId(service, calendarId, timeMin, timeMax, allEvents):events_result = service.events().list(calendarId=calendarId, timeMin=timeMin, timeMax=timeMax, singleEvents=True, orderBy='startTime').execute()events = events_result.get('items', [])    events_list = [(get_event_date(e, 'start'), get_event_date(e, 'end'), e['summary'].upper()) for e in events if e['summary'].upper() in allEvents]return unfold_events_list(events_list)

Some events spread over more than one day. For example, when you take holidays for more than one day. We unfold these multi-day events in daily events within the range of the coming week.

有些事件超过一天。 例如,当您休假超过一天时。 我们将在下一周的每日活动中展开这些多日活动。

def unfold_events_list(events_list):new_events_list = []for e in events_list:start = datetime.strptime(e[0], '%Y-%m-%d').date()end = datetime.strptime(e[1], '%Y-%m-%d').date()delta_days = (end - start).daysif delta_days > 1:for d in range(delta_days):unfolded_day = start + timedelta(days=d)if unfolded_day >= datetime.now().date() and unfolded_day <= datetime.now().date() + timedelta(days=6):new_events_list.append((unfolded_day, e[2]))else:new_events_list.append((start, e[2]))return new_events_list

Finally, we want a Pandas DataFrame with the events of both calendars for the coming week. To get to that result, we convert the events lists to data frames and merge on the date. We also add the weekday to the merged data frame.

最后,我们需要一个带有下两个日历事件的Pandas DataFrame。 为了获得该结果,我们将事件列表转换为数据框并在日期上合并。 我们还将工作日添加到合并的数据框中。

def create_events_df(events_list_1, events_list_2):events_df_1 = pd.DataFrame.from_records(events_list_1, columns=['date', 'events_cal_1'])events_df_2 = pd.DataFrame.from_records(events_list_2, columns=['date', 'events_cal_2'])events_df = events_df_1.merge(events_df_2, on='date', how='outer')events_df.date = pd.to_datetime(events_df.date)events_df.set_index('date', inplace=True)events_df.sort_index(inplace=True)dates = list(pd.period_range(START_DAY, NEXT_WEEK, freq='D').values)new_idx = []for d in dates:new_idx.append(np.datetime64(d))events_df = events_df.reindex(new_idx)events_df.reset_index(inplace=True)events_df['weekday'] = events_df.date.apply(lambda x: x.strftime('%A'))events_df.set_index('date', inplace=True)return events_df

To make sure we cover all dates of the coming week, we use a period_range and reindex the merged data frame.

为确保涵盖下一周的所有日期,我们使用period_range并为合并的数据框reindex period_range reindex

从Google工作表获取食谱 (Getting the recipes from the Google sheet)

At this point, we have a data frame with all days of the coming week and the events (if any) occurring in the two calendars. Now we can start to extract the recipes from the Google sheet and assign a recipe to each day. As with the Google Calendar API, let’s start by creating the service object for the Google Sheets API.

至此,我们有了一个数据框架,其中包含下一周的所有日期,以及两个日历中发生的事件(如果有)。 现在,我们可以开始从Google工作表中提取食谱,并为每一天分配一个食谱。 与Google Calendar API一样,让我们​​开始为Google Sheets API创建服务对象。

service_sheet = build('sheets', 'v4', credentials=creds)

With the method spreadsheets().values().get we can extract the recipes from the Google Sheet.

使用电子表格sheets()。values()。get方法,我们可以从Google表格中提取配方。

def get_recipes(service, spreadsheetId, range):recipes_result = service.spreadsheets().values().get(spreadsheetId=spreadsheetId, range=range).execute()recipes = recipes_result.get('values', [])recipes_df = pd.DataFrame.from_records(recipes[1:], columns=recipes[0])recipes_df.last_date_on_menu = pd.to_datetime(recipes_df.last_date_on_menu, dayfirst=True)recipes_df.set_index('row_number', inplace=True)eligible_recipes = recipes_df[ (recipes_df.last_date_on_menu < PREV_WEEK) | (np.isnat(recipes_df.last_date_on_menu)) ]return recipes_df, eligible_recipes

Next, we create a data frame with the recipes. I like working with Pandas DataFrames, but you could use other data structures as well of course.

接下来,我们使用配方创建一个数据框。 我喜欢使用Pandas DataFrames,但是您当然也可以使用其他数据结构。

The row_number is a field calculated in the Google Sheet itself. We use the Google Sheet function ROW() for that. It will help to update the field last_date_on_menu in the correct row. We will update that date when a recipe is chosen for the coming week.

row_number是在Google表格本身中计算的字段。 我们为此使用Google Sheet函数ROW() 。 这将有助于在正确的行中更新字段last_date_on_menu 。 我们将在下周选择食谱时更新该日期。

We need to make sure that a recipe is only repeated after one week. So we filter recipes_df by last_date_on_menu. This date must be empty or before the previous week.

我们需要确保一个星期后才重复一次食谱。 因此,我们筛选recipes_df通过last_date_on_menu 。 该日期必须为空或在前一周之前。

生成周菜单 (Generating the week menu)

In this step, we will assign an eligible recipe to each day of the coming week.

在此步骤中,我们将为下周的每一天分配合格的食谱。

def generate_weekmenu(service, events_df, traditions, free_events):weekmenu_df = events_df.copy()for i, r in events_df.iterrows():if r.weekday in traditions.keys():weekmenu_df.loc[i, 'recipe'] = traditions[r.weekday]weekmenu_df.loc[i, 'description'] = ''else:if r.weekday in ['Saturday', 'Sunday']:row_number = choose_recipe('difficult', i, weekmenu_df, eligible_recipes)update_sheet(service, row_number, i.strftime('%d-%m-%Y'), cfg.SPREADSHEET_ID)elif r.events_cal_1 in free_events or r.events_cal_2 in free_events \or pd.isnull(r.events_cal_1) or pd.isnull(r.events_cal_2):row_number = choose_recipe('medium', i, weekmenu_df, eligible_recipes)update_sheet(service, row_number, i.strftime('%d-%m-%Y'), cfg.SPREADSHEET_ID)else:row_number = choose_recipe('easy', i, weekmenu_df, eligible_recipes)update_sheet(service, row_number, i.strftime('%d-%m-%Y'), cfg.SPREADSHEET_ID)return weekmenu_df

To take into account the work planning (BUSY and FREE events), we will use the difficulty of each recipe. A random recipe of the preferred difficulty will be added to weekmenu_df. Finally we drop it from the eligible recipes to avoid duplicate recipes in the same week.

考虑到工作计划(忙碌和免费活动),我们将使用每种食谱的difficulty 。 首选难度的随机配方将添加到weekmenu_df. 最后,我们将其从符合条件的食谱中删除,以避免在同一周重复食谱。

def choose_recipe(difficulty, idx, weekmenu_df, eligible_recipes):choice_idx = np.random.choice(eligible_recipes.query("difficulty == '" + difficulty + "'" ).index.values)weekmenu_df.loc[idx, 'recipe'] = eligible_recipes.loc[choice_idx, 'recipe']weekmenu_df.loc[idx, 'description'] = eligible_recipes.loc[choice_idx, 'description']eligible_recipes.drop(choice_idx, inplace=True)return choice_idx

The method spreadsheets().values().update updates the Google Sheet.

方法电子表格().values()。update会更新Google表格。

def update_sheet(service, row_number, date, spreadsheetId):range = "recepten!F"  + str(row_number)values = [[date]]body = {'values' : values}result = service.spreadsheets().values().update(spreadsheetId=spreadsheetId, range=range, valueInputOption='USER_ENTERED', body=body).execute()

We iterate over each row of weekmenu_df. If the weekday is one of the TRADITIONS weekdays, we assign the corresponding recipe. For the other weekdays, we apply the following logic:

我们遍历weekmenu_df每一行。 如果工作日是“传统”工作日之一,则我们分配相应的食谱。 在其他工作日,我们采用以下逻辑:

  • In the weekend, choose a difficult recipe在周末,选择困难的食谱
  • During the week, when I’m at home or my wife has a day off, choose a recipe with medium difficulty在一周中,当我在家或我的妻子休息一天时,选择中等难度的食谱
  • During the week, when I or my wife are at work, choose an easy recipe在本周,当我或妻子上班时,选择简单的食谱

将周菜单添加到Google日历 (Adding the week menu to a Google Calendar)

Now that we have a menu for the coming week, we can add it as events to a Google Calendar. I’ve created a separate calendar for it. Share this calendar with the client_email in credentials.json. In the settings of your calendar you also need to give it permission to make changes in the events.

现在我们有了下周的菜单,我们可以将其作为事件添加到Google日历中。 我为此创建了一个单独的日历。 将此日历与凭据中的client_email共享。 在日历的设置中,您还需要授予其更改事件的权限。

def add_weekmenu_to_calendar(service, weekmenu_df, calendarId):for i, r in weekmenu_df.iterrows():event = {'summary': r.recipe,'description': r.description,'start': {'date': i.date().isoformat(),'timeZone': 'Europe/Brussels'},'end': {'date': i.date().isoformat(),'timeZone': 'Europe/Brussels'}}event = service.events().insert(calendarId=calendarId, body=event).execute()

让我们自动化 (Let’s automate)

Until now we have taken into account all the requested features for the application. But you would still have to run the code by hand to generate the week menu.

到目前为止,我们已经考虑了该应用程序所有要求的功能。 但是您仍然必须手动运行代码才能生成星期菜单。

I found this great website PythonAnyWhere where you can schedule Python programs. The free Beginner account allows to schedule one Python program on a daily basis. That’s exactly what we need.

我找到了这个很棒的网站PythonAnyWhere ,您可以在其中安排Python程序。 免费的初学者帐户允许每天安排一个Python程序。 这正是我们所需要的。

First, we need to stitch all the functions together and put them in a Python file. In this file, I do an extra check to see where we are in the current week menu. I do this by looking at the last date with a recipe in the Google Calendar with get_date_last_event.

首先,我们需要将所有功能拼接在一起,并将它们放入Python文件中。 在此文件中,我进行了额外的检查,以查看当前周菜单中的位置。 为此,我会使用get_date_last_event.在Google日历中get_date_last_event.食谱的最后日期get_date_last_event.

def get_date_last_event(service, calendarId):events_result = service.events().list(calendarId=calendarId, singleEvents=True, orderBy='startTime').execute()date_last_event = events_result.get('items', [])[-1]['start']['date'][:10]date_last_event = datetime.strptime(date_last_event, '%Y-%m-%d').date()return date_last_event

That date is stored in DATE_LAST_RECIPE. If the current day is after DATE_LAST_RECIPE minus NB_DAYS_BEFORE we can generate a new week menu.

该日期存储在DATE_LAST_RECIPE. 如果当前日期是DATE_LAST_RECIPE减去NB_DAYS_BEFORE我们可以生成一个新的星期菜单。

You can find the complete script on Github.

您可以在Github上找到完整的脚本。

if __name__ == '__main__':# Getting credentials from credentials.jsonCREDS_PATH = Path.cwd() / "weekmenu" / "credentials.json"creds = service_account.Credentials.from_service_account_file(CREDS_PATH, scopes=cfg.SCOPES)# Creating service objectsservice_cal = build('calendar', 'v3', credentials=creds)service_sheet = build('sheets', 'v4', credentials=creds)# Defining datesDATE_LAST_RECIPE = get_date_last_event(service_cal, cfg.CALENDARID_WEEKMENU) START_DAY = DATE_LAST_RECIPE + timedelta(days=1)NEXT_WEEK = START_DAY + timedelta(days=6)PREV_WEEK = START_DAY + timedelta(days=-7)START_DAY = format_date(START_DAY)NEXT_WEEK = format_date(NEXT_WEEK)PREV_WEEK = format_date(PREV_WEEK)# Getting the recipes from the Google Sheetrecipes_df, eligible_recipes = get_recipes(service_sheet, cfg.SPREADSHEET_ID, cfg.RANGE)# Check if the last weekmenu is still activeif DATE_LAST_RECIPE - timedelta(days=cfg.NB_DAYS_BEFORE) < datetime.now().date():# Getting the events from the Google Calendarsevents_list_1 = get_events_by_calendarId(service_cal, cfg.CALENDARID_1, START_DAY, NEXT_WEEK, cfg.ALL_EVENTS)events_list_2 = get_events_by_calendarId(service_cal, cfg.CALENDARID_2, START_DAY, NEXT_WEEK, cfg.ALL_EVENTS)# Merge the two events listsevents_df = create_events_df(events_list_1, events_list_2)# Generating the weekmenuweekmenu_df = generate_weekmenu(service_sheet, events_df, cfg.TRADITIONS, cfg.FREE_EVENTS)# Adding the weekmenu to a Google Calendaradd_weekmenu_to_calendar(service_cal, weekmenu_df, cfg.CALENDARID_WEEKMENU)print('Week menu is added to Google Calendar')else:print('Program stopped. Last week menu is not finished yet.')

On PythonAnyWhere I’ve created a subfolder week menu. I’ve uploaded the following files config.py, generate_weekmenu.py and credentials.json.

在PythonAnyWhere上,我创建了一个子文件夹的周菜单。 我已经上传了以下文件config.py,generate_weekmenu.py和凭据.json。

I then schedule a daily task that will run the generate_weekmenu.py script in the Tasks section. And voilà, we’re all set.

然后,我安排一个日常任务,该任务将在“任务”部分中运行generate_weekmenu.py脚本。 瞧,我们都准备好了。

结果 (The result)

After the first run of the script, we have a nice menu in our shared Google calendar.

第一次运行脚本后,我们在共享的Google日历中有一个漂亮的菜单。

结论 (Conclusion)

This script takes into account your professional schedule on your Google calendars. It selects your preferred recipes from a Google sheet. And by scheduling the script the recipes appear in an automated way in your Google Calendar. This frees you from the annoying chore to decide what to eat.

该脚本考虑了您在Google日历上的专业日程安排。 它从Google表格中选择您喜欢的食谱。 通过安排脚本,配方可以自动显示在Google日历中。 这使您从烦恼的琐事中解放出来,决定吃什么。

If you want to take it further, here are some ideas to fine-tune the script:

如果您想进一步讲解,这里有一些想法可以对脚本进行微调:

  • take into account the cooking time of a recipe考虑食谱的烹饪时间
  • allow a tradition of having at least one vegetarian meal per week允许每周至少吃一顿素食的传统
  • generate a grocery list for the chose recipes生成所选食谱的购物清单

I hope you enjoyed reading this story. If you have questions or suggestions about the script you can write a comment below. And if you liked it, feel free to clap for it.

希望您喜欢阅读这个故事。 如果您对脚本有疑问或建议,可以在下面写评论。 而且,如果您喜欢它,可以随时为它鼓掌。

翻译自: https://www.freecodecamp.org/news/how-to-save-time-and-money-by-building-an-automatic-meal-planner-7c7a9351d124/

如何制作营养膳食计算器

如何制作营养膳食计算器_如何通过构建自动膳食计划器节省时间和金钱相关推荐

  1. 如何制作营养膳食计算器_如何创建随机膳食生成器

    如何制作营养膳食计算器 Last week I decided to take on a new challenge. I called it: The #100Days100Projects Cha ...

  2. 批处理节省时间_简单的设计工作流程技巧,节省时间和头痛

    批处理节省时间 Does the way you work help you or slow you down? Do you feel efficient in your design workfl ...

  3. diy 单片机 自动浇花_基于单片机的自动浇花器的制作方法

    本实用新型涉及浇花设备技术领域,尤其涉及一种基于单片机的自动浇花器. 背景技术: 随着人们生活质量的不断提高,人们喜欢在家里放置花卉来点缀家中环境,从而使花卉种植不断普及,然而大多数花草生长问题是由花 ...

  4. 文件魔术数字_如何使用魔术脚手架自动创建文件并节省时间

    文件魔术数字 Before we begin: This article uses JavaScript / Node.js example code, but you can port these ...

  5. diy 单片机 自动浇花_基于单片机的自动浇花器设计

    龙源期刊网 http://www.qikan.com.cn 基于单片机的自动浇花器设计 作者:陈赋铭 来源:<农家科技下旬刊> 2015 年第 04 期 摘 要:本文是基于单片机 AT89 ...

  6. outlook 脱机通讯录_使用Outlook 2003中的通讯组列表节省时间

    outlook 脱机通讯录 Everybody sends out emails to the same group of people on a regular basis, but most pe ...

  7. spotify使用教程_使用JavaScript构建Spotify的着色器效果

    spotify使用教程 If you've used Spotify before, you are likely familiar with the duotone effect. Essentia ...

  8. mac睡眠状态下远程唤醒_如何控制Mac自动进入睡眠状态的时间

    mac睡眠状态下远程唤醒 It's often a good idea to let your Mac sleep after a period of time when you're not usi ...

  9. css的计算器,CSS3制作漂亮的计算器

    插件描述:原生js CSS3制作漂亮的计算器_加减乘除计算器代码 实现代码html> JS+CSS3实现计算器特效 C 7 8 9 + 4 5 6 - 1 2 3 ÷ 0 . = x jsvar ...

最新文章

  1. java使用eclipse打jar包_Eclipse对Java项目打Jar包
  2. GIT和SVN之间的五个基本区别
  3. 学多门计算机语言的好处,多学一门语言的19大好处
  4. 【任务脚本】2020双十一活动小结,京东活动依旧始终良心
  5. Django简介Django 各个环境下的安装
  6. 一位7亿收入产品经理的五大绝招
  7. ThreadLocal基本使用和内存泄漏分析
  8. wxWidgets:wxHashSet类用法
  9. Redirecting to binsystemctl start crond.service
  10. java 收集系统资源_方法:Linux 下用JAVA获取CPU、内存、磁盘的系统资源信息
  11. python全栈索引
  12. java数据库获取的值如何替换_java-如何将数据库中的列值获取到jLabels
  13. Error:To install them, you can run: npm install --save vue-style-loader css-loader……
  14. 在硅谷谈AI不够有创意,到苹果开吐槽大会 | 跟着李开复去硅谷
  15. android开发根据分辨率设置高度,【android】根据屏幕分辨率设置底栏高度
  16. 好奇怪呀后面加什么标点_沙发位后面是窗户有什么好的方案?
  17. 海康摄像头故障处理踩坑记录
  18. 计算机系统操作权限,电脑修改系统时间提示没有操作权限的解决办法
  19. 小程序scroll-view文字不能自动换行
  20. Redhat linux命令行连接wifi

热门文章

  1. @Target、@Retenrion注解
  2. 8热水器用户行为分析与事件识别
  3. PPT也可以制作特效字幕
  4. gzip 解压_简简单单_百度空间
  5. 甘肃教师计算机考试试题,2017下半年甘肃省初中信息技术教师资格证面试试题精选(1.7上午)...
  6. AnLink投屏电脑软件,有线无线连接--视频/图文完整连接方法
  7. 1Keyboard for mac使用教程
  8. 钢筋混凝土和预应力钢筋混凝土的区别
  9. PHP命令行输入和输出
  10. Arcgis Engine 二次开发之属性查询