The implementation of forward is horrible. The only correct way of expressing it is to make all four motors go forward. As an analogy, how would you react if your keyboard manufacturer told you "oh sorry, we made a mistake, you have to type every second letter in uppercase to get a lowercase word"? That would be non-intuitive.
The API you provide must be as ...
From my experience, kids understand DRY without explanation, and in fact they are very bored by the repetition.
which led to some motors accepting "backwards" as "forward"
This is I am afraid a dire mistake. Fix it as soon as you can, because it may ruin kid's intuition.Even I can't grok why forward method is so asymmetric.
Do not rely on magic numbers ...
A few things jump out at me immediately:
Use sizeof() whenever you need the size of something with non-dynamic allocation. In other words, all of your write calls on the WaveHeader struct members should be using sizeof, not hard coded sizes.
Allocation and initialization should be separate concerns. There's no need to have the same method that initializes a ...
This is very interesting. I love it. Good work.
with sr.Microphone() as sauce:
Sauce is what you add to pasta. Microphone is a source.
duckurl = "https://www.duckduckgo.com/?q="
This function is too long and should be shortened.
We can use a ...
Do not call main recursively. You are setting yourself up for stack overflow. Consider instead
except Exception as e:
Testing for counter == 4 is better done in a loop:
for _ in range(4):
I would suggest to separate the concerns of coloring and animating. Now, in particular theater_chase_rainbow duplicates code from other methods. Instead, have theater_chase take a color array as parameter. If you then add some animation styles and color schemes you can have \$O(n^2)\$ amount of fun trying all combinations.
It seems to me that in this code i +...
In C, I'd rather accept a pointer to a struct to be initialized than return newly allocated heap memory. It's clear that the caller owns the memory. The caller has the flexibility to pass you a pointer to a struct on its stack.
void initWAVHeader(WaveHeader *hdr, uint32_t sample_rate, uint16_t bit_depth, uint16_t channels);
The same goes for the rest of ...
1. Comments on your code
You make quite a lot of use here of os.system, which runs a command in a subshell. This can be a risky function to use, because the shell can do anything. For example, you write
os.system ("rm " + str(hometime_path))
but what if hometime_path were -rf *?
You're probably safe in this particular program because it's only for your ...
Here is a list of things I would improve:
define constants in upper-case (PEP8 reference)
put the main program logic into the if __name__ == '__main__': to avoid it being executed on import
naming according to PEP8 - getLine() to get_line() (or even better name would be something like get_stats())
remove unused sys import
follow the PEP8 import organization ...
Have you already executed the code to see how it performs and if the battery will last? There is that famous Donald Knuth quote saying premature optimization is the root of all evil (or at least most of it) in programming.
I never had to think about the energy consumption of a program, so I cannot tell you about the power efficieny. But as vnp already did, ...
Too much to put as a comment, so this is going to be an answer :
As a general comment, you use many variables which are used only once, so they might not really be useful.
ckyorn can be rewritten in a more concise way. Also, its name is weird and one of the parameters is not used.
def ckyorn( prompt):
"""Used for Y/N prompt"""
Since this is my idea, I'll share it. (Though, alecxe beat me to the rest of my suggestions)
Use datetime.utcnow().strftime from datetime instead of time.gmtime
As I stated in my comment, I would use a more understandable command than time.gmtime.
(1) Replace import time with from datetime import datetime.
(2) Your date assignment will be like this ...
I'm aware that you are a beginner. So I will try to improve your code starting from the most obvious problems and try advance step by step.
Names like x, y, z are an absolute no-go (unless naming coordinates). This is like naming them guesswhat. Names should describe what the variable holds as close to natural language as possible. So legal ...
I'll add my small contribution even though I'm not really a Python developer (hopefully some day). I've taken your update method and tested it on my computer (desktop, i3-4360@ 3.70GHz × 4 ), without the SDR bit. And my intuition was right!
Like in most languages allowing you to do it, don't ever do that:
self.fft_data = np.append(self.fft_data, self....
Your recordWAV is supposed to receive a header that has been setup with
genericWAVHeader. That function takes the desired sample rate and applies
it to the header. However, within recordWAV, the functions that setup the
PCM handle parameters determine the real sample rate (your call to
snd_pcm_hw_params_set_rate_near modifies the suggested sample rate) and ...
Opening and closing files takes resources:
with open('babar.txt', 'a') as f: f.write('a'*10000)
takes 300 micro-seconds while:
for _ in range(10000):
with open('babar.txt', 'a') as f: f.write('a')
takes 648000 micro-seconds
So to answer your question Would it be beneficial to write 10 rows at once instead of writing one row at a time?. The answer, ...
When I get my new hardware (looks like two-three days from now) I'm going to be adding a BMP180 sensor (barometric pressure/altitude).
I'm going to be replacing this with a DHT22, but that's one LoC change
I’m going to address these bits, but will build upon @alecxe and @ThomasWard answers, so check them out first.
The thing to note is that both the ...
Neat idea with that script. It looks good; not bad for the first program. Just a few comments:
I would improve some variable names: file_modification_time -> phone_last_seen_time, file_delta_time -> phone_unseen_duration. When I was reading the program it took me some time to figure out their purpose.
Use while True: instead of while finished == 1: so it ...
In general your script looks good when considering the style and structure, but there are a few issues:
Strange name for check_ntp_time – This holds the time since the last time you did time.time(), and in reality is a temporary variable for when you need to check it the last time. It doesn't convey the real purpose of the variable.
I would rather do ...
raw_ultrasonic_measure measures the duration of an echo staying high. It is not related to the distance in any way, it is just a duration of trig signal.
You need a time elapsed from the beginning of a signal to reception of echo - that is, a duration of echo being low.
In a quick and dirty way,
signal_start = micros();
Python has an official style guide, PEP8. It won't hurt getting familiar with it, since it helps keeping your code readable, consistent and ready for others to mess with.
Combining Italian and English gets confusing fast. It's also unhelpful for those of us that don't read Italian. There's also a distinct lack of whitespace between blocks of code and one-...
Right now you have a pretty large dependency staring right at you on the first line.
With that one declaration, I now know that your "library" is tailored to a specific sound architecture. Try running your code on Windows or a Mac, and your library won't cut it.
Instead, you may need to write a wrapper for a ...
You should probably prefer #!/usr/bin/env python3 as it's less likely to vary on different systems. It's not a big deal, though.
You should use snake_case, even for IP, so names like get_ip and send_ip.
Don't call os.system; use subprocess.Popen instead:
subprocess.Popen('dig +short myip.opendns.com @resolver1.opendns.com > raspip.txt'.split())
Keep your #define constant names consistent. You specify that LED_RED, LED_GRN, and LED_BLU are LEDs, but you don't specify what B1 is. A better name would be BTN_B1.
Keep your bracing consistent. Stick to one indentation style. For example in your code, you have both
Not bad for a first program.
You do formatting work in a couple of places, most notably in getLine(). What does "getLine" even mean? In this context, it only gives you half a line! I recommend deferring formatting until as late as possible, since stringifying data degrades it and makes it less reusable. Returning a tuple would be preferable.
I suggest ...
Here are some code style and organization notes:
remove unused imports (sys, requests)
import time is also not needed since you are immediately shadowing it after by defining the variable time
missing datetime import
organize imports per PEP8
use consistent 4-space indents
no need for extra space after the function and before the opening parenthesis - e.g. ...
Let's start at the Architecture of your Application and the data transfer.
There's basically two places where we can optimize the performance of your application. I'm ignoring latency for now, since that is mostly determined by the network and the performance of the image processing.
This means if we can improve the speed of image ...
I wrote a Pi+python control program so I had a quick look at what I did.
Interestingly I noticed that I seem to have had the same problem with forwards and backwards. I found this comment:
# Forwards and backwards are the same for left and right
# The trick is to reverse the motor connections for one side :-)
Thus I solved it by swapping the connections ...
arecord --device=hw:1,0 --format S16_LE --rate 44100 -d 2 /dev/shm/tmp_rec.wav ; sox -t .wav /dev/shm/tmp_rec.wav -n stat 2>&1 | grep "RMS amplitude" | tail -c 9
You can use newlines instead of ; and after | to make it easier to see the separate commands:
arecord --device=hw:1,0 --format S16_LE --rate 44100 -d 2 /dev/shm/tmp_rec....
I would recommend creating an Elements class.
def __init__(self, day='', date='', low='', high='', weather=''):
self.day = day
self.date = date
self.low = low
self.high = high
Then, when you need to set the values, loop through the elements and set the ...