How to get files written by the micro:bit to the PC? - python

I am new to BBC micro:bit, so I have the following Problem:
I want to read movements and write it to a file on the m:b and after all I want to download it from there to the pc to work on it.
I wrote the file like that:
from microbit import *
with open('FileName.txt', 'w') as my_file:
my_file.write('text to write down')
I couldn't see the file, when I used the m:b as USB- device.
But when I programmed the m:b to list all files it wrote short before the file was on it.
I know, m:b has no disk operating System, so I tried to pull it with python code, I started the following python code on a Windows pc:
(see: Docs to microfs)
import microfs
print microfs.ls()
But I got the error IOError: Could not find micro:bit.
The m:b is not found, I suppose.
What am I doing wrong? What else could I try?

Sometimes if the micro:bit cannot be found by scripts like uFlash or MicroFs it helps if you unplug the USB cable, wait a few seconds and plug it again (an additional note for Linux users, although I am aware that this is not the case for you, on Linux is also helpful to wait until the micro:bit drive has been mounted).
You are in the right track using MicroFs to access the MicroPython files, as they are in the microcontroller flash, and not accessible through the USB mass storage interface. Remember that writing a new program into the micro:bit does erase all of the flash contents, including any files your previous program might have created.
For easy of use I would recommend using the Mu editor (https://codewith.mu), as it offers you a GUI to move files in and out of the micro:bit. It's worth noting that Mu uses uFlash and MicroFs internally, so it will give you the same results as using those individual command line tools.

I, too, have spent several hours searching for the answer to getting microfs and mu to read a file from the microbit, after receiving the 'can't find it' message.
I have just found a solution: update the microbit firmware.
I have flashed an empty Python file from mu to the microbit and then used the command line ufs put <path to file>\main.py to copy over code that creates a text file and displays a heart on the microbit.
Now the Files option in mu correctly displays main.py and the created text file on my microbit.
I hope this helps.

As mentioned, you can use the command line ufs to put, get, list and delete files on the microbit.
pip install microfs --user
Then use ufs to list, delete, put and get files on to and off the microbit.
github site: https://github.com/ntoll/microfs.
The commands are:
ufs ls #list files on the card
ufs rm <filename> # remove a file
ufs put <filename> # write a file to the micro:bit
ufs get <filename> # get a file from the micro:bit
First of all put a blank .py file on to the micro:bit. In Linux you can create this using:
touch empty.py
Connect with microbit by double clicking on it using your file browser (e.g. Nautilus in Linux).
Use mu to flash empty.py onto the microbit.
Then write your Micropython code and call it main.py. Use ufs to write main.py to the micro:bit.
ufs main.py
This file will run at reset and restart. You can have your main.py file import and use other Micropython files on the micro:bit. Put these onto the micro:bit using ufs.
ufs <file to import to main.py>.py
e.g.
ufs put utilities.py
The files can be overwritten using ufs put.
You can't use ufs and a repl at the same time.
Now you are in a position to write and read a text file. Please find two example functions I have used for this.
def read_file(filename):
with open(filename, 'r') as my_file:
read_value = my_file.read()
return read_value
def write_file(filename, value):
with open(filename, 'w') as my_file:
my_file.write(str(value))
my_file.close()
The files are written to the microbit and the data remains intact after repowering the device. The data file can be seen using:
ufs ls
Then copied to your local machine using:
ufs get <filename>

Related

PYTHON AND BATCH SCRIPT: Run file if it exists and create if it doesn't

Full Disclaimer: I DO NOT KNOW PYTHON.
Hi Guys,
I have made an AutoHotKey Script for my volume keys. I would like to create a batch file which runs a python file (so if I change computers, I can easily create this scripts) which would do the following
Check if volume_keys.ahk exists in the D Drive
If it exists, run that;
If it doesn't exist, then create a file named volume_keys.ahk and add my script to it.
My script is:
^!NumpadMult::Send {Volume_Mute}
^!NumpadAdd::Send {Volume_Up}
^!NumpadSub::Send {Volume_Down}
I know how to code the .bat file and just need help for the python point-of-view, but I request the community to check it:
#ECHO OFF
ECHO This script will run an AHK Script. If you want to stop this process from happening, then cross this window off.If you want to continye:
pause
cd d:
D:\run_volume_keys_ahk_script.py
I really appreciate any help by the community.
Thanks in advance
You can use the os library for this. Here's what the python program would look like.
import os
if os.path.isfile('D:\\volume_keys.ahk'): # check if it exists
os.system('D:\\volume_keys.ahk') # execute it
else:
with open('D:\\volume_keys.ahk', 'w') as f: # open it in w (write) mode
f.write('^!NumpadMult::Send {Volume_Mute} \
^!NumpadAdd::Send {Volume_Up} \
^!NumpadSub::Send {Volume_Down}') # Write to file
os.system('D:\\volume_keys.ahk') # execute
To activate the ahk script, you might want to use the subprocess module, of which I took the example from here
import subprocess
subprocess.call(["path/to/ahk.exe", "script.ahk"])
Note that you'll have to find the ahk executable on a computer before you can use the script, maybe you want to automatically check that too.
You can set the path you want to check for scripts in one string, and then add the filenames of your scripts as strings to a list. You can use listdir() from the os module to see any files and directories at a given path, then iterate over your scriptnames and check if it exists in that list of files. If it does, run it.
In this example I copy-pasted your script into a string as value for the key 'scriptname' in a dictionary, so that python can actually create the script file. This isn't really a neat way to do it though, you might want to have your scripts prepared in a directory next to your python script and copy them from there. See an example of how here
from os import listdir
from os.path import isfile, join
CHECK_PATH = "D:"
AHK_EXECUTABLE_PATH = "path/to/ahk.exe"
SCRIPTS_TO_CHECK = {'script1.ahk':"""^!NumpadMult::Send {Volume_Mute}
^!NumpadAdd::Send {Volume_Up}
^!NumpadSub::Send {Volume_Down} """, 'script2.ahk':" some other script here"}
files_to_check = set(listdir(CHECK_PATH)) # using a set for fast lookup later
for scriptname, script in SCRIPTS_TO_CHECK.items():
if not scriptname in files_to_check:
print(f"script {scriptname} not found, creating it.")
with open(scriptname, 'w') as file:
file.write(script)
# else
subprocess.call(AHK_EXECUTABLE_PATH, scriptname)

Editing temporary file with Vim in Python subprocess not working as expected on Mac OS

My initial goal was to get user input via a command-line text-editor from within a Python script. More specifically, my plan was to create a temporary file and populate it with some pre-written text, open the file with a text-editor and allow the user to modify the file content, read the data from the file after the user exits the editor, then finally delete the file after it's all over.
I seem to have found a way to do this that is working for me, but along the way I tried a couple of approaches that did not work and I'd like to understand exactly why.
Consider the following Python script (a slightly modified version of the script taken from this post):
#!/usr/bin/env python2
# -*- encoding: ascii -*-
"""callvim.py
Demonstrates calling a text-editor (e.g. Vim) from within a Python script,
including passing input to the editor and reading output from the editor.
"""
import tempfile
import os
from subprocess import call
# Get the text editor from the shell, otherwise default to Vim
EDITOR = os.environ.get('EDITOR','vim')
# Set initial input with which to populate the buffer
initial_message = "Hello world!"
# Open a temporary file to communicate through
with tempfile.NamedTemporaryFile(suffix=".tmp") as tf:
# Write the initial content to the file I/O buffer
tf.write(initial_message)
# Flush the I/O buffer to make sure the data is written to the file
tf.flush()
# Open the file with the text editor
call([EDITOR, tf.name])
# Rewind the file offset to the beginning of the file
tf.seek(0)
# Read the file data into a variable
edited_message = tf.read()
# Output the data
print(edited_message)
I've tried running this script in two different environments so far: on a macOS computer (running macOS 10.12) and on a Debian computer (running Debian 8.8). Both computers have the same (minor) version of Vim installed (Vim 7.4).
When I run this script with EDITOR=vim on my Debian 8 (Jessie) machine it works as expected. I'm prompted with Vim and a buffer containing the string "Hello world!". After editing the buffer to contain the string "Goodbye world!", saving the file, and exiting Vim, I see the string "Goodbye world!" printed to the console.
When I run the same script on my macOS 10.12 (Sierra) machine it does not seem to work. The same procedure results in "Hello world!" being displayed on-screen - as if the file is being read before it is edited.
However if run the script on my Mac with EDITOR=nano then once again everything seems to work as expected.
I tried a few variations on this script using different methods from the tempfile module (e.g. using tempfile.TemporaryFile() and tempfile.mkstemp()) with the same results.
Now consider the following alternative script:
#!/usr/bin/env python2
# -*- encoding: ascii -*-
"""callvim.py
Demonstrates calling a text-editor (e.g. Vim) from within a Python script,
including passing input to the editor and reading output from the editor.
"""
import subprocess
import os
# Create a temporary file and write some default text
file_path = "tempfile"
file_handle = open(file_path, "w")
file_handle.write("Hello world!")
file_handle.close()
# Open the file with Vim
subprocess.call(["vim", file_path])
# Rewind to the beginning of the file
file_handle = open(file_path, 'r')
# Read the data from the file
data = file_handle.read()
# Close the temporary file
file_handle.close()
# Delete the temporary file
os.remove(file_path)
# Print the data
print(data)
This script, which avoids using the tempfile module, appears to be working consistently across both platforms.
So it seems that this script may be failing for some reason having to do with how Vim and the tempfile Python module interact on macOS. What's going on here?
This is happening because your second script closes the file handle before invoking vim, then opens a new one afterwards, whereas the first script doesn't. It has nothing to do with the tempfile module per se. This code works as expected:
import tempfile, os
from subprocess import call
initial_message = "Hello world!"
tf = tempfile.NamedTemporaryFile(suffix=".tmp", delete=False)
tf.write(initial_message)
tf.close()
call(['vim', tf.name])
tf = open(tf.name, 'r')
edited_message = tf.read()
tf.close()
os.unlink(tf.name)
print(edited_message)
Note the delete=False in the call to NamedTemporaryFile, which ensures that the file isn't deleted when we close it the first time (we have to delete it manually with os.unlink later).
I think what's going on here is that vim isn't editing your file in-place, it's writing to a swap file. When you save and quit, vim replaces the original file with the edited one, leaving your file handle pointing to the old, unedited one. There are ways to prevent vim from using swap files (see, e.g. here), but I wouldn't recommend them. Just remember to update your file handles after vim has done its business.

Python for Data Analysis, Chapter 2, first example

I'm following along with the examples in a translated version of Wes McKinney's "Python for Data Analysis" and I was blocked in first example of Chapter 2
I think my problem arose because I saved a data file in a wrong path. is that right?
I stored a file, usagov_bitly_data2012-03-16-1331923249.txt, in C:\Users\HRR
and also stored folder, pydata-book-mater, that can be downloaded from http://github.com/pydata-book in C:\Users\HRR\Anaconda2\Library\bin.
Depends.
You might change the location you save your File or eddit the path you give to your code in Line 10. Since you're yousing relativ Paths i guess your script runs in C:\Users\HRR\Anaconda2\Library\bin, which means you have to go back to C:\Users\HRR or use an absolute Path ... or move the File, but hell you don't want to move a file every time you want to open it, like moving word files into msoffice file to open it, so try to change the Path.
And allways try harder ;)
In python open() will open from the current directory down unless given a full path (in linux that starts with / and windows <C>://). In your case the command is open the folder ch02 in the directory the script is running from and then open usagov_bitly_data2012-03-16-1331923249.txt in that folder.
Since you are storing the text file in C:\Users\HRR\usagov_bitly_data2012-03-16-1331923249.txt and you did not specify the directory of the script. I recommend the following command instead open(C:\\Users\\HRR\\usagov_bitly_data2012-03-16-1331923249.txt)
Note: the double \ is to escape the characters and avoid tabs and newlines showing up in the path.

python: i have an error while trying this on my mac using IDLE on mac or terminal

i want to see some info and get info about my os with python as in my tutorial but actually can't run this code:
import os
F = os.popen('dir')
and this :
F.readline()
' Volume in drive C has no label.\n'
F = os.popen('dir') # Read by sized blocks
F.read(50)
' Volume in drive C has no label.\n Volume Serial Nu'
os.popen('dir').readlines()[0] # Read all lines: index
' Volume in drive C has no label.\n'
os.popen('dir').read()[:50] # Read all at once: slice
' Volume in drive C has no label.\n Volume Serial Nu'
for line in os.popen('dir'): # File line iterator loop
... print(line.rstrip())
this is the the error for the first on terminal, (on IDLE it return just an '
f = open('dir')
Traceback (most recent call last):
File "", line 1, in
FileNotFoundError: [Errno 2] No such file or directory: 'dir'
I know on mac it should be different but how? to get the same result
using macOS sierra.
os.popen executes a program and returns a file-like object to read the program output. So, os.popen('dir') runs the dir command (which lists information about your hard drive) and gives you the result. open opens a file on your hard drive for reading.
Your problem is that there is no file named dir. You likely wanted f = os.popen(dir) MAC is different than windows and the base directory listing command is ls. But most unixy systems have a dir command that lists files in a different format, so it should work for you.
The code you are following looks like it was written for Windows. popen runs a command -- but there is no dir command on a Mac. dir in DOS shows you files in a directory (folder); the equivalent command on a Mac is ls.
open and os.popen are entirely different*.
The first one just opens a file (by default for reading), but the second one runs a command in your shell and gives you the ability to communicate with it (e.g. get the output).
So, given that open opens the file for reading when you supply only the file's name, if such a file doesn't exist, it raises an error, which is the case here.
os.popen executes the given command on your computer as if you typed it in the terminal.
* There exists another function with a similar name: os.open, which is, again, different from the ones mentioned earlier.

Vim cannot save to temporary files created by python

Goal
I am trying to create and edit a temporary file in vim (exactly the same behavior as a commit script in git/hg/svn).
Current code
I found a method to do so in this answer:
call up an EDITOR (vim) from a python script
import sys, tempfile, os
from subprocess import call
EDITOR = os.environ.get('EDITOR','vim')
initial_message = "write message here:"
with tempfile.NamedTemporaryFile(suffix=".tmp") as tmp:
tmp.write(initial_message)
tmp.flush()
call([EDITOR, tmp.name])
tmp.seek(0)
print tmp.read()
The Issue
When I run the above code, the tempfile does not read the changes made in vim. Here is the output after I have added several other lines in vim:
fgimenez#dn0a22805f> ./note.py
Please edit the file:
fgimenez#dn0a22805f>
Now for the interesting (weird) part. If I change my editor to nano or emacs, the script works just fine! So far, this only seems to break when I use vim or textedit.
As another experiment, I tried calling a couple editors in a row to see what happens. The modified code is:
with tempfile.NamedTemporaryFile(suffix=".tmp") as tmp:
tmp.write(initial_message)
tmp.flush()
# CALLING TWO EDITORS HERE, VIM THEN NANO
call(['vim', tmp.name])
raw_input("pausing between editors, just press enter")
call(['nano', tmp.name])
tmp.seek(0)
print tmp.read()
I.e. I edit with vim then nano. What happens is that nano DOES register the changes made by vim, but python doesn't register anything (same result as before):
fgimenez#dn0a22805f> ./note.py
Please edit the file:
fgimenez#dn0a22805f>
BUT, if I edit with nano first, then vim, python still registers the nano edits but not the vim ones!
with tempfile.NamedTemporaryFile(suffix=".tmp") as tmp:
tmp.write(initial_message)
tmp.flush()
# CALLING TWO EDITORS HERE, NANO THEN VIM
call(['nano', tmp.name])
raw_input("pausing between editors, just press enter")
call(['vim', tmp.name])
tmp.seek(0)
print tmp.read()
Ouput from running the program and adding a\nb\nc in nano and d\ne\nf in vim:
fgimenez#dn0a22805f> ./note.py
Please edit the file:
a
b
c
fgimenez#dn0a22805f>
It seems as if using vim or textedit eliminates the ability to append to the file. I'm completely confused here, and I just want to edit my notes in vim...
Edit 1: Clarifications
I am on osx Mavericks
I call vim from the shell (not MacVim) and end the session with ZZ (also tried :w :q)
I'm no Python expert, but it looks like you're keeping the handle to the temp file open while Vim is editing the file, and then attempt to read in the edited contents from the handle. By default, Vim creates a copy of the original file, writes the new contents to another file, and then renames it to the original (see :help 'backupcopy' for the details; other editors like nano apparently don't do it this way). This means that the Python handle still points to the original file (even though it may have already been deleted from the file system, depending on the Vim settings), and you get the original content.
You either need to reconfigure Vim (see :help 'writebackup'), or (better) change the Python implementation to re-open the same temp file name after Vim has exited, in order to get a handle to the new written file contents.
I had the same problem on OS X after my code worked fine on Linux. As Ingo suggests, you can get the latest contents by re-opening the file. To do this, you probably want to create a temporary file with delete=False and then explicitly delete the file when you're done:
import sys, tempfile, os
from subprocess import call
EDITOR = os.environ.get('EDITOR','vim')
initial_message = "write message here:"
with tempfile.NamedTemporaryFile(suffix=".tmp", delete=False) as tmp:
tmp.write(initial_message)
tmp.flush()
call([EDITOR, tmp.name])
tmp.close()
with open(tmp.name) as f:
print f.read()
os.unlink(tmp.name)

Categories