首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >树莓派气象站

树莓派气象站
EN

Code Review用户
提问于 2014-05-16 13:10:59
回答 1查看 2.1K关注 0票数 10

请告诉我怎样才能做得更好。代码是这里是吉突布

代码语言:javascript
复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Write some message on the display.
# This project uses https://github.com/dbrgn/RPLCD.
# sudo apt-get install python-matplotlib

from __future__ import print_function, division, absolute_import, unicode_literals

import sys

# Import LCD stuff from RPLCD, et. al.
from RPLCD import CharLCD
from RPLCD import Alignment, CursorMode, ShiftMode
from RPLCD import cursor, cleared

from xml.dom.minidom import *
import urllib
import RPi.GPIO as GPIO
import time
import csv

# Imports for graph plotting
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

import os
import subprocess
import shutil


# some LCD magic happens here
try:
    input = raw_input
except NameError:
    pass

try:
    unichr = unichr
except NameError:
    unichr = chr

# ###################################################################################
# Configure stuff here:
# Temp sensor ID is the folder name for ds18b20 1-wire sensors
# found in /sys/bus/w1/devices/
# Drivers are loaded with
# sudo modprobe w1-gpio
# sudo modprobe w1-therm
# or put them in /etc/modules
TempSensorInside = '28-000005ad1070'
TempSensorOutside = '28-000005ad0691'
# Yahoo location code. Get the right one for your location from Yahoo's weather page.
LocationID = '700029'
# ###################################################################################

# Disable useless GPIO warnings
GPIO.setwarnings(False)

# Start Yahoo weather stuff
# Weather array
# Dimensions: 1 = today, 2 = tomorrow
# Elements: 1 = day, 2 = date, 3 = low temp, 4 = high temp, 5 = weather text
Weatherarray = [["", "", "", "", ""] , ["", "", "", "", ""]]

# Fetch weather XML for Trier, Germany
Trier = urllib.urlopen('http://weather.yahooapis.com/forecastrss?w=' + LocationID + '&u=c').read()

# Parse the XML
Trier = parseString(Trier)

# Get town
Place = Trier.getElementsByTagName('yweather:location')[0]
City = Place.attributes["city"].value
Country = Place.attributes["country"].value

# Get date
Date = Trier.getElementsByTagName('lastBuildDate')[0].firstChild.data

# Get coordinates
Geo_Lat = Trier.getElementsByTagName('geo:lat')[0].firstChild.data
Geo_Long = Trier.getElementsByTagName('geo:long')[0].firstChild.data

# Get today's weather
Today = Trier.getElementsByTagName('yweather:condition')[0]
Weathertext = Today.attributes["text"].value
Temperature = float(Today.attributes["temp"].value)
Conditioncode = Today.attributes["code"].value

# Put it all in a list
for Counter in range(2):

    # Weather data for two days
    # Get data
    Future = Trier.getElementsByTagName('yweather:forecast')[Counter]

    # Process data
    Weatherarray[Counter][0] = Future.attributes["day"].value
    Weatherarray[Counter][1] = Future.attributes["date"].value
    Weatherarray[Counter][2] = float(Future.attributes["low"].value)
    Weatherarray[Counter][3] = float(Future.attributes["high"].value)
    Weatherarray[Counter][4] = Future.attributes["text"].value
# End Yahoo weather stuff.

# Start sensor stuff
# The inside sensor
# Open, read, close the sensor files
tempfilein = open("/sys/bus/w1/devices/" + TempSensorInside + "/w1_slave")

textin = tempfilein.read()

tempfilein.close()

# Jump to the right position in the sensor file, convert the string to a number, put the decimal point in
secondlinein = textin.split("\n")[1]
temperaturedatain = secondlinein.split(" ")[9]
temperaturein = float(temperaturedatain[2:])
temperaturein = temperaturein / 1000
# print temperaturein

# The outside sensor
tempfileout = open("/sys/bus/w1/devices/" + TempSensorOutside + "/w1_slave")

textout = tempfileout.read()

tempfileout.close()

# Jump to the right position in the sensor file, convert the string to a number, put the decimal point in
secondlineout = textout.split("\n")[1]
temperaturedataout = secondlineout.split(" ")[9]
temperatureout = float(temperaturedataout[2:])
temperatureout = temperatureout / 1000
# print temperatureout

lcd = CharLCD()


# Print the data onto the display.
lcd.clear()
lcd.write_string(time.strftime("%d.%m.%Y %H:%M"))
lcd.cursor_pos = (1, 0)
#lcd.write_string(str(City) + ' ')
lcd.write_string('Innen:  '+ str(temperaturein) + ' Grad')
lcd.cursor_pos = (2, 0)
lcd.write_string('Aussen: '+ str(temperatureout) + ' Grad')
lcd.cursor_pos = (3, 0)
lcd.write_string(Weathertext)

# Write the data to a webpage on the local server
# Get some weather icons that are compliant with Yahoo condition codes. The ones by MerlinTheRed are nice and work well <http://merlinthered.deviantart.com/art/plain-weather-icons-157162192> CC-BY-NC-SA
index = open('/var/www/aktuell.html','w')
index.write('<style type="text/css">body {font-weight:lighter; font-family:Arial; font-size:100%; } h2 {margin:0 0 0 0;}''</style><h6>Updated: ' + time.strftime("%d.%m.%Y %H:%M:%S") + '</h6>' + Weathertext + '<img src="' + Conditioncode + '.png" align="right" alt="Wettericon"><br> Sensordaten: <br> Innen:<br><h2>' + str(temperaturein) + ' °C</h2><br> Aussen:<br><h2>' + str(temperatureout) + '°C</h2><br>')
index.close()


 # Write data to a .csv file for graph creation
weather_csv = open('/home/pi/YAWP/weather.csv', 'a')
datawriter = csv.writer(weather_csv)
datawriter.writerow([str(time.strftime('%Y-%m-%d %H:%M')),str(temperaturein),str(temperatureout)])
weather_csv.close()

# From here, a gnuplot file will take over.
p = subprocess.Popen("gnuplot plotter.gpi", shell = True)
os.waitpid(p.pid, 0)

# Copy it over to the webserver
shutil.copy2('/home/pi/YAWP/temps.png', '/var/www/')
EN

回答 1

Code Review用户

回答已采纳

发布于 2014-05-16 14:16:07

基本结构

我建议创建一个Elements类。

代码语言:javascript
复制
class Elements():
    def __init__(self, day='', date='', low='', high='', weather=''):
        self.day = day
        self.date = date
        self.low = low
        self.high = high
        self.text= weather

然后,当需要设置值时,循环遍历元素并使用setattr函数设置属性:

代码语言:javascript
复制
# Creates `[Elements(), Elements()]`
weather_array = [Elements()]*2

...

for elem in weather_array:
    for prop in ['day', 'date', 'low', 'high', 'text']:
        val = Future.attributes[prop].value

        if prop == 'low' or prop == 'high':
            val = float(val)            
        setattr(elem, prop, val)

您可以使用elem.day直接访问属性,但是由于我们使用文本值访问Future's属性,因此对elem's也进行同样的访问是有意义的。

根据其他代码的结构,更多的类可能很有用。

字符串插值

在您的代码中有几次执行以下操作:

代码语言:javascript
复制
string = 'This is ' + foo + ' some string concatenation'

在很多情况下,字符串连接都很好。但是,在这种情况下,如果需要将一些变量信息与字符串结合起来,则应该使用str.format()。此语法允许您将一到多个信息插入到字符串中:

代码语言:javascript
复制
>>>'Hello {}!'.format('World')
'Hello World!'

文件

打开文件时使用with语法。一旦离开了块,它就会自动关闭文件:

代码语言:javascript
复制
with open('some_file.txt', 'r') as file:
    # Do something

# The file is closed at this point.
foo = 'hello world!'

因为我们只担心这两个文件中的第2行,所以只要读过这一行,就可以中断:

代码语言:javascript
复制
temp_data= ''
temperatures = {temp_sensor_inside:0.0, temp_sensor_outside:0.0}
for sensor in temperatures:
    with open('/sys/bus/w1/devices/{}/w1_slave'.format(sensor), 'r') as my_file:
        # Iterate line-by-line grabbing both the line number and its text
        for line, text in enumerate(my_file):
            if line == 2:
                temp_data = line.split(' ')[9]

                # Assign the correct variable.
                temperatures[sensor] = float(temp_data[2:])/1000

                break

os.join

每当您创建文件路径时,我建议您使用os.path.join。此函数确保基于当前操作系统使用正确的斜杠。

代码语言:javascript
复制
>>>import os.path
>>>file_path = os.path.join('~', 'Documents', 'my_file.txt')
>>>file_path
'~\\Documents\\my_file.txt'

闭幕词

除此之外,查看PEP8,官方的Python样式指南。这将有助于使您的代码看起来和感觉更Pythonic。我很快就看到了一些不遵循惯例的东西:

  1. 使用underscores_in_variable_names
  2. 空格和空格必须保持一致。
  3. import的顺序通常是:标准图书馆、第三方图书馆、本地图书馆

寻找可以将代码拆分为函数的位置。这将有助于提高可读性,并使程序更加模块化,这将极大地帮助程序的增长。

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/50911

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档