Verstehe den Fehler in Python Programmierung nicht.

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Shiru
User
Beiträge: 3
Registriert: Montag 5. September 2016, 23:39

Hallo,
da es mein erster Beitrag in diesem Forum ist vergebt mir mögliche Fehler, die ich mache und korrigiert mich auch bitte gleich, damit ich sie nicht wiederhole.

Ich bin ein Programmieranfänger und ich habe mich als erste richtige Sprache für Python entschieden, die ich mir selbst versuche beizubringen. Um das Gelernte etwas zu vertiefen, wollte ich ein Programm schreiben, welches ein Wort annimmt und jeweils einen Buchstaben im Wort vergrößert und die anderen dabei klein lässt.
Ich sehe mein Problem in der Iteration, denn bei diesem Code kommt bei der ersten und letzten Variation "TesT" raus statt einmal "Test" und "tesT"

Code: Alles auswählen

inpt = input("Input: ") 

def var_input(inpt): 
	inpt = str(inpt) #da ich python 3.4.3 benutze und ich noch kein raw_input gefunden habe regle ich das so..
    string = inpt
    for n in range(len(inpt)):
		inpt = string.replace(string[n], string[n].upper())
	print (inpt)
	
var_input(inpt)
Diesen misslichen Umstand versuchte ich, einfach, weil ich es nicht besser weiß, so zu umgehen:

Code: Alles auswählen

inpt = input("Input: ")

def var_input(inpt):
        inpt = str(inpt)
        string = inpt
        for n in range(len(inpt)):
                inpt = string.replace(string[n], string[n].upper())
                inpt = inpt.replace(inpt[n+1:len(inpt)], inpt[n+1:len(inpt)].lower())
                
                if n > 0:
                        inpt = inpt.replace(inpt[:n], inpt[:n].lower())
                        
                print(inpt)
                print (" To be upped: %s" % (inpt[n])) #habe ich benutzt um den Fehler zu finden
                print ("inpt lower range %s :executed order %s" % (inpt[n+1:len(inpt)], inpt[n+1:len(inpt)].lower())) # "" 
                if n > 0:
                        
                    print ("inpt lower range %s with n >0: executed order %s" % (inpt[:n], inpt[:n].lower())) # ""

var_input(inpt)
Beim Wort "Test" oder anderen Wörtern, die nicht dauernd sich wiederholende Buchstaben haben funktioniert es so, allerdings geht es nicht bei Wörtern, wie "Banana" etc.
Dann kommt sowas bei raus:
Input: Banana
Banana
To be upped: B
inpt lower range anana :executed order anana
bAnana
To be upped: A
inpt lower range nana :executed order nana
inpt lower range b with n >0: executed order b
banaNa
To be upped: n
inpt lower range aNa :executed order ana
inpt lower range ba with n >0: executed order ba
banana
To be upped: a
inpt lower range na :executed order na
inpt lower range ban with n >0: executed order ban

banaNa
To be upped: N
inpt lower range a :executed order a
inpt lower range bana with n >0: executed order bana
bananA
To be upped: A
inpt lower range :executed order
inpt lower range banan with n >0: executed order banan


Wo genau liegt der Fehler, wie könnte ich es besser machen? Bin für alle Vorschläge offen, um meinen Code zu verbessern.
Danke im voraus.
Zuletzt geändert von Anonymous am Dienstag 6. September 2016, 00:17, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@Shiru: `raw_input()` kannst Du in Python 3 nicht finden weil es das dort `input()` das ist was bei Python 2 `raw_input()` war. Die Funktion liefert eine Zeichenkette, es macht also keinen Sinn da noch einmal `str()` drauf anzuwenden. Zeile 4 in den beiden Beispielen hat keinen Effekt, kann also entfallen.

Du beschreibst IMHO nicht wirklich gut was denn das eigentliche Ergebnis sein soll, deshalb rate ich einfach mal, das Du bei der Eingabe von 'test' die folgenden vier Ausgaben haben möchtest:

Test
tEst
teSt
tesT

Im ersten Beispiel verwendest Du die `replace()`-Methode die *alle* vorkommen vom ersten Argument durch das zweite ersetzt. Man kann die Anzahl der Ersetzungen zwar durch das dritte, optionale Argument beschränken, aber es gibt keine Möglichkeit einen Versatz anzugeben bei dem die Ersetzungen starten sollen. Damit ist die `replace()`-Methode nicht zu gebrauchen.

Im zweiten Versuch kommt auch `replace()` vor, den mag ich mir aber sonst nicht weiter anschauen, das ist viel zu viel für diese Aufgabe. Da ist die Menge an Code also grundsätzlich schon mal falsch. :-)

Du musst einfach nur den Teil vor dem aktuellen Index ausgeben, dann das Zeichen am aktuellen Index als Grossbuchstabe, und dann den Teil nach dem aktuellen Index.

Da das doch irgendwie nach Hausaufgabe riecht, nicht in Python sondern im Lisp-Dialekt Hy (der in Python implementiert ist):

[codebox=clojure file=Unbenannt.txt]#!/usr/bin/env hy

(defn uppercase-nth [text n]
(+ (cut text None n)
(.upper (get text n))
(cut text (inc n))))


(defmain [&rest args]
(let [text (input "Input: ")]
(for [i (range (len text))]
(print (uppercase-nth text i)))))[/code]
Shiru
User
Beiträge: 3
Registriert: Montag 5. September 2016, 23:39

Ich danke dir :D
Ich habe im Grunde verstanden wie du das Problem angehst nun muss ich nurnoch versuchen, das alles in die richtigen Python-Vokabeln umzuschreiben und diesmal hoffentlich Unnötiges wegzulassen :D
Das mit Lisp-Dialekt Hy kannte ich vorher noch gar nicht, muss mich nachher mal reinlesen.
Ich wünschte, es wäre eine Hausaufgabe, dann hätte ich nämlich auch einen Lehrer, der mir bei vielen Dingen helfen könnte ;)
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@Shiru: die ganzen Bausteine hast Du ja schon benutzt, jetzt geht es nur noch darum, sie richtig zusammenzusetzen; also alle Buchstaben bis zum n-ten inpt[:n] und ab dem n+1-ten inpt[n+1:] in Kleinbuchstaben umwandeln und den fehlenden inpt[n] in Großbuchstaben. Zusammensetzen, fertig, ganz ohne replace.
Shiru
User
Beiträge: 3
Registriert: Montag 5. September 2016, 23:39

Ja danke, hatte es schon gelöst :)
BlackJack

@Shiru: Die Hy-Variante in Python:

Code: Alles auswählen

def uppercase_nth(text, n):
    r"""Uppercase a letter.

    :returns: `text` with the `n`\-th character in upper case.
    :raises IndexError: if not 0 ≤ `n` < len(`text`)
    
    >>> uppercase_nth('parrot', 0)
    'Parrot'
    >>> uppercase_nth('spam', 1)
    'sPam'
    >>> uppercase_nth('eric', 42)
    Traceback (most recent call last):
      ...
    IndexError: string index out of range
    >>> uppercase_nth('python', -1)
    Traceback (most recent call last):
      ...
    IndexError: negative index
    """
    if n < 0:
        raise IndexError('negative index')
    return text[:n] + text[n].upper() + text[n + 1:]


def main():
    text = input('Input: ').lower()
    for i in range(len(text)):
        print(uppercase_nth(text, i))


if __name__ == '__main__':
    main()
Und weil ich gerade Leerlauf hatte, eine Lösung in Pascal :-):
[codebox=delphi file=Unbenannt.pas]program UpCaseEachLetter;

var line: String;
i: Byte;
original: Char;

begin
Write('Input: ');
ReadLn(line);
for i := 1 to Length(line) do
begin
original := line;
line := UpCase(original);
WriteLn(line);
line := original;
end;
end.[/code]
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Es ist wirklich interessant wozu man kommt wenn man Indizes vermeiden möchte.

[codebox=haskell file=Uppercase.hs]import Data.Char
import System.IO

uppercased :: String -> [String]
uppercased [] = []
uppercased [x] = [[toUpper x]]
uppercased (x:xs) = (toUpper x : xs) : map (x:) (uppercased xs)

prompt :: String -> IO String
prompt p = putStr p >> hFlush stdout >> getLine

main :: IO ()
main = do
string <- prompt "Input: "
mapM_ putStrLn (uppercased string)
[/code]
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Stimmt, kein Problem, das sich nicht per Rekursion lösen ließe:

Code: Alles auswählen

def uppercased(text, pre=""):
    return [] if not text else [pre + text.capitalize()] + uppercased(text[1:], pre + text[0])
nezzcarth
User
Beiträge: 1633
Registriert: Samstag 16. April 2011, 12:47

Sirius3 hat geschrieben:Stimmt, kein Problem, das sich nicht per Rekursion lösen ließe:
CamelCase wird da allerdings zeitweilig von capitalize verschluckt ;)
BlackJack

Mal was leicht perverses:
[codebox=bash file=Unbenannt.bsh]#!/bin/bash

main() {
local text
local i
declare -u char

read -p 'Input: ' text
for i in $(seq 0 $((${#text} - 1))); do
char=${text:$i:1}
echo "${text:0:$i}${char}${text:$((i + 1))}"
done
}

main[/code]
BlackJack

Eine Lösung in Assembler für DOS (``nasm -f bin -o upcase.com upcase.asm``):
[codebox=asm file=Unbenannt.asm] cpu 386
org 100h
[map all]

start:

segment .data

.prompt:
db "Input: $"
.cr:
db 13, 10, '$'

segment .bss

.max_length:
resb 1
.length:
resb 1
.string:
resb 128+1

segment .text
mov ah,09h
mov dx,.prompt
int 21h

mov byte [.max_length],128
mov ah,0ah
mov dx,.max_length
int 21h

mov ah,09h
mov dx,.cr
int 21h

mov ch,[.length]
or ch,ch
jz .exit

xor cl,cl
.main_loop:
xor bx,bx
.char_loop:
mov dl,[.string+bx]
cmp cl,bl
jne .skip_upcase

cmp dl,'a'
jl .skip_upcase
cmp dl,'z'
jg .skip_upcase
sub dl,20h
.skip_upcase:

mov ah,02h
int 21h

inc bl
cmp bl,ch
jle .char_loop

mov ah,02h
mov dl,10
int 21h

inc cl
cmp cl,ch
jne .main_loop

.exit:
ret[/code]
nezzcarth
User
Beiträge: 1633
Registriert: Samstag 16. April 2011, 12:47

BlackJack hat geschrieben:Mal was leicht perverses:
Och... ;) Das Ist jedenfalls so generisch, dass ich es mit minimalen Änderungen zusätzlich auch unter ksh93(, mksh) und zsh zur korrekten Mitarbeit bewegen konnte.
BlackJack

Ich habe da mal was zusammengeklickt…
Bild
Antworten