I am connected to a PLC with Python. This PLC, gives alarm conditions in an 8-bit representation. For example:
0110 0010
bit 0 = lights on/off
bit 1 = fan is on/off
bit 2 = alarm on/off
bit 3 = door on/off
...
Each bit tells different conditions.
I want to create a list of conditions and print them together, like: door is on, alarms is off , lights are off, etc..
In the above example there are three different conditions. I want to show them together, all of them can be 1 or 0. How can I associate faults/conditions with bits?
For these types of tasks I like to set up a dictionary with the bits mapped to the nice text representation. Because Python supports binary literals it's quite nicely self-documenting...
Something like:
status_lookup = { 0b00000001 : "Lights",
0b00000010 : "Fan",
0b00000100 : "Alarm",
0b00001000 : "Door"}
Then if you wanted a list of the currently "on" statuses:
bits = 0x0a # or whatever your input value was
currently_on = [status_lookup[i] for i in status_lookup if i & bits]
If you want to join them together in a string:
print("; ".join(currently_on))
As an alternative, if you're using Python 3.4+ you could do something similar using the new enum module:
from enum import IntEnum
class Status(IntEnum):
Lights = 0b00000001
Fan = 0b00000010
Alarm = 0b00000100
Door = 0b00001000
bits = 0x0a
currently_on = [x for x in Status if x & bits]
There are more elegant ways of doing it, but this will get you going:
s = ''
if value & 1:
s += "lights on"
else:
s += "lights off"
if value & 2:
s += ", fan on"
else:
s += ", fan off"
if value & 4:
s += ", alarm on"
else:
s += ", alarm off"
if value & 8:
s += ", door on" #? "door open"?
else:
s += ", door off"
Related
I am creating a quiz program with python. There are three text files, one for outputting the question (works), one for checking if the user input the correct (works) and one for updating mastery. The latter isn't working. A question is mastered when is answered correct three times. I want to update the mastery from the text file to go from zero to one (and so on).
When I run my program it replaces the first line with 1, however the two 0's below it go missing and I therefore recieve an index out of range error. I am open to trying other methods.
This is the code I am attempting to implement the code below into my own program:
with open('stats.txt', 'r') as file:
# read a list of lines into data
data = file.readlines()
print(data)
print("Your name: " + data[0])
x = "0"
# now change the 2nd line, note that you have to add a newline
data[1] = x + "\n"
# and write everything back
with open('stats.txt', 'w') as file:
file.writelines(data)
My program:
question_answered = 0 # sets number of questions answered to zero
lineq = 6 # sets the number of lines to output from questions.txt
linea = 0 # sets the number of linea to read from answers.txt
with open("questions.txt", "r") as q:
with open("answers.txt", "r") as a:
answer_lines = a.readlines()
while question_answered != 3:
question_answered += 1
for i in range(lineq):
line2 = (q.readline())
print(line2)
response = input("answer:")
if response not in answer_lines[linea]:
print("incorrect")
mastery = (update_mastery[linea])
mastery = int(mastery)
if mastery < 1:
print("mastery", mastery)
else:
mastery -= 1
print("mastery", mastery)
else:
print("correct")
with open("mastery.txt", "r") as m:
update_mastery = m.readlines()
mastery = update_mastery[linea]
mastery = int(mastery) + 1
mastery = str(mastery)
update_mastery[linea] = mastery + "\n"
with open('mastery.txt', 'w') as m:
m.writelines(update_mastery[linea])
linea += 1
questions()
questions.txt:
1)Define isotope
[A]Atoms of the same element with same number of protons and a different number of neutrons
[B]Atoms of the different element with same number of protons and a different number of neutrons
[C]Atoms of the same element with same number of neutrons and a different number of protons
[D]Atoms of the same element with same number of protons and a different number of electrons
2)Name the type of decay that occurs when, they have too many neutrons
[A]Gamma Radiation
[B]Alpha Decay
[C]Beta Plus Decay
[D]Beta Minus Decay
3)Define Coulomb
[A]1 coulomb is the quantity of charge carried past a given point if a steady current of 1 amp flows for 1 second
[B]1 coulomb is the quantity of charge carried past a given point if a steady voltage of 1 volts per 1 second
[C]1 coulomb is the quantity of current carried past a given point if a steady voltage of 1 volts per 1 second
[D]1 coulomb is the rate of flow of charge
answers.txt:
A
D
A
mastery.txt:
0
0
0
I believe it would be easier to keep track of the the mastery level using a dictionary stored in a pickle. It makes it very easy to handle program's state and is much faster to modify.
For a quick answer, I would load the pickle like this:
"""
We are loading the pickled mastery values by checking if the pickle file exists.
If it doesn't we define a default mastery level
"""
try:
with open("mastery.p", "rb") as mastery_file:
mastery = pickle.load(mastery_file)
except FileNotFoundError:
mastery = {
"1: Define isotope": 0,
"2: Name the type of decay that occurs when, they have too many neutrons": 0,
"3: Define Coulomb": 0,
}
You can then use mastery as a regular dictionary and modify the values accordingly. When you are done, you can save the mastery state in the pickle again:
def save():
with open("mastery.p", "wb") as m:
pickle.dump(mastery, m)
Now for the entire program:
import pickle
"""
Here we defining the quesions and choices in a dictionary, but you could
load them from a normal text file, json file, or a pickle.
The questions are the keys to choices.
"""
q_and_a = {
"1: Define isotope": [
"[A]Atoms of the same element with same number of protons and a different number of neutrons",
"[B]Atoms of the different element with same number of protons and a different number of neutrons",
"[C]Atoms of the same element with same number of neutrons and a different number of protons",
"[D]Atoms of the same element with same number of protons and a different number of electrons",
],
"2: Name the type of decay that occurs when, they have too many neutrons": [
"[A]Gamma Radiation",
"[B]Alpha Decay",
"[C]Beta Plus Decay",
"[D]Beta Minus Decay",
],
"3: Define Coulomb": [
"[A]1 coulomb is the quantity of charge carried past a given point if a steady current of 1 amp flows for 1 second",
"[B]1 coulomb is the quantity of charge carried past a given point if a steady voltage of 1 volts per 1 second",
"[C]1 coulomb is the quantity of current carried past a given point if a steady voltage of 1 volts per 1 second",
"[D]1 coulomb is the rate of flow of charge",
],
}
"""
The answers have been defined with the same scheme as the questions
Once again, you could load these from a file or add them as the last
item in the q_and_a and filter them out when giving the questions.
"""
answers = {
"1: Define isotope": "a",
"2: Name the type of decay that occurs when, they have too many neutrons": "b",
"3: Define Coulomb": "a",
}
"""
We are loading the pickled mastery values by checking if the pickle file exists.
If it doesn't we define a default mastery level
"""
try:
with open("mastery.p", "rb") as mastery_file:
mastery = pickle.load(mastery_file)
except FileNotFoundError:
mastery = {
"1: Define isotope": 0,
"2: Name the type of decay that occurs when, they have too many neutrons": 0,
"3: Define Coulomb": 0,
}
# Here, we are iterating over every question each session
def show_questions(q, choices):
print(f"{q}:") # Show the question
print("\n".join(choices)) # Show the choices
answer = input("You answer: ") # wait for answer
if answer.lower() != answers[q]: # convert to lowercase (to match answerkey)
print(f"wrong, answer is {answers[q]}")
mastery[q] -= 1
print(f"Your mastery decreased to {mastery[q]}\n")
return False
else:
print("Correct!")
mastery[q] += 1
print(f"Your mastery increased to {mastery[q]}\n")
return True
def save():
with open("mastery.p", "wb") as m:
pickle.dump(mastery, m)
def loop_all():
"""
Loops through all qustions once
"""
for q, choices in q_and_a.items():
show_questions(q, choices)
save()
def for_mastery(max_level=3):
"""
Loops through each question till mastery is reached
Mastery can be adjusted by passing it as an argument
"""
for q, m in mastery.items():
print(m)
choices = q_and_a[q]
while m < max_level:
passed = show_questions(q, choices)
if passed:
m += 1
else:
m -= 1
save()
print("mastered!\n")
for_mastery()
A simple program for adding increasing a binary number by one, converting it to hexadecimal and the chr() equivalent starts to make a weird buzzing noise through the headphone jack with each loop. Sort of like a tapping noise I guess
Here is the code I wrote in Python 3:
mem = '0000000000000000000000000000000000000000000000000000000000100000' # Starts at 32
def incbin():
global mem
membin = int(mem.replace('b', ''), 2)
membin += 1
membinfin = bin(membin)
mem = membinfin[2:]
while True:
print('')
incbin()
for x in range(int(len(mem)/8)):
print(hex(int(mem[x:x+8], 2))[2:].zfill(2), end = ' ')
for x in range(int(len(mem)/8)):
print(chr(int(mem[x:x+8], 2)), end = ' ')
I should also mention that the Windows error sound keeps playing for a split second every now and then but no error appearing.
Here is an example of the console output:
dc b8 Ü ¸ as you can see, the first 2 sets of characters are the hexadecimal representation and the second set is the chr() equivalent.
Could this be a hardware issue? I'm using a Lenovo Yoga 11e with 4GB of RAM and an Intel Core i3 2.3GHz
I don't know why this is happening. I just want to find out why it's happening. I should also say that the fans kick on to the maximum. Which is strange because I can run somewhat graphical intensive games with the fans still quiet.
It looks like you could be printing the audible bell character. Do you get the same noise when you do something like print chr(7)? How does that compare to the result of print chr(7) * 100?
Try this code:
mem = '00100000'
def incbin():
global mem
membin = int(mem.replace('b', ''), 2)
membin += 1
membinfin = bin(membin)
mem = membinfin[2:]
def tryChr(number):
try:
return f" {chr(number)}"
except:
return " N/A"
def formatOne(number):
h = ( "00" + hex(number)[2:] )[-4:] # fits with 2**15 max
return " ".join( (h[i:i+2] for i in range(0,len(h),2)) ) + tryChr(number)
l = []
for c in range(32,2**15): # 2**16 gives error - check yourself why
l.append( formatOne(c) )
print(" ".join( ( l)))
It only prints once and stores stuff inlists in between - no endless loop. It should be easier on your hardware and might minimize your problem.
Hello I'm a new face to json and I want to ask something about it, anyway here's my code:
for key in result1date.keys():
key = sorted(result1date.keys())
currentdate = key
print currentdate
result1 = firebase.get('/Rooms/Room1/' + currentdate + '/Inspection/Scan-in/Inspector/', None)
result2 = firebase.get('/Rooms/Room1/' + currentdate + '/Inspection/Scan-out/Inspector/', None)
print result1
print currentdate
for key in result1.keys():
inspector = key
timeout = result2[inspector]["Time"]
# for key in result1date.keys():
# Date = key
result1datetime = firebase.get('/Rooms/Room1/'+ currentdate +'/Inspection/Scan-in/Inspector/'+ inspector +'/', None)
for key in result1datetime.keys():
key = sorted(result1datetime.keys())[-2]
time = key
print time
print time
ch1 = result1datetime[time]["Checklist"]["Entrance louver clean and dust-free"]
# ch2 = result1datetime[time]["Checklist"]["Room plate number – clean and well-polished"]
ch3 = result1datetime[time]["Checklist"]["Appearance door surface- in good condition"]
# ch4 = result1datetime[time]["Checklist"]["Let the door close by itself to test the door closure – in working order"]
ch5 = result1datetime[time]["Checklist"]["Eye viewer and fire escape plan in order"]
ch6 = result1datetime[time]["Checklist"]["Privacy Sign or Make Up Room Sign"]
# ch7 = result1datetime[time]["Checklist"]["Key card holder – in working order"]
ch8 = result1datetime[time]["Checklist"]["Switches at the entrance working correctly"]
#CLOSET
#ch9 = result1datetime[time]["Checklist"]["Let the door close by itself to test the door closure – in working order"]
RESERVED FOR DOOR IN WORKING CONDITION
ch10 = result1datetime[time]["Checklist"]["Lights in working order"]
# items below are sufficient
ch11 = result1datetime[time]["Checklist"]["6 Hangers?"]
ch12 = result1datetime[time]["Checklist"]["2 bathrobes?"]
ch13 = result1datetime[time]["Checklist"]["2 pairs of slippers?"]
ch14 = result1datetime[time]["Checklist"]["1 set of iron and board?"]
ch15 = result1datetime[time]["Checklist"]["Elsafe open or working?"]
ch16 = result1datetime[time]["Checklist"]["1 set of laundry list and bag?"]
ch17 = result1datetime[time]["Checklist"]["1 extra pillow with pillow cover?"]
#ch18 = result1datetime[time]["Checklist"]["Luggage bench fabric top is clean"]#DINING DRESS CODE
#ch19 = result1datetime[time]["Checklist"]["Luggage bench fabric top is clean"] #FLASHLIGHT
#LUGGAGE AND LUNCH BREAK
ch20 = result1datetime[time]["Checklist"]["Luggage bench fabric top is clean"]
# ch21 = result1datetime[time]["Checklist"]["Drawers – clean and dust-free"]
#MINIBAR
#ch22 = result1datetime[time]["Checklist"]["Luggage bench fabric top is clean"]#Arrangement of the items is neat & clean.
#ch23 = result1datetime[time]["Checklist"]["Luggage bench fabric top is clean"]#Ensure the items below are sufficient
ch24 = result1datetime[time]["Checklist"]["2 coke, 2 sprite, 1 C2 lemon, 1 C2 apple, 1 pineapple juice, 1 orange juice, 1 mineral water, 2 San Mig light, 2 pale pilsen?"]
ch25 = result1datetime[time]["Checklist"]["1 pringles, 1 cashew nut, 1 cup noodles (placed in the coffee tray on the writing desk)?"]
ch26 = result1datetime[time]["Checklist"]["Fridge is cold and clean"]
I have three dates. 'currentdate' so i looped all over them hoping to get the same output but three of them with different dates. Here's my firebase structure:
(https://i.stack.imgur.com/DfYSP.png)
But I'm only getting one. when I looped all keys using this part of the code
for key in result1date.keys():
key = sorted(result1date.keys())
the ones below should have followed it. Any help is appreciated. I want to know why is this happening and hopefully a solution or a suggestion.
I want to get an output of something like this:
[DATE 1 HERE with all the details within its branches]
[DATE 2 HERE with all the details within its branches]
[Date 3 HERE with all the details within its branches]
This looks wrong:
for key in result1datetime.keys():
key = sorted(result1datetime.keys())[-2]
time = key
print time
You're iterating through your keys in the for loop, but then you always get the same key in the next line (sorted(result1datetime.keys())[-2]).
Why did you add that line in the first place? This way, you're always getting the middle key (out of three).
Perhaps you wanted to sort the returned key instead (key = sorted(key)[-2]). Your structure image does not show deep enough to know what to expect in that level.
In any case, I'd recommend you not to reuse the key variable inside the loop like that. It will make things hard to understand. And note that the problem is resetting it for a fixed element of the same iterable you were looping on in the first place.
I'm not that familiar with python or json so this might not work in your case but did my best building this, hope it can be of some help
If the Json file has a fixed stable structure or if the values are even quite similarly formatted, I was thinking you could do this:
Json sample as dict:
firebase_json = {
"Rooms": {
"Room1": {
"2017-11-29": {
"Status": ["unoccupied"],
"Inspection": ["yes"],
"Scan-in": ["no"],
"Scan-out": ["yes"]
},
"2017-12-05": {
"Status": ["occupied"],
"Inspection": ["no"],
"Scan-in": ["yes"],
"Scan-out": ["no"]
},
},
"Room2": {
"2017-11-02": {
"Status": ["unoccupied"],
"Inspection": ["yes"],
"Scan-in": ["no"],
"Scan-out": ["yes"]
},
"2017-12-01": {
"Status": ["occupied"],
"Inspection": ["no"],
"Scan-in": ["yes"],
"Scan-out": ["no"]
}
}
}}
sample selections
room = input("Room?",)
for a in firebase_json:
for b in firebase_json[a]:
if b != room: #select by given room.
continue
print(b)
for c in firebase_json[a][b]:
print(" ", c) # if selection by date add previous != statement here
for d in firebase_json[a][b][c]:
for e in firebase_json[a][b][c][d]:
print(" ", d, ":", e)
There is possibly a better way of doing this but as I said.
i am new to pythin and trying to work out an if statement for some data being collected.
import grovepi
import time
import datetime
import grovelcd
#headerline
print ("Time,Noise (db),Light (lux),Temperature (C),Humidity (rH)")
here i have the already existing header lines for when they are printed into a csv file.I want another displaying the information i outline below.
while True:
timestamp=time.time()
#read from a analog sensor on input 1
d= grovepi.analogRead(1)
#read from an analog sensor on input 2
a= grovepi.analogRead(2)
#read from an digital sensor on input 3
(t,h)=grovepi.dht(3,0)
above is the reading of each sensor
print ("%f,%d,%d,%f,%f"%(timestamp,d,a,t,h))
What i would like is an additional value, i am having issues getting an if statement to take the value and determine if it matches what i want. All these should be number values.
the idea i have is
if t > 35:
print("Warning")
if h > 50:
print("Warning")
if n > 75:
print("Warning")
else:
print("OK")
Essentially what i have looks like this output:
Noise Light Temperature Humidity
85 500 34 76
What im trying to achieve is this:
Noise Light Temperature Humidity Note
85 500 34 76 OK
Any help appreciated, i dont know python very well unfortunately.
If you want to print an extra column, like "1234567890,34.3,51.2,70.3,Warning" then you can do it with a simple boolean variable, like this:
while True:
...
warning = t > 35 or h > 50 or n > 75
print ("%f,%d,%d,%f,%f,%s" % (
timestamp, d, a, t, h, "Warning" if warning else "OK"
))
Above, I've defined warning as a boolean condition, and used if for the inline if operator to print either "Warning" or "OK".
If you need extra flexibility you can assign to a string variable:
while True:
...
# Note, only message for the first matching condition would display
if t > 35:
message = "Warning: T"
elif h > 50:
message = "Warning: H"
elif n > 75:
message = "Warning: N"
else:
message = "OK"
print ("%f,%d,%d,%f,%f,%s" % (timestamp, d, a, t, h, message))
And if you need to display multiple messages, you can collect a list, like this:
while True:
...
warnings = []
if t > 35:
warnings.append("WarnT")
if h > 50:
warnings.append("WarnH")
...
status = " ".join(warnings) if warnings else "OK"
print ("%f,%d,%d,%f,%f,%s" % (timestamp, d, a, t, h, status))
This would collect all warnings in a list (so it would be like ["WarnT", "WarnH"]), then if the list is not empty join with spaces (" ".join(warnings)) so it'll be "WarnT WarnH", and otherwise use "OK" as the message. Tune the output as you feel appropriate.
Hope this helps.
(BTW, you may consider using something like %0.2f instead of %f if you want a fixed number of digits. I believe you'd probably want to round to a sane precision, e.g. "59.03" instead of something like "59.031045032")
The code im trying to create is to print a wavelength such as radio waves or microwaves based on the wavelength value input.
userInput = input("Enter wavelength (m) value: ")
waveValue= float(userInput)
if waveValue > 10**-1 :
print("Radio Waves")
elif waveValue < 10**-3 :
print("Microwaves")
elif waveValue < 7*10**-7 :
print("Infared")
elif waveValue <4-10**-7 :
print(" Visible light")
elif waveValue <10**-8 :
print( "Ultraviolet")
elif waveValue <10**-11 :
print( "X-rays")
elif waveValue >10**-11 :
print("Gamma rays")
else :
print()
Any hints on how I can get the second if statement to work. Every input I put in just outputs radio waves because my arguments does not work properly.
Also there is 5 more inputs that I will have to use elif commands for.
Are you trying to use powers of 10 here? Because the convention for "10 to the minus 1" for example, is 1.0e-1. What you have in your code translates to "10 times -1" or -10, which I don't think you intended.
I would rewrite as:
if waveValue > 1.0e-1:
print("Radio Waves")
elif (waveValue > 1.0e-3) and (waveValue < 1.0e-1):
print("Micro Waves")
as a prior answer pointed out, it is also more efficient to order the answers so that one side of the comparison is not needed (those values have already been accounted for by earlier tests).
for example:
if waveValue < 1.0e-3:
<not in current code>
elif waveValue < 1.0e-1:
print("Micro Waves")
else:
print("Radio Waves")
Nothing wrong with your approach for a small number of "break values". For a large number of "break values" you are better off to create a table with the break values and the corresponding action.
i.e., in your case, a table with wavelength and classification. First row containing 10e-1 and "Radio Waves", 2nd row containing 10e-3 and "Microwaves"
In code, you just loop though the until until you find the correct row for waveValue.
This is common in Tax Tables. As a bonus, you can store your tax tables in an external database instead of hard-coding the values in your program.
I think your second statement is wrong.
It says waveValue >10*-1<10*-3 which I think is >-10 and < -30 and if what I say is correct then there can't be numbers bigger than -10 that are smaller than -30
A list of tuples could work quite well here:
wave_categories = []
# Load up your data of definitions
wave_categories.append((1e-3, 'Microwaves'))
wave_categories.append((1e-2, 'Somewaves'))
wave_categories.append((1e-1, 'Radiowaves'))
wave_categories.append((1, 'Ultrawaves'))
Then your detection becomes a loop:
def find_wave(wavelength):
for category_wavelength, name in wave_categories:
if wavelength < category_wavelength:
return name
raise Exception('Wavelength {} not detected in list'.format(wavelength))
To make it work for lots and lots of categories, just add more data to wave_categories.
You can use the bisect module for this:
from bisect import bisect
freqs = [10**-11, 10**-8, 4*10**-7, 7*10**-7, 10**-3, 10**-1]
names = ['Gamma rays', 'X-rays', 'Ultraviolet', 'Visible light',
'Infared', 'Microwaves', 'Radio Waves']
>>> names[bisect(freqs, 10**-2)]
'Radio Waves'
>>> names[bisect(freqs, 10**-4)]
'Microwaves'