Does anyone know why this doesn't work?
Instead of printing the solution, it produces this error:
Traceback (most recent call last):
File "C:\Program Files\Python34\lib\tkinter__init__.py", line 1533,
in call return self.func(*args)
TypeError: solution1_s() missing 1 required positional argument: 'sol_s1'
solutions_s={
"sol_s1":"if this is happeing to you, there is a bug in the software. call up your supplier and they will try and troubleshoot the phone. make sure you have all the latest updates installed",
"sol_s2":"these are all signs of a virus. the deleting of applications is virus munching on your data, and pop ups on your scren is also a virus symptom. immiditely use your antivirus to look for the problem or take it to a repair shop where they can delete the virus",
"sol_app":"check if you have enogh storage on your device, if you dont and that was the problem, then see if you can get a storage upgrade. However, if it isnt there is a good chance you have a virus on your phone. scan your phone with an antivirus, or let your local repair shop do it",
"sol_pop":"if the pop ups are on a web browser, this is normal. try getting an ad blocker if it is bothering you, but do not click on them. however, if it is happening on the main screen, you have contracted a virus. use your antivirus orget it fixed at a repair shop",
"sol_s3":"this is another sign of a software fault. the only one who can fix this is your supplier. contact them as soon as possible"}
def solution1_s(sol_s1):
label20=Label(screen,text=solutions_s[sol_s1])
label20.pack()
sys.exit()
def solution2_s(sol_s2):
label22=Label(screen,text=solutions_s[sol_s2])
label22.pack()
sys.exit()
def solution_app(sol_app):
label23=Label(screen,text=solutions_s[sol_app])
label23.pack()
sys.exit()
def solution_pop(sol_pop):
label24=Label(screen,text=solutions_s[sol_pop])
label24.pack()
sys.exit()
def solution3_s(sol_s3):
label26=Label(screen,text=solutions_s[sol_s3])
label26.pack()
sys.exit()
When you put a variable in the function header like this:
def solution1_s(sol_s1):
Python expects that you pass it an argument, which can be anything, and names it sol_s1 within the scope of that function.
However, you appear to want to look up the key sol_s1 in the dictionary solutions_s, which you have declared in your script, instead.
Try this instead:
def solution1_s():
label20=Label(screen,text=solutions_s['sol_s1'])
label20.pack()
sys.exit()
Here's some reading material with in-depth discussion on scopes and dicts:
Scopes
Dictionaries
Related
This question already has an answer here:
How to use dill library for object serialization with shelve library
(1 answer)
Closed 2 years ago.
I'm teaching myself Python using a roguelike tutorial. I've hit a bug with saving the game, and I'm trying to figure out how to resolve it.
My save-game code is dirt simple, and looks like this:
def save_game(engine: Engine) -> None:
with shelve.open('savegame', 'n') as data_file:
data_file['engine'] = engine
Then "engine" object has all the game-state info I need. Most of the time, it works great.
However, I've found that the auto-save gets screwed up when it triggers after I use a fireball scroll:
AttributeError: Can't pickle local object 'FireballDamageConsumable.get_action.<locals>.<lambda>'
Poking around a bit, I gather that I need to somehow get dill into the mix. Just doing import dill isn't enough.
However! Before I solve THAT problem, I have another problem I'd like to solve first while I still have this bug that lets me see it.
If I quite the game immediately after the failed save, my save file is now corrupted. The auto-load feature won't pick it up (and in the current state of the game, that means I have to delete the save file manually). An auto-save that periodically corrupts its own save file seems like a much more significant problem.
So, my question is really a two-parter:
How to I refactor my save_game method to be smarter? How do I prevent it from corrupting the file if something goes wrong? Should I pre-pickle the engine object, and only do shelve.open if that doesn't throw any errors? Is there a simple way for me to create a backup file from the old data and then revert to it if something goes awry? (Edit: Think I might have this part working.)
Once Part 1 is resolved, is there a way for me to tweak my call to shelve so that it doesn't get confused by lambdas? Do I just need to by hyper-vigilant any time a lambda shows up in my code and make sure it gets omitted from the state I'm trying to save? Are there any other "gotchas" I need to be aware of that would make this kind of brute force "Just save the entire game state" approach a bad idea?
Thanks in advance for any guidance anyone can offer.
Edit:
I did put together some code for backing up the save file that seems to do the job. I'm tossing it in here just in case someone wants to point me towards some common/built-in Python utility that does all this work for me. Failing that, this seems to prevent the autosave from corrupting its own file. Now I just have to figure out why it was trying to corrupt the file in the first place.
SAVE_FILE_BASE = 'savegame'
SAVE_FILE_LIST = [SAVE_FILE_BASE + '.dat', SAVE_FILE_BASE + '.dir', SAVE_FILE_BASE + '.bak']
def save_game(engine: Engine) -> None:
# Make a copy of the old save file (if it exists) just in case this one gets janked.
backup()
try:
with shelve.open(SAVE_FILE_BASE, 'n') as data_file:
data_file['engine'] = engine
purge_backups()
data_file.close()
except Exception:
data_file.close()
traceback.print_exc()
restore_backups()
def backup() -> None:
[cautious_copy(file, file + '.bak') for file in SAVE_FILE_LIST]
def restore_backups() -> None:
[cautious_move(file + '.bak', file) for file in SAVE_FILE_LIST]
def purge_backups() -> None:
[cautious_remove(file + '.bak') for file in SAVE_FILE_LIST]
def cautious_copy(src: str, dest: str) -> None:
if os.path.isfile(src):
copy2(src, dest)
def cautious_move(src: str, dest: str) -> None:
if os.path.isfile(src):
move(src, dest)
def cautious_remove(file: str) -> None:
if os.path.isfile(file):
os.remove(file)
Ah-ha! Looks like this question fixes my problem:
How to use dill library for object serialization with shelve library
Plugging this into the import statements does the trick:
from dill import Pickler, Unpickler
shelve.Pickler = Pickler
shelve.Unpickler = Unpickler
This question already has answers here:
What exactly is file.flush() doing?
(4 answers)
Closed 4 years ago.
I have made a program which monitors the keyboard and writes all pressed keys in the document, but to save changes it have to be close, how i can update information without closing? I am using lib "pynput"
I have tried to make a loop for opening and closing doccument but it hasn't worked corectly.
#input the lib
from pynput import keyboard
file = open("test.txt", "a")
def on_press(key):
'''check pressed keys, AttributeError is for special keys'''
try:
file.write(key.char)
except AttributeError:
file.write('{0}'.format(key))
def on_release(key):
'''if that keys pressed go to a new line, if esc than stop a program and save changes'''
if key == keyboard.Key.space:
file.write("\n")
if key == keyboard.Key.enter:
file.write("\n")
if key == keyboard.Key.esc:
file.write("\n")
# Stop listener
return False
# Collect events until released
with keyboard.Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
file.close()
I want it to save changes in a real time.
You can use file.flush() for your specific use-case. You might need to follow up with os.fsync(file.fileno())
As per the documentation, it will "[...] force write of file with filedescriptor fd to disk. On Unix, this calls the native fsync() function; on Windows, the MS _commit() function"
Check out the official documentation, along with some other discussions on this very issue. I've seen this re-asked on StackOverflow, but I opted to respond as it was under the Python-3.x tag, and people can offer Python3-specific hints.
Let me know if this works, and if not, what's your platform
I am following a tutorial over at https://blog.patricktriest.com/analyzing-cryptocurrencies-python/ and I've got a bit stuck. I am tyring to define, then immediately call, a function.
My code is as follows:
def merge_dfs_on_column(dataframes, labels, col):
'''merge a single column of each dataframe on to a new combined dataframe'''
series_dict={}
for index in range(len(dataframes)):
series_dict[labels[index]]=dataframes[index][col]
return pd.DataFrame(series_dict)
# Merge the BTC price dataseries into a single dataframe
btc_usd_datasets= merge_dfs_on_column(list(exchange_data.values()),list(exchange_data.keys()),'Weighted Price')
I can clearly see that I have defined the merge_dfs_on_column fucntion and I think the syntax is correct, however, when I call the function on the last line, I get the following error:
NameError Traceback (most recent call last)
<ipython-input-22-a113142205e3> in <module>()
1 # Merge the BTC price dataseries into a single dataframe
----> 2 btc_usd_datasets= merge_dfs_on_column(list(exchange_data.values()),list(exchange_data.keys()),'Weighted Price')
NameError: name 'merge_dfs_on_column' is not defined
I have Googled for answers and carefully checked the syntax, but I can't see why that function isn't recognised when called.
Your function definition isn't getting executed by the Python interpreter before you call the function.
Double check what is getting executed and when. In Jupyter it's possible to run code out of input-order, which seems to be what you are accidentally doing. (perhaps try 'Run All')
Well, if you're defining yourself,
Then you probably have copy and pasted it directly from somewhere on the web and it might have characters that you are probably not able to see.
Just define that function by typing it and use pass and comment out other code and see if it is working or not.
"run all" does not work.
Shutting down the kernel and restarting does not help either.
If I write:
def whatever(a):
return a*2
whatever("hallo")
in the next cell, this works.
I have also experienced this kind of problem frequently in jupyter notebook
But after replacing %% with %%time the error resolved. I didn't know why?
So,after some browsing i get that this is not jupyter notenook issue,it is ipython issueand here is the issue and also this problem is answered in this stackoverflow question
I am trying to update the firmware of a controller through a serial interface. To do this, I must send a reboot message to the controller (no problem there) and then send another message (the character 'w') THE MOMENT it starts up so that it may start up in write mode. This is easily done with the minicom utility by pressing w continuously while the device restarts.
I want to achieve this functionality using python code instead, but I can't figure out how to send a message until the device is up without throwing exceptions (since the device is not connected).
This is what I have tried, but it does not work (with pyserial):
def send_w(serial_port, baud_rate):
msgw = "w_"
ans = ""
ser = serial.Serial(port=serial_port, baudrate=baud_rate,timeout = 10)
ser.write(msgw)
ans = ser.read(24)
ser.close()
print(ans)
return ans
def set_firmware_version(serial_port, baud_rate):
s = ""
try:
with serial.Serial(serial_port,baud_rate,timeout=1) as ser:
msgr = "%reset "+sk+"_"
ser.write(msgr)
ser.close()
print("reset")
except (IOError) as e:
print("Error in: set_firmware_version")
print(e)
return s
time.sleep(1)
send_w(serial_port, baud_rate)
set_firmware_version(sp,br)
This gives the following error:
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)
I also tried sending the messages in a loop with a short timeout, but had the same problem. Is there any way to send a message continuously and disregard exceptions if the device is not found?
Any help will be greatly appreciated.
Full Traceback:
Traceback (most recent call last):
File "mc_config.py", line 69, in <module>
set_firmware_version(sp,br)
File "mc_config.py", line 64, in set_firmware_version
send_w(serial_port, baud_rate)
File "mc_config.py", line 46, in send_w
ans = ser.read(24)
File "/home/avidbots/.local/lib/python2.7/site-packages/serial/serialposix.py", line 501, in read
'device reports readiness to read but returned no data '
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)
(I am using ubuntu 16.04 and python 3)
What if you put the excepting code into a try and then catch the exception with an except serial.serialutil.SerialException {...} block?
Clearly there's a significant window of time to submit the w ( otherwise the "press w" method wouldn't often work.) Your requirement, then, would be to retry only the part of the code that's absolutely necessary to send the w, so that you send it quickly enough to "catch" the system in its bootup state. Since the backtrace shows that the exceptions occurs in send_w, then you can add try/except blocks and a while loop around what is now one line at the end of set_firmware_version.
Instead of just this:
send_w(serial_port, baud_rate)
Something like this might solve the problem:
while True:
try:
send_w(serial_port, baud_rate)
break
except serial.serialutil.SerialException:
pass # retry
You may need to change your imports to expose that exception, fyi. And you may need to consider whether you're catching too many possible exceptions - it's possible that exception might also represent other errors that shouldn't be retried. You might also need to add a small sleep time there - this is essentially a busy wait loop (https://en.wikipedia.org/wiki/Busy_waiting).
if __name__ == "__main__":
with open("log.txt", 'r') as f:
content = f.readlines()
for i, line in enumerate(content):
I am using above code to read text file. But it only gets current data
Depending on operating system, you have a couple of choices.
Check if the file has changed since last time.
In Linux there is this "new" functionality that will inform you of changes made to a file.
It was a while back since I tried to work with something similar and guess what, there is this package you can use that has solved this problem.
I believe it was this package I used, not sure. But the documentation claims to give you some methods to use:
http://pythonhosted.org/watchdog/