Lines in text file won't iterate through for loop Python - python

I am trying to iterate through my questions and lines in my .txt file. Now this question may have been asked before, but I am really having trouble with this.
this is what I have right now:
from transformers import AutoTokenizer, AutoModelForQuestionAnswering
import torch
max_seq_length = 512
tokenizer = AutoTokenizer.from_pretrained("henryk/bert-base-multilingual-cased-finetuned-dutch-squad2")
model = AutoModelForQuestionAnswering.from_pretrained("henryk/bert-base-multilingual-cased-finetuned-dutch-squad2")
f = open("glad.txt", "r")
questions = [
"Welke soorten gladiatoren waren er?",
"Wat is een provocator?",
"Wat voor helm droeg een retiarius?",
]
for question in questions:
print(f"Question: {question}")
for _ in range(len(question)):
for line in f:
text = str(line.split("."))
inputs = tokenizer.encode_plus(question,
text,
add_special_tokens=True,
max_length=100,
truncation=True,
return_tensors="pt")
input_ids = inputs["input_ids"].tolist()[0]
text_tokens = tokenizer.convert_ids_to_tokens(input_ids)
answer_start_scores, answer_end_scores = model(**inputs, return_dict=False)
answer_start = torch.argmax(
answer_start_scores
) # Get the most likely beginning of answer with the argmax of the score
answer_end = torch.argmax(
answer_end_scores) + 1 # Get the most likely end of answer with the argmax of the score
answer = tokenizer.convert_tokens_to_string(
tokenizer.convert_ids_to_tokens(input_ids[answer_start:answer_end]))
print(text)
# if answer == '[CLS]':
# continue
# elif answer == '':
# continue
# else:
# print(f"Answer: {answer}")
# print(f"Answer start: {answer_start}")
# print(f"Answer end: {answer_end}")
# break
and this is the output:
> Question: Welke soorten gladiatoren waren er?
> ['Er waren vele soorten gladiatoren, maar het meest kwamen de thraex, de retiarius en de murmillo voor', ' De oudste soorten gladiatoren droegen de naam van een volk: de Samniet en de Galliër', '\n']
> ['Hun uitrusting bestond uit dezelfde wapens als die waarmee de Samnieten en Galliërs in hun oorlogen met de Romeinen gewoonlijk vochten', '\n']
> ['De Thraciër (thraex) verscheen vanaf de tweede eeuw voor Chr', ' Hij had een vrij klein kromzwaard (sica), een klein rond (soms vierkant) schild, een helm en lage beenplaten', " De retiarius ('netvechter') had een groot net (rete) met een doorsnee van 3 m, een drietand en soms ook een dolk", '\n']
> ['Hij had alleen bescherming om zijn linkerarm en -schouder', ' Vaak droeg hij ook een bronzen beschermingsplaat (galerus) van zijn nek tot linkerelleboog', ' Vaak vocht de retiarius tegen de secutor die om die reden ook wel contraretiarius werd genoemd', '\n']
> ['Hij had een langwerpig schild en een steekzwaard', ' Opvallend was zijn eivormige helm zonder rand en met een metalen kam, waarschijnlijk zo ontworpen om minder makkelijk in het net van de retiarius vast te haken', ' Een provocator (‘uitdager’) vocht doorgaans tegen een andere provocator', '\n']
> ['Hij viel zijn tegenstander uit een onverwachte hoek plotseling aan', ' Hij had een lang rechthoekig schild, een borstpantser, een beenplaat alleen over het linkerbeen, een helm en een kort zwaard', '']
> Question: Wat is een provocator?
> Question: Wat voor helm droeg een retiarius?
But the sentences are supposed to repeat in the other questions too.
Does anyone know what I am doing wrong here? It is probably something really easy, but I really don't seem the find the mistake.

You would need to add f.seek(0) after your first parse through the file. This is because when you read the file once, the cursor is at the end of the file, after which for line in f does not read the file from the beginning again. Please refer to Tim and Nunser's answer here which explains it well.
Something like this:
from transformers import AutoTokenizer, AutoModelForQuestionAnswering
import torch
max_seq_length = 512
tokenizer = AutoTokenizer.from_pretrained("henryk/bert-base-multilingual-cased-finetuned-dutch-squad2")
model = AutoModelForQuestionAnswering.from_pretrained("henryk/bert-base-multilingual-cased-finetuned-dutch-squad2")
f = open("glad.txt", "r")
questions = [
"Welke soorten gladiatoren waren er?",
"Wat is een provocator?",
"Wat voor helm droeg een retiarius?",
]
for question in questions:
print(f"Question: {question}")
for _ in range(len(question)):
for line in f:
text = str(line.split("."))
inputs = tokenizer.encode_plus(question,
text,
add_special_tokens=True,
max_length=100,
truncation=True,
return_tensors="pt")
input_ids = inputs["input_ids"].tolist()[0]
text_tokens = tokenizer.convert_ids_to_tokens(input_ids)
answer_start_scores, answer_end_scores = model(**inputs, return_dict=False)
answer_start = torch.argmax(
answer_start_scores
) # Get the most likely beginning of answer with the argmax of the score
answer_end = torch.argmax(
answer_end_scores) + 1 # Get the most likely end of answer with the argmax of the score
answer = tokenizer.convert_tokens_to_string(
tokenizer.convert_ids_to_tokens(input_ids[answer_start:answer_end]))
print(text)
f.seek(0) # reset cursor to beginning of the file

Your f is just an open file which is exhausted the first time through. I think you meant this:
f = list(open("glad.txt", "r"))

Related

How to build this regex so that it extracts a word that starts with a capital letter if only if it appears after a previous pattern?

I need a regex that extracts all the names (we will consider that they are all the words that start with a capital letter and respect having certain conditions prior to their appearance within the sentence) that are in a sentence. This must be done respecting the pattern that I clarify below, also extracting the content before and after this name, so that it can be printed next to the name that was extracted within that sequence or pattern.
This is the pseudo-regex pattern that I need:
the beginning of the input sentence or (,|;|.|y)
associated_sense_1: "some character string (alphanumeric)" or "nothing"
(con |juntos a |junto a |en compania de )
identified_person: "some word that starts with a capital letter (the name that I must extract)" and it ends when the regex find one or more space
associated_sense_2: "some character string (alphanumeric)" or "nothing"
the end o the input sentence or (,|;|.|y |con |juntos a |junto a |en compania de )
the (,|;|.|y) are just person connectors that are used to build a regex pattern, but they do not provide information beyond indicating the sequence of belonging, then they can be eliminated with a .replace( , "")
And with this regex I need extract this 3 string groups
associated_sense_1
identified_person
associated_sense_2
associated_sense = associated_sense_1 + " " + associated_sense_2
This is the proto-code:
import re
#Example 1
sense = "puede ser peligroso ir solas, quizas sea mejor ir con Adrian y seguro que luego podemos esperar por Melisa, Marcos y Lucy en la parada"
#Example 2
#sense = "Adrian ya esta en la parada; y alli probablemente esten Lucy y May en la parada esperandonos"
person_identify_pattern = r"\s*(con |por |, y |, |,y |y )\s*[A-Z][^A-Z]*"
#person_identify_pattern = r"\s*(con |por |, y |, |,y |y )\s*[^A-Z]*"
for identified_person in re.split(person_identify_pattern, sense):
identified_person = identified_person.strip()
if identified_person:
try:
print(f"Write '{associated_sense}' to {identified_person}.txt")
except:
associated_sense = identified_person
The wrong output I get...
Write 'puede ser peligroso ir solas, quizas sea mejor ir' to con.txt
Write 'puede ser peligroso ir solas, quizas sea mejor ir' to Melisa.txt
Write 'puede ser peligroso ir solas, quizas sea mejor ir' to ,.txt
Write 'puede ser peligroso ir solas, quizas sea mejor ir' to Lucy en la parada.txt
Correct output for example 1:
Write 'quizas sea mejor ir con' to Adrian.txt
Write 'y seguro que luego podemos esperar por en la parada' to Melisa.txt
Write 'y seguro que luego podemos esperar por en la parada' to Marcos.txt
Write 'y seguro que luego podemos esperar por en la parada' to Lucy.txt
Correct output for example 2:
Write 'ya esta en la parada' to Adrian.txt
Write 'alli probablemente esten en la parada esperandonos' to Lucy.txt
Write 'alli probablemente esten en la parada esperandonos' to May.txt
I was trying with this other regex but I still have problems with this code:
import re
sense = "puede ser peligroso ir solas, quizas sea mejor ir con Adrian y seguro que luego podemos esperar por Melisa, Marcos y Lucy en la parada"
person_identify_pattern = r"\s*(?:,|;|.|y |con |juntos a |junto a |en compania de |)\s*((?:\w\s*)+)\s*(?<=con|por|a, | y )\s*([A-Z].*?\b)\s*((?:\w\s*)+)\s*(?:,|;|.|y |con |juntos a |junto a |en compania de )\s*"
for m in re.split(person_identify_pattern, sense):
m = m.strip()
if m:
try:
print(f"Write '{content}' to {m}.txt")
except:
content = m
But I keep getting this wrong output
Write 'puede ser peligroso ir solas' to quizas sea mejor ir con Adrian y seguro que luego podemos esperar por.txt
Write 'puede ser peligroso ir solas' to Melisa,.txt
Write 'puede ser peligroso ir solas' to Marcos y Lucy en la parad.txt
import re
sense = "puede ser peligroso ir solas, quizas sea mejor ir con Adrian y seguro que luego podemos esperar por Melisa, Marcos y Lucy en la parada"
if match := re.findall(r"(?<=con|por|a, | y )\s*([A-Z].*?\b)", sense):
print(match)
it result = ['Adrian', 'Melisa', 'Marcos', 'Lucy']

Make auto random phrases in same time

I need help to make lot of random text to send on twitter but its too long copy paste any one know how i can duplicate (rdmlol == 0): to 500 Thank
Code
if(rdmlol == 0):
api.update_status(status = 'coucou les toxic de ma tl feur ' + str(TweetCount) + ' je ne suis pas un robot lol allez voir feur ')
elif(rdmlol == 1):
api.update_status(status = 'coucou les pierre de ma tl feur ' + str(TweetCount) + ' je ne suis pas un robot lol allez voir feur')```
You're probably looking for a for-loop over a range?
for _ in range(500):
msg = "coucou les toxic de ma tl feur " + str(TweetCount) + " je ne suis pas un robot lol allez voir feur"
api.update_status(status = msg)
If you need to construct a different message each time, the solution depends on what exactly do you need, e.g.
import random
def create_message(tweet_count, words):
# f-strings were introduced in Python 3.6
return f"coucou les {random.choice(words)} de ma tl feur {tweet_count} je ne suis pas un robot lol allez voir feur"
def update_status(api):
words = ["toxic", "pierre"]
for i in range(500):
msg = create_message(i+1, words)
api.update_status(status = msg)
I hope this helps.

Python Tokenizer, sentence gets cut off at newline character

I am trying to build a tokenizer with python, I think it is going on pretty well but there is one problem that I cannot seem to solve. I'll try to be as elaborative as possible:
This is the text I am trying to tokenize (txt.gz file):
"Het Franse danceduo Daft Punk hangt hun kenmerkende helmen aan de wilgen .
De dance-act stopt er na 28 jaar mee .
In een bijna acht minuten durende video kondigde het tweetal het afscheid aan .
Een woordvoerder heeft het nieuws aan entertainmentblad Variety bevestigd , maar wilde verder niet uitweiden over de reden van het stoppen .
In de video die vanochtend online kwam zijn Thomas Bangalter en Guy-Manuel de Homem-Christo met hun helmen te zien .
In de bijna dertig jaar dat ze actief waren , hebben ze lange tijd hun identiteit geheim weten te houden .
De twee staan tegenover elkaar en lopen vervolgens uit elkaar terwijl een onheilspellende wind klinkt .
And this is the output I am getting:
" Het Franse danceduo Daft Punk hangt hun kenmerkende helmen aan de wilgen .
dance-act stopt er na 28 jaar mee .
kondigde het tweetal het afscheid aan .
reden van het stoppen .
Homem-Christo met hun helmen te zien .
waren , hebben ze lange tijd hun identiteit geheim weten te houden .
onheilspellende wind klinkt "
This is my code:
import sys
import re
import gzip
def tokenizer(data):
tokens = re.compile('[^ ].*?[.!?]')
list_of_tokens = tokens.findall(data)
print(list_of_tokens)
string_token = ""
string_token = string_token.join(list_of_tokens)
string_token = re.sub('([.,!?()])', r' \1 ', string_token)
return string_token
def main(argv):
with gzip.open(argv[1], 'rt') as f:
data = f.read()
print(tokenizer(data))
if __name__ == '__main__':
main(sys.argv)

How to define a sentence as ,Starting with "uppercase letter" end ending with ".", in a txt file

I'm working on a python script that asks what word you want to find.
It searches for that word in (for example) word.txt file and prints it, including the line + line number.
Since my word.txt file contains paragraphs, the "line" is misinterpreted.
Grammatically, a line means "Starting with" capital letter "and ending with". "Or the like.
But in my script, a sentence (line) ends at the end of the aliena.
I have been googling for " variable containing string that begins with "uppercase" and ending with "." and more without a result.
Down here is my code and below that, the file (a news article) I am using.
fh =open("name.txt","r")
word=input("Enter the word to search:")
s=". "
count=1
while(s):
s=fh.readline()
L=s.split()
if word in L:
print("Line Number:",count,":",s)
count+=1
(name.txt)
Het gaat "heel moeilijk" worden om de verspreiding van de nieuwe variant van het coronavirus tegen te gaan, zei de Britse minister van Volksgezondheid Matt Hancock zondagochtend. "We hebben nog een lange weg te gaan." De gemuteerde versie van het virus is waarschijnlijk een stuk besmettelijker dan eerdere varianten.
Inwoners van Londen en andere gebieden waar vanwege de nieuwe variant strengere lockdowns zijn afgekondigd, moeten zich gedragen alsof ze besmet zijn, zegt Hancock. Dat betekent dat ze moeten thuisblijven, tenzij het echt niet anders kan.
21 miljoen inwoners van Londen en een deel van het oosten en zuidoosten van Engeland mogen elkaar niet meer bezoeken. Voor Kerstmis worden geen uitzonderingen gemaakt.
Niet-essentiële winkels zijn dicht en mensen moeten zoveel mogelijk thuisblijven. Voor werk, studie, buitensport of begrafenissen met maximaal dertig aanwezigen mogen inwoners wel de deur uit.
Mutatie op 9 december goed voor 62 procent van nieuwe gevallen
De nieuwe variant van het coronavirus heeft zich al volop verspreid in Londen en het oosten van Engeland. Het Britse statistiekbureau ONS heeft berekend dat deze mutatie op 9 december al goed was voor 62 procent van alle nieuwe coronabesmettingen in de Britse hoofdstad. In Oost-Engeland werd op die datum in 59 procent van de gevallen het gemuteerde coronavirus vastgesteld.
Uit de cijfers blijkt hoe snel de gemuteerde versie van het virus om zich heen grijpt. Op 18 november maakte deze variant, die in september in Engeland opdook, nog slechts 28 procent van de geconstateerde gevallen in Londen uit.
Het vaccineren van de bevolking is volgens de Britse minister nu des te belangrijker. Het Verenigd Koninkrijk verwacht dat aan het einde van dit weekend ongeveer een half miljoen mensen zijn gevaccineerd.
Nieuwe variant verspreidt zich mogelijk sneller
De ontdekking van de nieuwe stam in Nederland is in de nacht van zaterdag op zondag bekendgemaakt. Op basis van een eerste analyse constateerde een speciale adviesgroep dat deze variant zich mogelijk sneller verspreidt dan eerdere varianten.
Virussen muteren voortdurend. Ze overleven door zich aan te passen aan een andere omgeving. De meeste mutaties van het coronavirus zijn ongevaarlijk.
De nieuwe stam, een variant van SARS-CoV-2 met de wetenschappelijke naam VUI-202012/01, is in september ontdekt. De mutatie is vooral aangetroffen in het zuidoosten van Engeland, maar is ook in Wales vastgesteld. Verder zijn drie gevallen in Denemarken en een in Australië bekend.
Geen duidelijke signalen dat nieuwe veriant gevaarlijker is
"De nieuwe variant is mogelijk 70 procent besmettelijker dan de originele variant van het virus", zei de Britse premier Boris Johnson zaterdag tijdens een persconferentie. Nader onderzoek moet meer duidelijkheid verschaffen.
Er zijn geen duidelijke signalen dat de nieuwe variant ook gevaarlijker is. De kans op een ziekenhuisopname of overlijden is te vergelijken met de kans daarop bij de oorspronkelijke variant van het virus. Ook wijst niets erop dat coronavaccins minder effectief werken tegen de nieuwe variant van het virus.
This should work.
filename = "name.txt"
word = input("Enter the word to search:")
with open(filename, "r") as f:
for i, line in enumerate(f):
new_word = " " + word.lower() + " " # lowercase word with leading and trailing spaces
new_line = " " + line.rstrip("\n").replace(".", "").lower() + " " # lowercase line with leading and trailing spaces, without dot
if new_word in new_line:
print("Line Number:", i, ":", line)

Comparing data from sensors in arrays before writing a Csv file doesn't work, Raspberry Pi

I'm writing a datalogging program for my Raspberry Pi which is going pretty well. But before writing a new line in a csv file i want to check if the data is different to make sure i don't write the same data twice.
The problem is, i use an array to store the new data, and an array to store the old data. when they are different the code will write a new line in the CSV file and make the old and the new data the same, then new data will change again. But for some reason the old != new is not working in finding if the data is changed.
I tried using more global variables and no local variables. I tried using the Values Array (all sensors data, also a lot of 0) in stead of the Info Array (active sensor data). I thought it might be a pointer issue but i don't think Python uses pointers.
When i write the line "old = new" in the if new != old: loop. (see code)
it only goes trough once and stops.
The thing that really bums me out is that when i change the sensor values and i use CTRL + C to interrups. it seems like old and new are ALWAYS the same. but they have updated to the new values.
I tried to debugg the code but the Pi and Thonny both freeze when i get to the libraries.
######################Variables#######################
AnalogSensor = [False, True, False, False, False, True, True, True] #8 analog inputs
AnalogSensorDelay = [1, 1, 1, 1, 1, 0.4, 2, 0.8] #the timing to read all of these inputs.
LoggingDelay = 1 #the timing to write the Csv file
# DHT = 17 #not yet connected
Decimalen = 0 #the amount of decimals after the decimal dot (1 means only logging 100th of seconds, 2 means 10th of a second. etc.)
###############Libraries##################
import time
import csv
from datetime import date
import datetime
import os.path
import Adafruit_GPIO.SPI as SPI
import Adafruit_MCP3008
###############Initial values of variables#############
name = "/media/pi/DIRK\040PI/" + str(date.today()) + ".0.csv" #this will write a file to this path (USB stick in the pi) with the name 2019-09-25.0.csv
old = 1
new = 0
SPI_PORT = 0
SPI_DEVICE = 0
starttime = time.time()
Sensortimer = [0]*8
values = [0]*8
Loggingtimer = 0
dataArray = [0]
###############Setup###################################
if Decimalen == 0:
Decimalen = -1 #gets rid of the decimal dot of there are no decimals.
mcp = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE))
data = [0]*(AnalogSensor.count(True)) #creates an array with the size of the amount of inputs put on True
def Filename(name): #this function changes the '2019-09-25.0.csv' name and changes the .0 to .1 .2 etc if the file already exists.
x = 0
while os.path.isfile(name): #checks if the file exists.
print("There was already a file named",name)
x = x + 1 #increase file number
name = "/media/pi/DIRK\040PI/" + str(date.today()) + "." + str(x) + ".csv"
print("Creating file ", name)
return name
def Writecsv(name, delay, info): #writes a csv file with the name returned by the Filename function, with the delay chosen with LoggingDelay, and info is an array filled with active sensor data.
global Loggingtimer
global totaltime
global starttime
global old
global new
if (Loggingtimer + delay <= totaltime - starttime): #checks if delay time has passed ( this is to bypass the sleep function and to be able to do other things )
Loggingtimer = time.time() - starttime
new = info #changes new to an array with the same values as info ( an array with active sensor values )
if new != old: # if new data is different from old data
print(info) # prints data in the Shell for comfort.
write = str(datetime.datetime.now()) ##
write = write.split() ##
write[1] = write[1][:(9+Decimalen)] ##
data = [write[0],write[1]] ## Creates a timestamp with 2 values, the date, and the time with chosen decimals
for x in range((AnalogSensor.count(True))): ## Add the data from the info array to the timestamp array to create the LOG.
data.append(info[x]) ##
with open(name,'a',newline="") as f:
writer = csv.writer(f)
writer.writerow(data) # Write a row with the complete log
print("Writing to file")
----------------------------------------------------------------------
# old = new
----------------------------------------------------------------------
def Analogread(pin, delay): # This function reads the values of the MCP3008 and puts them in array Values, note. the array Values has the values of all 8 inputs, even if some inputs are disabled
global totaltime
global Sensortimer
global starttime
if (Sensortimer[pin] + delay <= totaltime - starttime):
Sensortimer[pin] = time.time() - starttime
values[pin] = mcp.read_adc(pin)
return values[pin]
name = Filename(name)
while True:
totaltime = time.time() # Keeps updating the time
y = 0
for counter in range(8): # Looks in the AnalogSensor array how many sensors are on True
if AnalogSensor[counter] == True:
Analogread(counter, AnalogSensorDelay[counter]) # Read the value of the inputs that are on True, ( the inputs on false will always be 0 )
data[y] = values[counter] # Puts the data from the active sensors in a different array with only active sensor data
y = y + 1
Writecsv(name, LoggingDelay, data)
i expect the output to be someting like:
There was already a file named /media/pi/DIRK PI/2019-09-25.0.csv
There was already a file named /media/pi/DIRK PI/2019-09-25.1.csv
There was already a file named /media/pi/DIRK PI/2019-09-25.2.csv
Creating file /media/pi/DIRK PI/2019-09-25.3.csv
[7, 0, 700, 254]
Writing to file
[4, 0, 702, 254]
Writing to file
[9, 0, 697, 356]
Writing to file
[3, 0, 707, 456]
Writing to file
[2, 0, 712, 677]
Writing to file
But after
[7, 0, 700, 254]
Writing to file
It just stops. No error. And keeps updating both Old and New data arrays which stay the same for some reason. Even though old can only be updated to the value of new after old and new are different and a new line is written in the csv file.
I think mistake is here, try that code:
def Analogread(pin, delay):
global totaltime
global Sensortimer
global starttime
if (Sensortimer[pin] + delay <= totaltime - starttime):
Sensortimer[pin] = time.time() - starttime
return mcp.read_adc(pin)
and change
Analogread(counter, AnalogSensorDelay[counter])
data[y] = values[counter]
to
data[y] = Analogread(counter, AnalogSensorDelay[counter])
So i am not completely sure where the problem was in the code above,
but after getting a lot more experience with python I started working with classes.
This is the second version of my datalogger code and this works perfectly :D.
import csv
from os.path import exists
import datetime
import RPi.GPIO as GPIO
from time import sleep
from random import randrange
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
class Logger:
path = '/home/pi/Documents/Namelogs/'
date = str(datetime.date.today())
fieldnames = ['date','time']
def __init__(self, name = 'datalog.0.csv'):
'''
Omschrijving
-------------------
Deze class beschikt over alle functies die te maken hebben met het loggen van data.
Variabelen
----------
path: 'string'
Het pad waar de csv file opgeslagen gaat worden.
date: 'string'
De datum wanneer het programma begint.
fieldnames: [list]
De extra waarden die in de datalog moeten staan(behalve de data), default = datum en tijd.
data: {dictionary}
Hierin staat alles wat gelogd moet worden, het is een dictonary opgebouwd uit 4 keys:
-Data : hierin komt alle nieuwe data te staan
-Old : hierin komt alle oude data te staan
-Date : hierin komt de huidige datum te staan
-Time : hierin komt de huidige tijd te staan
Parameters
----------
name : `string`
De naam van het bestand dat je wilt loggen, de standaard naam is datalog
Alle andere helper functies:
- log_data()
- collect_data()
- check_data()
- print_data()
- check_file()
- check_date()
'''
self.data = {}
self.name = name
self.data['data'] = 0
self.fileName = str(self.path + self.name + str(datetime.date.today()) + ".0.csv")
def collect_data(self):
'''
Deze functie verzamelt de data die gelogd moet worden, de data wordt opgeslagen onder "data"
wanneer nieuwe data gelogd wordt worden de waardes uit "data" verplaatst naar "old"
De oude data kan gebruikt worden door de volgende functie:
- check_data()
'''
self.data['old'] = self.data['data']
data_array = {}
for sensor in Sensor.sensorArray:
if sensor.state:
data_array[sensor.name] = sensor.read_data()
self.data['data'] = data_array
def log_data(self):
'''
Korte Omschrijving
------------------
Deze functie logt de huidige data uit de data dictionary in een csv bestand onder de naam gespecificeerd bij de class.
Uitgebreide Omschrijving
------------------------
Deze functie haalt de huidige datum en tijd op, en combineert dit met de data uit de data dictionary.
Deze combineert hij in een nieuwe dictionary en hij schrijft deze weg onder de juiste headers.
Deze headers zijn aangemaakt bij de create_file() functie.
'''
self.data['date'] = str(datetime.datetime.now().date())
self.data['time'] = str(datetime.datetime.now().time())
with open(self.fileName,'a',newline="") as f:
writer = csv.DictWriter(f, fieldnames = Logger.fieldnames)
writer.writerow({'date' :self.data['date'], 'time' : self.data['time'][:12], **self.data['data']})
def check_data(self, compare_data = True):
'''
Omschrijving
------------
Deze functie vergelijkt de data uit collect_data() met de oude data uit collect_data() en geeft op basis daarvan een waarde terug, zie Return.
Deze functie kan gecombineerd worden met de log_data() functie zodat alleen verschillende data gelogd wordt.
Voorbeeld
---------
if logger.check_data():
logger.log_data()
Parameters
----------
compare_data : Boolean (True of False, standaard = True)
Deze variabele bepaald of deze functie wel of niet uitgevoerd wordt.
Return
------
True / False: Boolean
Deze functie geeft False terug wanneer de data het zelfde is als de oude data.
In alle andere gevallen geeft deze functie True terug.
'''
if compare_data:
if self.data['data'] == self.data['old']:
print("Data not logged, since data == old data")
return False
else:
return True
return True
def print_data(self):
'''
Omschrijving
------------
Deze functie print de data die verzamelt is met de collect_data() functie op een nette en leesbare manier in de shell.
'''
print("-"*150)
print(self.data['data'])
print("-"*150)
def create_file(self):
'''
Korte omschrijving
-------------------
Deze functie maakt het bestand met de gekoze naam aan en schrijft een header.
Belangrijk! - Dit is altijd de eerste functie die aangeroepen wordt.
Uitgebreide omschrijfing
-------------------------
Deze functie kijkt of er al een bestand is met de gekozen naam. ("gekozen naam"_"datum".0.csv)
Als dit bestand al bestaat gaat de functie het getal in de naam aanpassen totdat er een bestandsnaam gevonden is die wel beschikbaar is.
Zodra deze gevonden is gaat de functie een header schrijver met de datum, de tijd en alle actieve sensoren.
Return
-------
self.fileName : 'Sting'
De complete naam van het log bestand
("gekozen naam"_"datum".x.csv)
'''
x = 0
self.fileName = self.path + self.name + "_{}.{}.csv".format(str(datetime.date.today()),x)
while exists(self.fileName):
x+=1
self.fileName = self.path + self.name + "_{}.{}.csv".format(str(datetime.date.today()),x)
with open(self.fileName,'a',newline="") as f:
writer = csv.DictWriter(f, fieldnames = Logger.fieldnames)
writer.writeheader()
return self.fileName
def check_date(self):
'''
Korte omschrijving
-------------------
Deze functie kijkt of het een nieuwe dag is, zo ja maakt hij een nieuw bestand.
Uitgebreide omschrijfing
-------------------------
Deze functie vergelijkt de datum wanneer het laatste bestand gemaakt is met de huidige datum,
als deze niet het zelfde zijn wordt de create_file() functie aangeroepen die een nieuw datalog bestand maakt, zie create_file().
waarna de datum wanneer het laatste bestand gemaakt is veranderdt wordt naar vandaag.
'''
dateNow = str(datetime.date.today())
if dateNow != self.date:
self.date = dateNow
self.create_file()
class Sensor(Logger):
sensorArray = []
def __init__(self, name, state, pin):
self.name = name
self.state = state
self.pin = pin
GPIO.setup(pin, GPIO.OUT)
GPIO.output(pin, state)
if self.state:
Logger.fieldnames.append(self.name)
Sensor.sensorArray.append(self)
def read_data(self):
if self.name == 'digital sensor 1':
data = randrange(2)
else:
data = randrange(3)*randrange(15)
return data
#while True:
# logger.collect_data()
# logger.check_date()
# logger.print_data()
# if logger.check_data():
# logger.log_data()
# sleep(0.2)

Categories

Resources