2024-06-15, 15:15
  #1
Medlem
I ett annat inlägg ställer användaren Rullandegalning en fråga om hur man i Python hämtar en extern fil och använder den som en uppslagsbok. Eftersom forumsdelen är i dvala 364 dagar om året kan vi lika gärna reda ut vad han vill och hur man kan göra det.

I ursprunglig tråd inkommer Rullandegalning med följande AI-genererad kod:


Ur koden kan vi utläsa att han har låtit AI generera ett shifferskript som ska knäcka ett skiffer med en extern ordlista. I koden finner vi följande mock-kod:
Kod:
# Load the list of English words
with open("path/to/your/dictionary.txt") as f:
    
words = [word.strip().upper() for word in f if word.strip().isalpha()] 

Frågan han ställer är hur han får in en ordlista i sitt skript när han befinner sig på sin Ipad.

För att lösa detta problem behöver han veta två saker:
1. uppslagsverk eller dictionaries har två betydelser i Python. Båda betydelserna används dessutom i den AI-genererade koden. Ett uppslagsverk är kodmässigt objektet Dict
Kod:
=dict({"a":"apa"}
Out[7]: {'a''apa'}
type(a)
Out[8]: dict 
Men det kan också vara ett uppslagsverk, dvs en ordbok som en fil.

2. För att hämta en fil i ditt script behöver du känna till modulen "os" och "sys". Båda använder ditt operativsystems konfiguration för att finna specifika kommandon för just ditt system. Det enklaste du kan göra är att låta Python själv bestämma den relativa adressen till din ordbok, eller använda den absoluta adressen som du manuellt matar in när du kör ditt skript.

3. De flesta pythonprogram körs genom CLI och startas med python [programfil.py] eller python3 [programfil.py] eller python -m [programfil.py]. Vi kommer att använda de två föregående beroende på ditt OS. När jag vill köra mitt skript vill jag också mata in den ordfil som jag använder som ordlista, vilket jag gör med python programfil.py ordlista.txt.

Vi kommer använda "sys" och vi skapar ett litet skript som kommer att printa ut argumenten vi använder när vi öppnar programmet:
Kod:
import sys
#sys.argv är platsen där argumenten ligger. Den returnerar en lista med dina argument.
wrd_list =sys.argv 
print(wrd_list

Redultatet blir:
Kod:
python3 tmp.py
['tmp.py']

Vill jag ha med min ordlista eller en adress till min ordlista;
Kod:
python3 tmp.py ordlista.txt
['tmp.py', 'ordlista.txt']
Kod:
python3 tmp.py c:\ordlista.txt
['tmp.py', 'c:\ordlista.txt']

Okej! Nu vet vi hur vi hämtar filnamnet och eventuellt hela adressen till filen, bra! Hur använder vi nu den?
Ja, processen här beror ju på hur din ordlista är utformad, är det ord som är i flytande text, eller är det ord som är uppradade?

Till att börja med ser hans ursprungliga kod ut så här:
Kod:
with open("path/to/your/dictionary.txt") as f:
    
words = [word.strip().upper() for word in f if word.strip().isalpha()] 
Vi behåller den så länge och modifierar det vi har lärt oss.
Kod:
import sys
#Eftersom sys.argv returnerar en lista på allt som är efter "python" måste jag välja element i listan
#Jag vet att element på plats 1 är min ordlista.
#Jag hämtar då element 1 genom sys.argv[1]
file_name =sys.argv[1]

# Nu har jag ersatt "path/to/your/dictionary.txt" med file_name
# Den kan vara ett filnamn eller en absolut adress.
with open(file_name'r') as f:
    
words = [word.strip().upper() for word in f if word.strip().isalpha()] 

Om vi skapar en fil med frukter:
Kod:
cat frukt.txt
äpple
banan
päron

Vi kör vårt lilla skript som det är nu:
Kod:
python3 tmp.py frukt.txt 
['ÄPPLE', 'BANAN', 'PÄRON']

Ser man på, vi får min ordlista i en lista. Vi har således använt en extern fil i vårt skript.
Dock är inte listkomprimeringen särskilt strålande, då "f" är en IOWrapper som hänger. Vi vet inte vad den kommer att göra. Nu hade vi tur att den läste av varje ord i ordlistan, den kunde lika gärna ha läst av varje bokstav.

Är man inte säker på var man har sin ordlista får man använda modulen "os" och "os.path" för att hitta adressen till sin lista. Men det är en annan tråd.

För övrigt är AI-gnererad python rätt klumpig att använda.

För folk som inte förstår akademisk diskussion:
Hur kan vi mer hjälpa killen med sitt skript?
Hur kan kille lära sig att t.ex. skriva om den där for-loopen som lika gärna kan vara i With-containern.
Varför ska man inte köra IOWrapper helt utan uppgift?

(Vhe kan hålla sig borta från python så länge).
__________________
Senast redigerad av Methos 2024-06-15 kl. 15:43.
Citera
2024-06-15, 15:32
  #2
Medlem
FelaktigCaptchas avatar
Citat:
Ursprungligen postat av Methos
För övrigt är AI-gnererad python rätt klumpig att använda.
Næsten al AI-genereret kode er ikke så god. 👏🏿
Citera
2024-06-15, 16:55
  #3
Medlem
henrikos avatar
Då försöker jag ändå hitta lite att diskutera då.

Citat:
Ursprungligen postat av Methos
I koden finner vi följande mock-kod:
Kod:
# Load the list of English words
with open("path/to/your/dictionary.txt") as f:
    
words = [word.strip().upper() for word in f if word.strip().isalpha()] 

Vad menar du med detta? I vilket sammanhang ersätts den riktiga koden med denna enklare attrapp?

Citat:
Ursprungligen postat av Methos
För att lösa detta problem behöver han veta två saker:
1.
2.
3.

Vilka två av dessa tre punkter är det som gäller?

Citat:
Ursprungligen postat av Methos
För att hämta en fil i ditt script behöver du känna till modulen "os" och "sys".

Det där är ju två helt olika moduler. Menar du möjligen "modulerna" så är det inte sant. Det räcker alldeles utmärkt med os för att läsa in en fil.

Citat:
Ursprungligen postat av Methos
Nu hade vi tur att den läste av varje ord i ordlistan, den kunde lika gärna ha läst av varje bokstav.

Ska vi vara petiga här så är f i det här exemplet inte en IOWrapper som du påstår. Den är en TextIOWrapper, och när du itererar över en sådan med hjälp av in så får du rader, alltid.

"wrappern" f arbetar alltså inte ordvis som du antyder att den gör.

Varför det i exemplet faktiskt alltid råkar bli ord har snarare med användingen av isalpha() att göra, som sållar bort tomrader och eventuella rader med hela meningar ur filen.

Citat:
Ursprungligen postat av Methos
För folk som inte förstår akademisk diskussion:

Varför måste diskussionen ske inom en akademi överhuvudtaget. Varför inte bara föra en helt vanlig diskussion, om det finns något att diskutera? Det är ju bara Python-kod det handlar om. Det är inget man måste ha en speciell skyddad yrkestitel eller så för att få uttala sig om. Jag fattar inte alls vad du vill ha sagt här.

Citat:
Ursprungligen postat av Methos
Hur kan kille lära sig att t.ex. skriva om den där for-loopen som lika gärna kan vara i With-containern.

Den första frågan borde vara vad Rullandegalning skulle tjäna på det? Lägre inlärningströskel? Högre läsbarhet? Tveksamt.

Citat:
Ursprungligen postat av Methos
Varför ska man inte köra IOWrapper helt utan uppgift?

Vad menar du? Har det med Rullandegalnings problem att göra? Är detta inte mera lämpligt att avhandla som ett helt separat ämne?
Citera
2024-06-15, 16:57
  #4
Medlem
Enterprises avatar
Citat:
Ursprungligen postat av Methos
Hur kan vi mer hjälpa killen med sitt skript?
Jag tror nu att vi kastar pärlor åt svin, men felhantering (t.ex. att hantera om argument saknas) vore lämpligt.
Citera
2024-06-15, 17:15
  #5
Medlem
Citat:
Ursprungligen postat av Enterprise
Jag tror nu att vi kastar pärlor åt svin, men felhantering (t.ex. att hantera om argument saknas) vore lämpligt.

Nä, det är genom dessa pedagogiska uppgifter som vi mer avancerade användare kan lära oss av det vi gör. Vi får nu tillfälle att tänka till. Du lär dig inte att förstå din programmering genom att hämta kod från internet och använda, utan du lär dig programmering och matematik (för den delen) genom att analysera och förklara för andra.

Men däremot bör hans kod göras om. Jag gillar inte hans AI-genererade kod utan struktur.
Jag har grubblat på varför AIn vill begränsa ordlistan till dels enbart ord, men sedan konventera ordet till string.upper() både i ordlistan och sedan i shifferfunktionen. Om alla ord som ordlistan innehåller redan är upper(), då spelar det ju ingen roll om hans shifferfunktion gör "key" till upper(), för den är redan upper().

Och ja, självklart bör han ha en kontrollfunktion som kontrollerar att han verkligen har en ordlista, för annars smäller ju koden på något ställe. Den bör smälla vid IOWrappern då open() knappast kan vara utan filnamn/filadress.
Efter den kontrollen bör ju han ha en kontroll som ser till att han verkligen har ord i sin ordlista.
Citera
2024-06-15, 17:25
  #6
Medlem
Citat:
Ursprungligen postat av henriko
Då försöker jag ändå hitta lite att diskutera då.



Vad menar du med detta? I vilket sammanhang ersätts den riktiga koden med denna enklare attrapp?

Och få ännu en metadiskussion? Håll dig till koden...

Om du inte ser att den wrappern är en mock-kod så är det något fel. Kola vad open() tar in för parameter...

Citat:
Det där är ju två helt olika moduler. Menar du möjligen "modulerna" så är det inte sant. Det räcker alldeles utmärkt med os för att läsa in en fil.

Här använder vi sys då det räcker med CLI-argumentet. Vi behöver inte röra OS.
OS kan förvisso vara bra på vissa lägen, men det ger också en brantare inlärningskurva.

Citat:
Ska vi vara petiga här så är f i det här exemplet inte en IOWrapper som du påstår. Den är en TextIOWrapper, och när du itererar över en sådan med hjälp av in så får du rader, alltid.

"wrappern" f arbetar alltså inte ordvis som du antyder att den gör.

Varför det i exemplet faktiskt alltid råkar bli ord har snarare med användingen av isalpha() att göra, som sållar bort tomrader och eventuella rader med hela meningar ur filen.

Fast du vet inte om ordlistan är på rader eller i fulla meningar. Ja, isalpha() garderar härom att det inte blir en massa knasigheter. Dock är det helt onödigt att göra den ordlistan som han gör. Dels för att han lika gärna kan iterera genom wrappern med for-loopen och dels för att han använder string.upper() på två ställen.
Citera
2024-06-15, 17:48
  #7
Medlem
Enterprises avatar
Citat:
Ursprungligen postat av Methos
dels för att han använder string.upper() på två ställen.
Detta är typiskt ett (förvisso harmlöst) "script kid"-misstag, när man sammanfogar kopierad kod från två olika källor utan djupare förståelse om vad koden gör. Som bekant är LLM precis likadan, vilket nog är orsaken till förekomsten av denna onödighet, alltså: A) kopierad kod och B) oförståelse
Citera
2024-06-15, 17:52
  #8
Medlem
henrikos avatar
Citat:
Ursprungligen postat av Methos
Och få ännu en metadiskussion? Håll dig till koden...

Om du inte ser att den wrappern är en mock-kod så är det något fel. Kola vad open() tar in för parameter...

Mock-kod är ju när man har en funktion eller modul med samma interface som en annan funktion eller modul, och att man då kan byta ut den riktiga mot mocken, för att möjliggöra eller underlätta körning av delar av systemet, utan att behöva ha ett komplett system.

Nej jag ser inte att någon del av denna snippet uppfyller dessa kriterier, varför jag upplever att det du som initierar metadiskussioner genom att blanda in irrelevanta begrepp.

Varför skrev du inte bara "kod" istället för "mock-kod"? Vad är det jag missar, i distinktionen här, som verkligen är betydelsefullt för tråden?

Citat:
Ursprungligen postat av Methos
Fast du vet inte om ordlistan är på rader eller i fulla meningar. Ja, isalpha() garderar härom att det inte blir en massa knasigheter.

Trams. Det spelar ingen roll hur ordlistfilen faktiskt ser ut. Ditt påstående som jag bemötte handlade om "wrappern" f, och dess beteende rent generellt. Det är samma "wrapper" f oavsett hur ordlistfilen ser ut. "Wrappern" i sig, i sammanhanget, jobbar radvis oavsett hur ordlistfilen ser ut. Ordlistfilens innehåll ändrar inte på detta.

Citat:
Ursprungligen postat av Methos
Dock är det helt onödigt att göra den ordlistan som han gör. Dels för att han lika gärna kan iterera genom wrappern med for-loopen och dels för att han använder string.upper() på två ställen.

Irrelevant, då det endast var dina påståendet angående den befintliga koden jag bemötte. Att det går att lösa uppgiften på olika sätt ändrar givetvis inget av det du skrivit om koden som den faktiskt var eller är.
Citera
2024-06-15, 17:52
  #9
Medlem
Citat:
Ursprungligen postat av Enterprise
Detta är typiskt ett (förvisso harmlöst) "script kid"-misstag, när man sammanfogar kopierad kod från två olika källor utan djupare förståelse om vad koden gör. Som bekant är LLM precis likadan, vilket nog är orsaken till förekomsten av denna onödighet, alltså: A) kopierad kod och B) oförståelse

Förutom då att det kan leda till flera instansieringar av listan. För varje gång du använder stringmetoder skapar du en helt ny lista.
Citera
2024-06-15, 18:06
  #10
Medlem
henrikos avatar
Citat:
Ursprungligen postat av Methos
Fast du vet inte om ordlistan är på rader eller i fulla meningar.

Du skrev ju ut den. Så ja, jo, jag vet exakt vad den innehöll.

Men genom att läsa koden kunde jag konstatera att koden inte arbetade ordvis, vilket sättet du uttryckte dig på antydde, och att därmed följande innehåll
Kod:
äpple banan päron
skulle ge
Kod:
['ÄPPLE', 'BANAN', 'PÄRON']
__________________
Senast redigerad av henriko 2024-06-15 kl. 18:10.
Citera
2024-06-15, 18:22
  #11
Medlem
Citat:
Ursprungligen postat av henriko
Du skrev ju ut den. Så ja, jo, jag vet exakt vad den innehöll.

Men genom att läsa koden kunde jag konstatera att koden inte arbetade ordvis, vilket sättet du uttryckte dig på antydde, och att därmed följande innehåll
Kod:
äpple banan päron
skulle ge
Kod:
['ÄPPLE', 'BANAN', 'PÄRON']

Jag har aldrig sagt att den läser ordvis, den ska läsa teckenvis som allt annat i denna värld.

För att du ska förstå:
Kod:
with open("frukt.txt""r") as f:
    
words = [word.strip().upper() for word in f if word.strip().isalpha()] 

print(
words

Där har du samma kod, men jag har lagt in ordlistan manuelt.

Med en fil med
Kod:
cat frukt.txt
äpple päron banan

Får jag: []
Dvs TOM lista.

Kod:
cat frukt.txt
äpple 
päron
banan
Svar;
['ÄPPLE', 'PÄRON', 'BANAN']

Kod:
cat frukt.txt
äpplepäronbanan
Svar:
['ÄPPLEPÄRONBANAN']


Som du ser får vi helt olika svar från wrappen beroende på hur vår ordlista ser ut.
När ordlistan är på en enda rad såsom "äpple, banan, päron" får vi en tom lista tillbaka.
Detta har fullt med att du itererar genom en wrapper utan uppgift, vilket gör att orden kommer på samma rad.
Citera
2024-06-15, 20:03
  #12
Medlem
henrikos avatar
Citat:
Ursprungligen postat av Methos
Jag har aldrig sagt att den läser ordvis, den ska läsa teckenvis som allt annat i denna värld.

Du skrev "Dock är inte listkomprimeringen särskilt strålande, då "f" är en IOWrapper som hänger. Vi vet inte vad den kommer att göra. Nu hade vi tur att den läste av varje ord i ordlistan, den kunde lika gärna ha läst av varje bokstav."

Det är mycket konstigt, eller åtminstone ovidkommande, i den lilla texten. Men en sak i taget.

Ordet "den" i den sista meningen där måste ju syfta på "wrappern" och inget annat. Alltså påstår du att wrappern läser varje ord. Det är inte alls det den gör. Den läser varken ord, som du påstod då, eller teckenvis som du yrar om nu. Den läser rader.

Hur detta är implementerat bakom kulisserna, om den möjligen där läser tecken för tecken, eller i block om 512 tecken, eller vad den gör, har vi ingen aning om, och det ska vi skita i.

Håller du med om att TextIOWrapper läser radvis? Eller motsätter du dig detta?

Citat:
Ursprungligen postat av Methos
För att du ska förstå:
Kod:
with open("frukt.txt""r") as f:
    
words = [word.strip().upper() for word in f if word.strip().isalpha()] 

print(
words

Där har du samma kod, men jag har lagt in ordlistan manuelt.

Med en fil med
Kod:
cat frukt.txt
äpple päron banan

Får jag: []
Dvs TOM lista.

Så långt är vi givetvis överens, eftersom jag skrev "sållar bort tomrader och eventuella rader med hela meningar ur filen".

Visst. Nu är det inte en vettig mening du skrivit. Men ja. Jag borde ha skrivit att isalpha() sållar bort rader med flera ord. Det var dåligt av mig.

Om du lagt in filen manuellt eller med något annat verktyg är fullständigt irrelevant så klart. Om den så är skriven av en katt har det inget med saken att göra. Det enda som är relevant är filens syntax.

Citat:
Ursprungligen postat av Methos
Kod:
cat frukt.txt
äpple 
päron
banan
Svar;
['ÄPPLE', 'PÄRON', 'BANAN']

Varför du repeterar detta vet jag inte. Detta var väl ändå högst klarlagt redan från början, och har inte ifrågasatts av någon.

Citat:
Ursprungligen postat av Methos
Kod:
cat frukt.txt
äpplepäronbanan
Svar:
['ÄPPLEPÄRONBANAN']

Det här exemplet är ju bara bizarrt. Jag begriper inte syftet. Detta kan ju aldrig definieras eller tolkas på något annat sätt än som ett sammansatt ord, och alltså fungerar det exakt som i första exemplet, som ingen har ifrågasatt.

Enda chansen att kunna ha en fil som ser ut så här, och plocka ut enskilda ord eller orddelar, vore ju om man i ett steg innan hade läst in en ordlista, så en algoritm faktiskt skulle kunna göra något vettigt av datan, men det blir ju då ett moment 22.

Citat:
Ursprungligen postat av Methos
Som du ser får vi helt olika svar från wrappen beroende på hur vår ordlista ser ut.

Ja, det är väl ganska givet.

Jag tror inte jag hävdat något annat. Det jag hävdat är att "wrappern" är den samma oavsett hur filen ser ut. Och att du i samtliga fall, hur du än skriver, får ut rad för rad från "Wrappern".

Vad tjafsar du om?

Citat:
Ursprungligen postat av Methos
När ordlistan är på en enda rad såsom "äpple, banan, päron" får vi en tom lista tillbaka.

Ja, som sagt. Och som du illustrerade med första exemplet i detta inlägg.


Citat:
Ursprungligen postat av Methos
Detta har fullt med att du itererar genom en wrapper utan uppgift, vilket gör att orden kommer på samma rad.

Efter alla dessa exempel och repetitioner fattar jag fortfarande inte vad du menar med "utan uppgift". "Wrappern" har ju uppgiften att leverera rader ur filen.

Kan du försöka beskriva vad du menar med någon synonym eller så? Pratar du om att "wrappern" saknar syfte? Eller pratar du om att "wrappern" saknar direktiv?
Citera

Skapa ett konto eller logga in för att kommentera

Du måste vara medlem för att kunna kommentera

Skapa ett konto

Det är enkelt att registrera ett nytt konto

Bli medlem

Logga in

Har du redan ett konto? Logga in här

Logga in