10 svar
128 visningar
IndentationError behöver inte mer hjälp
IndentationError 7
Postad: 26 mar 2021 09:00

Hur kan man förhindra ett program från att köras om man får NAN värden?

Hej,

Jag har ett skript som beräknar global volym och area. I några fall, förvandlas dessa värden till "NAN" (not a number). Så, jag vill förhindra att mitt program körs i det första fallet jag får ett "NAN".

Efter lite webbsökning, hittade jag numpy isnan som kunde vara användbart.

Jag tänkte skriva:

import numpy as np

if np.isnan("min variabel"):
    break

men det verkar inte funka. 

Kan någon tänka på ett annat alternativ eller ett bättre sätt att använda numpy isnan? Tack på förhand!

Smutstvätt 24967 – Moderator
Postad: 26 mar 2021 09:20

Skulle det fungera med en if-sats? I sådant fall skulle du kunna köra:

import numpy as np

if np.isfinite(DIN VARIABEL):
	KOD SOM SKA KÖRAS HÄR

np.isfinite rensar bort både NaN:s och oändligheter dock. 

Lindehaven 820 – Lärare
Postad: 26 mar 2021 11:08

Du får egentligen inte ett "NAN" utan ett numpy.NaN

Exempel:

import numpy as np
my_list = [1, 2, 3, np.NaN, 4, 5]
for e in my_list:
    if np.isnan(e):
        break
    else:
        print(e)
Laguna 30251
Postad: 26 mar 2021 12:26

Vad gör du för operation som ger NaN? 

IndentationError 7
Postad: 26 mar 2021 12:49

@Laguna

Hej, jag vill tacka alla för era svar. Jag kör några simuleringar med nanopartiklar i en lösning. Om alla parametrar är ok, blir simuleringen klar. Annars, exploderar den och ger NaN. Men jag tror att det inte är mitt Python skript som är problematiskt, utan det är en C++ kod som är importerad och innehåller formeln för beräkningen av den globala volymen och arean. Så, egentligen vill jag stoppa C++ kod från att köras, när jag får NaN.

Lindehaven 820 – Lärare
Postad: 26 mar 2021 12:56
IndentationError skrev:

@Laguna

Hej, jag vill tacka alla för era svar. Jag kör några simuleringar med nanopartiklar i en lösning. Om alla parametrar är ok, blir simuleringen klar. Annars, exploderar den och ger NaN. Men jag tror att det inte är mitt Python skript som är problematiskt, utan det är en C++ kod som är importerad och innehåller formeln för beräkningen av den globala volymen och arean. Så, egentligen vill jag stoppa C++ kod från att köras, när jag får NaN.

Intressant, visa gärna denna C++ kod, hur du importerat den och använt den. Vi kan nog lösa problemet gemensamt.

IndentationError 7
Postad: 26 mar 2021 13:10

Koden är stor och kan inte delas offentligt, men dess mest viktiga delen är följande:

int k = 0;
real global_volym = 0.0;
real global_area = 0.0;
for (; it.isValid(); ++it) {
global_volym += abs(1.0/6.0*xi*(pos1+pos2+pos3)/3.0);
global_area += 0.5*sqrt(xi*xi);
std::cout << " Globala volymen är : " << global_volym << std::endl;
std::cout << " Globala arean är : " << global_area << std::endl;
k=k+1;
}

, där "xi" är en tvärprodukt.

Så vad kan jag lägga till här för att avsluta programmet när jag får NaN? Kanske något liknande med sys.exit i Python?

Lindehaven 820 – Lärare
Postad: 26 mar 2021 14:12

C++ koden skickar svaren till stdout och då gissar jag att du omdirigerar svaren till din Python-kod som läser dem från stdin, kanske med input()? Om det är så, kan du inte på något enkelt sätt avsluta C++ programmet från Python eftersom de kör separata processer.

Python-programmet behöver först ta reda på processidentiteten för C++ processen och sedan stoppa den med os.kill().

Om du öppnat C++ programmet från Python med exvis subprocess.Popen() så går det enklare att ta reda processidentiteten för C++ processen och stoppa den.

Kolla på Geeks for Geeks om att stoppa extern process eller på Stack Overflow om att stoppa process öppnad från Python.

Laguna 30251
Postad: 26 mar 2021 15:03

Det här kanske ser bra ut: https://en.cppreference.com/w/cpp/numeric/math/isnan

Lindehaven 820 – Lärare
Postad: 26 mar 2021 15:26
Laguna skrev:

Det här kanske ser bra ut: https://en.cppreference.com/w/cpp/numeric/math/isnan

Ja, det går ju att använda i C++ koden och låta den stänga ned själv. Och slippa åbäket med processidentiteter...

int k = 0;
real global_volym = 0.0;
real global_area = 0.0;
for (; it.isValid(); ++it) {
  global_volym += abs(1.0/6.0*xi*(pos1+pos2+pos3)/3.0);
  global_area += 0.5*sqrt(xi*xi);
  if (std::isnan(global_volym) || std::isnan(global_area)) {
    std::cout << "NaN" << std::endl;
    exit(EXIT_FAILURE);
  }
  else {
    std::cout << " Globala volymen är : " << global_volym << std::endl;
    std::cout << " Globala arean är : " << global_area << std::endl;
    k=k+1;
  }
}
IndentationError 7
Postad: 26 mar 2021 19:24

Tack så mycket för den användbara länken @Languna.

Din lösning funkade perfekt i mitt fall @Lindehaven :)

Svara
Close