- Liittynyt
- 28.08.2018
- Viestejä
- 803
woot, käytän juuri Codea en tiennyt tuollaisesta ominaisuudesta. tuli tehtyä nyt apinan hommia mutta jos jatkossa.
Ottaa aikansa, että editorin ominaisuuksista saa kaiken irti. Kannattaa varmaan tsekata Youtubesta joku VSCode tutoriaali. Noista varmaan ne käytetyimmät ominaisuudet tulee selville nopeasti.woot, käytän juuri Codea en tiennyt tuollaisesta ominaisuudesta. tuli tehtyä nyt apinan hommia mutta jos jatkossa.
Suositus on käsittääkseni se, että tyypillisesti lähes kaikki halutaan mainin ulkopuolella ja että mainiin jäisi pelkästään se logiikka, jota tarvitaan ohjelman varsinaiseen ajamiseen. Näin ainakin periaatteessa samaa tiedostoa voidaan käyttää sekä kirjastona että sovelluksena. Yksinkertainen esimerkki (paremmankin voisi väsätä, mutta ei ole tähän hätään käytettävissä tähän yhtään enempää aikaa):Ymmärrän nyt miten tämä toimii, mutta en ymmärrä vielä miten käytän sitä oikein
if __name__ == "__main__":
main()
elikkäs laitetaanko kaikki koodi myös muuttujat ja muut funktiot kaikki tuohon def main(): alle? vai tulisko muuttujat, muutujien alustus, ja muut def funktiot olla ulkopuolella?
def main():
rupesin nyt olemassa olevaan python koodiini lisäämään tätä if toimintoa, mutta rupesin siirtämään kaiken sen alle ja aikamoinen työ vetää joka riville yks tab "4space". Olisiko vain se koodi missä käytetään def funktioita siirrettävä main:in alle?
edit: siirsin nyt kaiken def mainin alle ja koodi ainakin toimii. en tiedä olisiko siinä mitään pahaa jos muuttujat ja def funkkarit olisivat ulkopuolella. ymmärränkö oiken että jos funktiot olisivat ulkopuolella, niitä voisi käyttää ulkopuolelta? nyt kun kaikki on mainin alla niin vain tämä kirjasto saa luvan käyttää funktioita ja koko koodia.
def add(x, y):
return x + y
def main():
x = input("Enter a number: ")
x = float(x)
y = input("Enter another number: ")
y = float(y)
print(f"Result: {add(x,y)}")
if __name__ == "__main__":
main()
Kannattaa myös opetella lukemaan noita kääntäjän/linterin virheilmoituksia ajatuksen kanssa, tuossa ylläolevassa virheilmossa se kerrottiin melko tarkasti, miksi se ei toimi. Tarkoitus siis ei ole vittuilla, itse olin myös aikoinaan laiska noita lukemaan kun opettelin koodaamista ja googlettelin kaiken.
Joo olette molemmat oikeassa. Vähän väsyneenäkin yritin tuota tehdä niin ei vain mennyt päähän, että mikä siinä rivissä oli virheenä.Alkuperäisessä oli loopin ulkopuolella luku1 ja loopissa luku2.
Eli ehkä se luku1 olikin kirjoitusvirhe vaikka piti esitellä luku2 ?
Mutta kuten @Technocrat jo kertoi kannattaa opetella lukemaan virheitä, muuten ei pääse kovin pitkälle...
No siis yleisesti sä korvaat sen localhostin sen Raspberryn IP-osoitteella. Jos olette samassa sisäverkossa, niin se voisi esimerkiksi olla "192.168.0.10". Eli koettaisit ottaa yhteyden osoitteeseen ws://192.168.0.10:1234. Sitten pitää olla palomuurit sun muut konffattu päästämään tuo liikenne läpi. Sama periaate jos otat yhteyden internetistä, silloin käytät sen Raspin julkista IP-osoitetta. Mutta silloin pitää ehkä laittaa joku port forwarding päälle reitittimestä, jonka takana se Raspi on. Koska se julkinen osoite pointtaa vain siihen reitittimeen/modeemiin, joka on saanut operaattorilta osoitteen. Se pitää ohjata sisäverkon osoitteeseen.Miten toi websocket client pitäis toteuttaa että se frontend ottaa aina yhteyden siihen C++ serveriin siellä laitteen sisällä,
Se frontti ajetaan selaimessa, ei laitteella. Eli jos frontti tarvitsee porttia 1234 WS:ään, niin sitten se pitää avata, jotta liikenne kulkee. Mutta, WS toimii portin 80 kautta, et tarvitse siihen 1234:ää.Mutta jos haluan että laitteelle on vain portti 80 auki käyttöliittymää varten ja kaikki muu liikenne tapahtuu laitteen sisällä
Onko mun hakema toiminnallisuus siis mahdottomuus? Ei ole mahdollista että kaksi komponenttia keskustelee keskenään vain rasperryn sisällä, ja frontend näyttää vain keskustelun tulokset selaimessa?Se frontti ajetaan selaimessa, ei laitteella. Eli jos frontti tarvitsee porttia 1234 WS:ään, niin sitten se pitää avata, jotta liikenne kulkee. Mutta, WS toimii portin 80 kautta, et tarvitse siihen 1234:ää.
Ei tietenkään ole mahdottomuus. Kerrotko, mitä siis tarkalleen haluat tehdä? Vastasin vain siihen, että haluat ottaa WS-yhteyden selaimesta Raspiin portin 1234 kautta. (Ellen siis ymmärtänyt jotain väärin.) WS:ään et tarvitse muuta porttia kuin 80:n.Onko mun hakema toiminnallisuus siis mahdottomuus? Ei ole mahdollista että kaksi komponenttia keskustelee keskenään vain rasperryn sisällä, ja frontend näyttää vain keskustelun tulokset selaimessa?
column_name DECIMAL(P,D);
D:n pitää olla vähemmän tai yhtäsuuri kuin P, niin pitäiskö P täyttää nollilla tai jotain?
The declaration syntax for a DECIMAL column is DECIMAL(M,D). The ranges of values for the arguments are as follows:
- M is the maximum number of digits (the precision). It has a range of 1 to 65.
- D is the number of digits to the right of the decimal point (the scale). It has a range of 0 to 30 and must be no larger than M.
Ei ainakaan vielä.Selvensikö tuo?
Ok. Eli M on kokonaistarkkuus eli luvun numeroiden KOKONAISmäärä. D on desimaalien määrä. DECIMAL(11,9) tarkoittaa että sulla on yhteensä 11 numeroa, joista 9 on desimaaleja. Eli sen pilkun vasemmalle puolelle jää 11-9 numeroa. Se on 2. Siksi 40.76 toimii mutta 534.4 ei toimi. 534:ssä on 3 numeroa pilkun vasemmalla puolella ja se vaatisi tarkkuudeksi 12, eikä 11 kun desimaaleja on 9.Ei ainakaan vielä.
Eipä se kannan vaihto yleensä mitään oikeasti auta, jokaisen tapauksessa joudut kuitenkin opettelemaan miten asiat tehdään juuri siinä kannassa.Tietenkin sitä voisi kokeilla jotain muutakin db:tä (vaikka toki ehkä järkevintä pysyä myslissä kun sen nyt jotenkin tuntee). Esim joku ArnangoDb on ollut vähän kokeilussa. Siitä saisi suoraan microservicejäkin ulos. No, opetellaan tää nyt loppuun ja katsotaan sitten. Serverillä pyörii jo mysli valmiiksi, niin järkevää kai käyttää sitä. Ja kun phpmysal:lla on niin kiva pullautella sisään ja ulos dataa.
Tähän vielä kommentti, unsigned poistaa mahdollisuuden tallentaa negatiivisia lukuja, yleensä rahasummien kanssa se ei ehkä ole tarkoitus ?Ei ainakaan vielä.
Kokeilin esimerkiksi että DECIMAL (11,9)
Jolloin data tuotuna
40.76 -> 40.760000000, mutta
534.4 -> 99.999999999
106880 -> 99.999999999 jne
Eli out of rangella mennään. Laitoin unzigened zerofilliksi kentän myös testiksi.
create table t (
v1 decimal(10,5) unsigned zerofill,
v2 decimal(10,5)
);
insert into t values (1.75, 1.75);
select * from t;
+-------------+---------+
| v1 | v2 |
+-------------+---------+
| 00001.75000 | 1.75000 |
+-------------+---------+
insert into t values (-1.75, -1.75);
=> ERROR 1264 (22003): Out of range value for column 'v1' at row 1
Itse käytän näitä:Mikähän virheilmoitus tämä on visual codessa, kun yritän html tiedostoa avata edge selaimeen. Olen poistanut ja tehnyt uuden launch.jsonin ja sama virhe tulee vaikka laittaa run valikosta start debugging tai run without debugging. Ei auta vaikka tekee kaikki tiedostot workspacesta lähtien uusiksi. Aikaisemmin toimi mainiosti, mutta eilen rupesi tuota virhettä ilmoittamaan.
function getStationShortCodeForTimeTableQuery (station) {
const URL = "https://rata.digitraffic.fi/api/v1/metadata/stations/"
axios(
{
method: "GET",
url: URL,
headers: {
"Accept-Encoding": "gzip"
}
}
)
.then((response) => {
let body = response.data
let stationToLowerCase = station.toLowerCase()
const matchingStation = body.filter(train => train.passengerTraffic === true && train.stationName.toLowerCase().match(stationToLowerCase))
console.log(matchingStation) // tulostaa objektin sisällön: [{}, {}] (consolen toka loggaus)
console.log(typeof matchingStation) // == object ( consolen kolmas loggaus)
return matchingStation
})
let station = req.body.station
let hmm = getStationShortCodeForTimeTableQuery(station)
console.log(`${hmm} mikä tää o`) // tulostaa undefined (consolen eka loggaus), typeof = undefined
res.render("about")
Ja return tuon axios-kutsun eteen. Ja jos tykkää Promise-syntaksista, niin sitten voi laittaa then-kutsun sen getStationShortCodeForTimeTableQuery(station)-kutsun jälkeen, jonka sisällä sitten lokitus ja res.render().Eli async/await kehiin ja pitäisi toimia
Menin tutkimaan tuota async await touhua ja saan nyt logattuakin tuossa toisessa funktiossa mutta se ei ole kuitenkaan mitä haen vaan tarvitsen sen palautettavan muuttujaksi että voin lähettää sen templateen renderöitäväksi. Menee yli hilseen ja arvailun puolelle. Onko tarjota rautalankamallia?console.log ja Promise ovat asynkronisia, kun taas funktiosi on synkroninen. Siksi näet objektin vaikka se ei vielä synkronista koodia suoritettassa ole käytössä.
Eli async/await kehiin ja pitäisi toimia
const getStationShortCodeForTimeTableQuery = async (station) => {
const stationsURL = "https://rata.digitraffic.fi/api/v1/metadata/stations/"
try {
const resp = await axios({
method: "GET",
url: stationsURL,
headers: {
"Accept-Encoding": "gzip"
}
})
if (resp.status == 200) {
const body = resp.data
const stationToLowerCase = station.toLowerCase()
const matchingStation = body.filter(train => train.passengerTraffic === true && train.stationName.toLowerCase().match(stationToLowerCase))
return `${matchingStation[0].stationName}, ${matchingStation[0].stationShortCode}`
} else {
console.log("tapahtui virhe")
}
} catch (err) {
console.error(err)
}
}
exports.getAllPassengerTrafficStations = (req, res) => {
let station = req.body.station
getStationShortCodeForTimeTableQuery(station).then(resp => console.log(resp))
res.render("about")
}
Sullahan on jo se muuttujassa, muuttujassa resp tuossa alemmassa koodissa. Eli sen lisäksi että lokitat, sä voit laittaa sinne sen res.render():in. Kun käytät theniä, niin se res.render() pitää olla sen thenin sisällä. Tai sitten laitat asyn/await myös alempaan:tarvitsen sen palautettavan muuttujaksi että voin lähettää sen templateen renderöitäväksi
const foo = await getStationShortCodeForTimeTableQuery();
res.render(foo); // Tai mitä nyt haluatkin tehdä
Voi perkele luulin yrittäneeni just tuolla then:issä renderöidä jo kertaalleen, mutta ehkäpä meni placeholder ja muuttuja sekasin tai jotain muuta jännää.Sullahan on jo se muuttujassa, muuttujassa resp tuossa alemmassa koodissa. Eli sen lisäksi että lokitat, sä voit laittaa sinne sen res.render():in. Kun käytät theniä, niin se res.render() pitää olla sen thenin sisällä. Tai sitten laitat asyn/await myös alempaan:
Käyttäisin samaa tapaa joka paikassa eli joko .then() tai sitten async/await. En ehkä sekaisin. Ja jos teet async/await, niin se exports.getAllPassengerTrafficStations pitää määritellä asyn:ksi.Koodi:const foo = await getStationShortCodeForTimeTableQuery(); res.render(foo); // Tai mitä nyt haluatkin tehdä
<html><head>
<script src="jquery-3.5.1.min.js"></script>
<script>
$(document).ready(function(){
$.get("ajaxtest.py?id=1", function(result){ $( "#a1" ).html( "<small>" + result + "</small>" ); });
$.get("ajaxtest.py?id=2", function(result){ $( "#a2" ).html( "<small>" + result + "</small>" ); });
$.get("ajaxtest.py?id=13", function(result){ $( "#a13" ).html( "<small>" + result + "</small>" ); });
$.get("ajaxtest.py?id=63", function(result){ $( "#a63" ).html( "<small>" + result + "</small>" ); });
$.get("ajaxtest.py?id=88", function(result){ $( "#a88" ).html( "<small>" + result + "</small>" ); });
});
</script>
</head>
<body>
<table>
<tr><td>Test</td><td id="a1">asd</td></tr>
<tr><td>Test</td><td id="a2">asd</td></tr>
<tr><td>Test</td><td id="a13">asd</td></tr>
<tr><td>Test</td><td id="a63">asd</td></tr>
<tr><td>Test</td><td id="a88">asd</td></tr>
</table>
</body></html>
Yksinkertaisin on varmaan tehdä id- numeroista taulukko ja loopata se läpi siellä missä tarvitaan, eli ready():n getit (ja ehkä taulukon rivit myös)Pitääpä itsekin pitkästä aikaa kysyä täältä viisaampien apua kun javascriptiä en oikein ole noin 15 vuoteen koodannut ja jquery on vielä vieraampaa. Olen siis koodailemassa omaa kotiautomaatio/kodinohjausjärjestelmääni uusiksi. Kooditagien sisällä on mahdollisimman simppeli ongelmallinen koodinpätkä, oikean html:n generoi minulla python-skripti automaattisesti ja siinä on aika paljon kaikkea muutakin. Nykyinen koodi sinällään kuitenkin toimii.
Ajattelin, että nuo $.get() -rivit varmaankin saisi jotenkin tehtyä jollain luupilla ettei tarvitsisi tehdä/generoida jokaiselle ladattavalle id:lle omaa riviä. Noita rivejä tulee lopputuloksessa olemaan noin viitisenkymmentä kappaletta ja id-numerot saattavat olla mitä tahansa arviolta 1 ja 500 väliltä. Tuo html-taulukko siis generoituu tosiaan automaattisesti tekemälläni python-skriptillä joten tarvittaessa saan sitäkin muutettua.HTML:<html><head> <script src="jquery-3.5.1.min.js"></script> <script> $(document).ready(function(){ $.get("ajaxtest.py?id=1", function(result){ $( "#a1" ).html( "<small>" + result + "</small>" ); }); $.get("ajaxtest.py?id=2", function(result){ $( "#a2" ).html( "<small>" + result + "</small>" ); }); $.get("ajaxtest.py?id=13", function(result){ $( "#a13" ).html( "<small>" + result + "</small>" ); }); $.get("ajaxtest.py?id=63", function(result){ $( "#a63" ).html( "<small>" + result + "</small>" ); }); $.get("ajaxtest.py?id=88", function(result){ $( "#a88" ).html( "<small>" + result + "</small>" ); }); }); </script> </head> <body> <table> <tr><td>Test</td><td id="a1">asd</td></tr> <tr><td>Test</td><td id="a2">asd</td></tr> <tr><td>Test</td><td id="a13">asd</td></tr> <tr><td>Test</td><td id="a63">asd</td></tr> <tr><td>Test</td><td id="a88">asd</td></tr> </table> </body></html>
Noiden ajaxtest.py suorittaminen kestää noin sekunnista kymmeneen sekuntiin kappaleelta riippuen id:stä jonka takia ajattelin latailla ne jqueryllä. Aluksi tosin ajattelin että tuo skripti joka luo tuon html:n olisi suoraan käynyt hakemassa nuo toisen skriptin hakemat tiedot mutta sivun latautuminen kesti aivan liian kauan eikä noiden tietojen ilmestyminen viiveellä haittaa mitään.
Promise.all ei auta "...saisi jotenkin tehtyä jollain luupilla ettei tarvitsisi tehdä/generoida jokaiselle ladattavalle id:lle omaa riviä..." ongelmaan. Sillä saat tosin kaikki rivit päivittymään samaan aikaan (eli kun viimeinenkin kutsu on resolvattu) jos sitä haet. Ilman promisea taulukon itemit päivittyvät heti, kun kyseisen rivin kutsu on resolvattu.document.querySelectorAll("tr")
.forEach(item => console.log(item.children[1].id))
<script>
$(document).ready(function(){
document.querySelectorAll("tr").forEach(getdata);
function getdata(item) {
solu = "#"+item.children[1].id;
nro = item.children[1].id.substring(1);
$.get("ajaxtest.py?id="+nro, function(result){ $( solu ).html( "<small>" + result + "</small>" ); });
}
});
</script>
Noniin, pääsin tuolla @Samppa vinkillä jo niin pitkälle että sain id:t napattua ja niiden perusteella luupattua $.get():llä nuo läpi mutta jostain syystä kaikki arvot päivittyvät peräkkäin viimeisen id:n sijaintiin. Eli allaolevalla koodinpätkällä toimii jo lähestulkoon oikein, html on sama kuin aiemmin. console.log():lla kyllä katselin että kaikki id:t käydään järjestyksessä läpi. Luultavasti tässä taas on joku hyvin simppeli aivopieru mitä en keksi.
HTML:<script> $(document).ready(function(){ document.querySelectorAll("tr").forEach(getdata); function getdata(item) { solu = "#"+item.children[1].id; nro = item.children[1].id.substring(1); $.get("ajaxtest.py?id="+nro, function(result){ $( solu ).html( "<small>" + result + "</small>" ); }); } }); </script>
solu = "#"+item.children[1].id;
function(result){ $( solu ).html( "<small>" + result + "</small>" );
Mutta jos se sivun luova python hakisikin taulukkoon sisällön asynkronisesti (multiprocessing, threading), ja päivittäisi serverillä olevaa sivua sitä mukaa kuin tietoja saadaan, ja lopettaisi päivityksen kunhan kaikki tiedot on kertaalleen kerätty tai kun aikaa on kulunut sopivasti, niin asiakaspäässä riittäisi pelkkä http-refresh sopivin välein. Sekä nappi, jolla saa päivityksen taas käyntiin. jQuery on tässä tarpeeton, ja sen sivun saa tehtyä myös ilman javascriptiä.Toki voisin pythonilla luoda koko sivun jokaisella sivulatauksella jolloin sivun latautumiseen kestäisi ikuisuus. Toinen vaihtoehto olisi tietty muutaman minuutin välein generoida nuo tiedot valmiiksi johonkin tiedostoon tai tietokantaan mutta en näe sitä järkevänä koska tuolla sivulla ei vierailla normaalitilanteessa kovin usein joten ihan turhaan varmuuden vuoksi noita generoitaisiin. Sitten taas yli muutaman minuutin ikäiset arvot ovat vanhentuneita joten ne joka tapauksessa olisi kiva hakea tuoreeltaan.
Näinhän se on. Mutta kun ymmärsin että vaihtoehdotkin kiinnostavat, ja kun minulla tuota aikaa on, niin näpersin pienen python-skriptin, joka lukee muutaman kuvitteellisen "anturin", joiden lukemiseen kuluu max 10 sekuntia / anturi, ja tekee tämän multiprocessing-rinnakkaistetusti niin, että kokonaisaika riippuu periaatteessa vain hitaimmasta anturista, jos prosessien määrää ei rajoiteta. Eli siis skriptin ajoaika on 10 sekuntia + overhead, vaikka antureita olisi sata. Lopuksi skripti rakentaa tuloksista html-raportin ja avaa sen oletusselaimessa. Mikään webiserverin kautta jaettava sovellus tämä ei kuitenkaan ole.hrk, varmaan tuon voisi tehdä noinkin, mutta koitan tehdä tätä mahdollisimman pitkälti niillä taidoilla mitä mulla on. Kuitenkin vaikka suuri osa on ihan tuttua niin aina välillä tulee tällaisia pikkujuttuja joita ensin yritän omin voimin ratkoa ja lopulta joudun kyselemään esim täällä. Esim nuo multiprocessing ja threading ovat vielä lähestulkoon tuntemattomia asioita ja kun tätä tekee vapaa-ajalla ihan harrastuspohjalta niin ei ole oikein resursseja opetella ihan kaikkea vaikka mieli tekisikin. Ehkä sitten seuraavassa versiossa käytän noitakin. Tämäkin on jo parannus kun saa edes suurimman osan vanhoista purkkavirityksistä siivoiltua.
import multiprocessing as mp
import os, time, random
import tempfile
# anturien tunnukset
id = ['lämpö, ulko', 'lämpö, olkkari', 'lämpö, makkari',
'lämpö, sauna', 'oluita, jääkaapissa', 'meilejä, lukematta']
def test(id):
viive = random.randint(1, 10)
time.sleep(viive)
return random.randint(1,30)
def f(Q, idx):
Q.put((idx, test(id[idx])))
def startjobs(Q, count):
for i in range(count):
p = mp.Process(target=f, args=(Q, i))
p.start()
# fire and forget: no join
def main():
Q = mp.Queue()
count = len(id)
t = time.time()
startjobs(Q, count)
results = []
while(count):
idx, value = Q.get()
results.append((id[idx], value))
count -= 1
page = "<html><body>\n<table>\n"
page += "<tr><th style=\"text-align:left;\">Anturi</th><th>Lukema</th></tr>"
for result in sorted(results):
ident, value = result
page += f"\n<tr><td>{ident}</td><td>{value}</td></tr>"
page += "\n</table>\n</body></html>"
with tempfile.NamedTemporaryFile('w',suffix=".html", delete=False) as f:
f.write(page)
tempname = f.name
os.startfile(tempname)
time.sleep(1) # give time for browser to open file
os.remove(tempname)
if __name__ == "__main__":
# main process only
main()
Joo, Pythonin multiprocessing-kirjasto on mukava, kun jokaisella prosessilla on oma kopio kaikesta ja voidaan tehdä mitä vaan. Threading-kirjasto on paljon krantumpi. Mutta kyllä tämä nyt puheena oleva tehtävä hoituu paremmin siten kuin olet sen hoitanut. Kun se webiserveri joka tapauksessa on. AJAX on hieno keksintö.Hmm... eihän tuo nyt niin kovin monimutkaiselta ainakaan yhtäkkiä vaikuta. Ainakin luulen ymmärtäväni kuinka tuo toimii ihan näin nopealla vilkaisullakin. Pitääpä ottaa tuo skriptinpätkä talteen ja tutustua siihen joskus paremmalla ajalla. Kiitoksia tuostakin, ei sitä tiedä jos vaikka joskus jotain tuontyyppistäkin tekisi johonkin projektiin.
import re
import subprocess
from influxdb import InfluxDBClient
response = subprocess.Popen('/usr/local/bin/speedtest-cli --simple', shell=True, stdout=subprocess.PIPE).stdout.read().decode('utf-8')
ping = re.findall('Ping:\s(.*?)\s', response, re.MULTILINE)
download = re.findall('Download:\s(.*?)\s', response, re.MULTILINE)
upload = re.findall('Upload:\s(.*?)\s', response, re.MULTILINE)
ping = ping[0].replace(',', '.')
download = download[0].replace(',', '.')
upload = upload[0].replace(',', '.')
speed_data = [
{
"measurement" : "internet_speed",
"tags" : {
"host": "RaspberryPiMyLifeUp"
},
"fields" : {
"download": float(download),
"upload": float(upload),
"ping": float(ping)
}
}
]
client = InfluxDBClient('localhost', 8086, 'speedmonitor', 'pimylifeup', 'internetspeed')
client.write_points(speed_data)
Ping: 5.424 ms
Download: 404.41 Mbit/s
Upload: 663.63 Mbit/s
IP=****
IP_LAT=***
IP_LON=***
PROVIDER=Keski-Suomen Valokuituverkot Oy
TEST_SERVER_HOST=nopeustesti2.ksvvnet.fi:8080
TEST_SERVER_DISTANCE=85.1755
LATENCY=3
JITTER=0
DOWNLOAD_SPEED=713.05
UPLOAD_SPEED=1047.20
Millä re.findall-parametreilla saan tuosta toisesta haettua vastaavat tiedot Ping, Download ja Upload kenttiin? Eli pelkkä numeraalinen arvo pitäisi hakea.
ping = re.findall('LATENCY=(.*?)\s', response, re.MULTILINE)
download = re.findall('DOWNLOAD_SPEED\=(.*?)\s', response, re.MULTILINE)
upload = re.findall('UPLOAD_SPEED\=(.*?)$', response, re.MULTILINE)
Eikös tuo MULTILINE-optio ole juurikin tuo "pieni muokkaus". Silloin siis dollarimerkki matchaa sekä rivinvaihdot että stringin lopun. Eli nuo pingin ja downloadin \s-merkit voisi myös korvata $:lla, jolloin kaikki toimii riippumatta siitä missä järjestyksessä rivit on listattu.Huom. Tuo uploadin pattern olettaa sitten että tuo stringi päättyy tuon upload-osion jälkeen, eli jos se vielä jatkuukin niin tuo ei toimi, vaan tarvii pienen muokkauksen tuohon.Python:ping = re.findall('LATENCY=(.*?)\s', response, re.MULTILINE) download = re.findall('DOWNLOAD_SPEED\=(.*?)\s', response, re.MULTILINE) upload = re.findall('UPLOAD_SPEED\=(.*?)$', response, re.MULTILINE)
EDIT: Hups, jäi tuo muuttujan nimi vääräksi tuonne findall-komentoon, nyt korjattu niin että pitäisi toimia suoraan.