Strona główna Polish Python Coders Group
   Strona główna   Pomoc Zaloguj się Rejestracja  
Witamy, Gość. Zaloguj się lub zarejestruj.
Czy dotarł do Ciebie email aktywacyjny?

Zaloguj się podając nazwę użytkownika, hasło i długość sesji

Aktualności:
Szukaj Szukaj
Strony: [1]   Do dołu
Drukuj
Wątek: zadania na stringach  (Przeczytany 300 razy)
« : 01:43 01/12/17 »
leo9997 Offline
Hello World!

Zobacz profil
*

Reputacja: 2
Płeć: Mężczyzna
Wiadomości: 44


I już wracam Uśmiech dawno mnie nie było, kolejna lista w załączniku. Udało mi się zrobić pierwsze i drugie zadanie i moim zdaniem działa poprawnie Uśmiech sprawdźcie proszę, czy się nie mylę i jeśli się da, to jak to zoptymalizować, z góry dzięki ^^

ZAD1
Kod
def Anagramy(a,b):
tab,tab1=[],[]
 
for i in a:
if i.isalpha():
tab+=[i.lower()]
 
for i in b:
if i.isalpha():
tab1+=[i.lower()]
 
tab.sort(key=str)
tab1.sort(key=str)
 
if tab==tab1:
print('Są anagramami')
else:
print('Nie są anagramami')
 
Anagramy(input('Podaj pierwszy tekst '),input('Podaj drugi tekst '))

ZAD2
Kod
def Kompresja(a):
tab={}
for i in a:
if not i.isspace(): # jeśłi wyraz nie jest białym znakiem i
tab[i.lower()]=tab.get(i.lower(),0)+1
return tab.items()
 
def Dekompresja(b):
b,tab1=Kompresja(b),[]
for i in b:
tab1+=[i[0]]*i[1]
print(tab1)
 
Dekompresja(input('Podaj tekst do kompresji '))


Zapisane
« Odpowiedz #1 : 02:42 01/12/17 »
Guaz Offline
Advanced Python User

Zobacz profil
**

Reputacja: 24
Płeć: Mężczyzna
Wiadomości: 168


Do pierwszego najoptymalniejsze jest użycie słowników które zliczą ci wszystkie znaki alfabetyczne, następnie porównujesz słowniki. Metodę zliczającą już poznałeś gdy zliczaliśmy słowa Uśmiech.
Do tego wypadałoby zagnieździć w funkcji anagrams, drugą (aby nie pisać tego samego kodu).
Na przykład:
Kod
def main(): #< Polecam stosować te praktykę dla czytelności :D. 
   if Anagramy(input('Podaj pierwszy tekst '),input('Podaj drugi tekst ')):
       print("Są anagramami")
   else:
       print("Nie są anagramami")
#Inne zalety stosowania main'a odruchowo odkryjesz prędko.
#Zwłaszcza że (przynajmniej w poznanych przeze mnie) kod ci nie wystartuje w innych językach bez main'a :P.
 
def Anagramy(a, b):
   def build_dict(string):
       [metoda z get, by zbydować słownik i go zwrócić w returnie - pamiętaj o if letter.isalpha() aby nie zliczało spacji]
   if build_dict(a) == build_dict(b):
       return True #Gdy będą takie same zwróci True kończąc działanie i nie idąc dalej.
   return False #Gdy będą różne, poprzedni return nie wystąpi, więc przejdzie do tego.
 
if __name__ == "__main__":
   main() # zabezpiecza nas to przed niepowołanym uruchomieniem programu gdy chcemy
#z niego wyciągnąć na przykład tylko funkcję Anagramy, bez main'a.

Zad2
Tu nie możesz użyć słownika, ponieważ dla ciągu "AAAABBBAAA" dostaniesz {"A" : 7, "B" : 3} zrzutowane na [("A", 7), ("B", 3)] zamiast [("A", 4), ("B", 3), ("A", 3)] więc nie będziesz w stanie tego dobrze zdekompresować.
Powinieneś tu zastosować zliczanie w pętli, aż do wystąpienia innego znaku i od razu pakować w krotki gdy się zmieni litera. Albo (co wskazane optymalizacyjnie), działanie matematyczne przy zmianie znaku działając na fragmentach list.

A tu taki ubogi cezar - ma taką bolączkę że wszystkie litery zmienia na małe i wywala się gdy dasz mu przesunięcie ponad ilość liter w alfabecie:
Kod
def main():
   tekst1="".join(str(input("Wprowadz tekst: "))).lower()
   print(tekst1)
 
   x=int(input("Wprowadz wartosc przesuniecia (od 1 do 26): "))
   print( cezar(tekst1, x) )
 
def cezar(tekst, przesuniecie):
   tekst = list(tekst)
   for i in range (len(tekst)):
       temp = ord(tekst[i])
       while temp+przesuniecie > 122:
           temp = 96+(temp+przesuniecie-123)
       tekst[i] = chr(temp+przesuniecie)
 
       #~ print(chr(ord(tekst[i])+przesuniecie), end='')
   tekst = "".join(i for i in tekst)
   return tekst
 
if __name__ == "__main__":
   main()
Mogą w nim być błędy, ale raczej nie ma, bo na innym forum komuś ten kod wrzucałem ;p.
Starałem się dopasować styl z jak najmniejszą ingerencją w kod, więc nawet na pierwszy rzut oka da się go jeszcze mocno zoptymalizować ;p.
Zapisane

Python 3.5.2 / Mint
« Odpowiedz #2 : 08:03 01/12/17 »
sig Offline
Professional Python User

Zobacz profil
***

Reputacja: 78
Wiadomości: 345


Kompresja z podobnego zadania (flamaster na spoj-u http://pl.spoj.com/problems/FLAMASTE/), tyle że cyfry dajemy dopiero od 3 wystąpień (bo np A1 zajmie więcej miejsca niż samo a)
Kod
def flamaster(napis):
   wynik = ""
   pop = ""
   licznik = 1
 
   def dodaj(pop, licznik):
       if licznik == 1:
           return pop
       if licznik == 2:
           return pop + pop
       if licznik >= 3:
           return pop + str(licznik)
       return ""
 
   for znak in napis:
       if znak == pop:
           licznik += 1
       else:
           wynik = wynik + dodaj(pop, licznik)
           pop = znak
           licznik = 1
   return wynik + dodaj(pop, licznik)
 
 
ile = int(input())
for i in range(ile):
   linia = input().rstrip("\n")
   print(flamaster(linia))
 
Zapisane
« Odpowiedz #3 : 11:34 01/12/17 »
leo9997 Offline
Hello World!

Zobacz profil
*

Reputacja: 2
Płeć: Mężczyzna
Wiadomości: 44


nie mam pojęcia jak to zrobić żeby zliczało w pętli i pakowało do krotek kiedy znak się zmienia ;/
Zapisane
« Odpowiedz #4 : 11:51 01/12/17 »
Guaz Offline
Advanced Python User

Zobacz profil
**

Reputacja: 24
Płeć: Mężczyzna
Wiadomości: 168


Spójrz na fragment kodu sig'a:
Kod
    for znak in napis:
       if znak == pop:
           licznik += 1
       else:
           wynik = wynik + dodaj(pop, licznik)
           pop = znak
           licznik = 1
Wystarczy go trochę zmienić, by wynik był listą do której dodajesz krotki (pop, licznik).

Albo moje podobne rozwiązanie z kiedyś:
Kod
def example(string):
   char = string[0]; counter = 0; result = []
   for ch in string:
       if ch is char: counter += 1;
       else:
           result.append((char, counter))
           counter = 1; char = ch
   else: result.append((char, counter)); #Zapis ostatniego ciągu znaków.
   return result
 
print(example("AAABBBAABBBBAAA"))
 
(Nie pamiętam kiedy i do czego to napisałem, ale działa xP)

@Edit:
Ah i trochę bardziej przemyślany cezar ;d:
Kod
>>> def cezar(word, move):
...     from string import ascii_uppercase as upp
...     leng = len(upp)
...     return "".join([upp[(upp.index(i)+move)%leng] for i in word.upper()])
...
>>> cezar("abcdefz",1)
'BCDEFGA'
 
Zapisane

Python 3.5.2 / Mint
« Odpowiedz #5 : 12:11 01/12/17 »
leo9997 Offline
Hello World!

Zobacz profil
*

Reputacja: 2
Płeć: Mężczyzna
Wiadomości: 44


Dobra już rozumiem to drugie, pogubiłem się wcześniej w pętli, pomieszałem zmienne. Pytanie, tutaj main() jest przydatny ?
Kod
def main():
s=input('Podaj tekst do kompresji i dekompresji ')
print(Kompresja(s))
print(Dekompresja(s))
 
def Kompresja(string):
znak=string[0] #ABBAAA
licznik=0
wynik=[]
for i in string:
if i is znak:
licznik+=1
else:
wynik.append((znak, licznik))
licznik=1
znak=i
else: # gdy kończy się nasz string
wynik.append((znak, licznik))
return wynik
 
def Dekompresja(string):
tab=Kompresja(string)
napis=''
for i in tab:
napis+=i[1]*i[0]
return napis
 
if __name__=="__main__":
main()
 
Zapisane
« Odpowiedz #6 : 12:48 01/12/17 »
Guaz Offline
Advanced Python User

Zobacz profil
**

Reputacja: 24
Płeć: Mężczyzna
Wiadomości: 168


Nie jest niezbędny, to po prostu dobra praktyka aby zawsze był. Bo to sprawia że kod jest czytelniejszy. I odpalając plik główny szkielet programu w którym wykonujesz działania na funkcjach, masz od razu widoczny, zamiast doszukiwać się czy między funkcjami nie jest coś deklarowane itd.

Jedyne co, to w dekompresji nie powinno być kompresji.
Kompresja(s) przypisz do zmiennej i wywołaj dekompresję.
Kod
def main():
s=input('Podaj tekst do kompresji i dekompresji ')
k = Kompresja(s))
print(k)
d = Dekompresja(k))
print(d)
 
def Kompresja(string):
znak=string[0] #ABBAAA
licznik=0
wynik=[]
for i in string:
if i is znak:
licznik+=1
else:
wynik.append((znak, licznik))
licznik=1
znak=i
else: # gdy kończy się nasz string
wynik.append((znak, licznik))
return wynik
 
def Dekompresja(arg):
tab=arg
napis=''
for i in tab:
napis+=i[1]*i[0]
return napis
 
if __name__=="__main__":
main()
By nie dawać stringa do funkcji dekompresującej aby sobie go sam skompresował, bo wtedy funkcja jest bezużyteczna gdy podamy jej coś do dekompresji a ona się będzie doszukiwała zdekompresowanego stringa Chichot. Gdzie w takim wypadku jej funkcjonalność Język?
Chodzi o to żeby dostała skompresowany format i go zdekompresowała Uśmiech.
Zapisane

Python 3.5.2 / Mint
« Odpowiedz #7 : 18:59 01/12/17 »
leo9997 Offline
Hello World!

Zobacz profil
*

Reputacja: 2
Płeć: Mężczyzna
Wiadomości: 44


Kod
def main():
s=input('Podaj tekst do tłumaczenia ')
k=Kompresja(s)
print(k)
d=Dekompresja(k)
print(d)
 
def Morse():
tab,tab1={},{}
with open("Morse.txt", "r", encoding="ANSI") as file:
for i in file:
i=i.split()
tab[i[0]]=i[1]
tab1[i[1]]=i[0]
return tab,tab1
 
def Kompresja(string):
word,result=[],[]
string=string.upper()+' '
dictK,dictD=Morse()
 
for i in string:
if not i.isspace():
word+=[dictK[i]]
else:
result.append((word))
word=[]
return result
 
def Dekompresja(arg):
tab,napis=arg,''
dictK,dictD=Morse()
 
for i in tab:
for k in range(len(i)):
napis+=dictD[i[k]]
napis+=' '
return napis
 
if __name__=="__main__":
main()
 

Morse niby działa ale jakoś mnie to nie przekonuje. Morse.txt zrobiłem sam, wziąłem pod uwagę tylko litery(bez polskich znaków) i cyfry. Dwa słowniki itd. Strasznie to rozległe ;/ nie mam innego pomysłu
Zapisane
« Odpowiedz #8 : 13:42 02/12/17 »
Guaz Offline
Advanced Python User

Zobacz profil
**

Reputacja: 24
Płeć: Mężczyzna
Wiadomości: 168


Chwila, kompresujesz i dekompresujesz morsa Język?
Zapisane

Python 3.5.2 / Mint
« Odpowiedz #9 : 13:47 02/12/17 »
leo9997 Offline
Hello World!

Zobacz profil
*

Reputacja: 2
Płeć: Mężczyzna
Wiadomości: 44


Nie no kompresuje napis i dekompresuje ten napis w morsie. Nie rozumiem, pogubiłem się Chichot
Zapisane
« Odpowiedz #10 : 14:27 03/12/17 »
Guaz Offline
Advanced Python User

Zobacz profil
**

Reputacja: 24
Płeć: Mężczyzna
Wiadomości: 168


Jeśli twierdzisz że działa ;p.
Zapisane

Python 3.5.2 / Mint
« Odpowiedz #11 : 14:44 03/12/17 »
leo9997 Offline
Hello World!

Zobacz profil
*

Reputacja: 2
Płeć: Mężczyzna
Wiadomości: 44


ej no Chichot serio jest coś nie tak ?
Jeszcze potrafię tak. W kompresji bez tablic. Słowa oddzielam spacjami a znaki w słowach |.
Kod
def main():
s=input('Podaj tekst do tłumaczenia ')
k=Kompresja(s)
print(k)
d=Dekompresja(k)
print(d)
 
def Morse():
tab,tab1={},{}
with open("Morse.txt", "r", encoding="ANSI") as file:
for i in file:
i=i.split()
tab[i[0]]=i[1]
tab1[i[1]]=i[0]
return tab,tab1
 
def Kompresja(string):
result,string='',string.upper()+' '
dictK,dictD=Morse()
 
for i in string:
if not i.isspace():
result+=dictK[i]+'|'
else:
result=result.rstrip('|')+' '
return result
 
def Dekompresja(arg):
wynik,arg='',arg.split()
dictK,dictD=Morse()
 
for i in arg:
i=i.split('|')
for k in range(len(i)):
wynik+=dictD[i[k]]
wynik+=' '
return wynik.capitalize()
 
if __name__=="__main__":
main()
 
Zapisane
« Odpowiedz #12 : 16:55 03/12/17 »
leo9997 Offline
Hello World!

Zobacz profil
*

Reputacja: 2
Płeć: Mężczyzna
Wiadomości: 44


Kod
def main():
tekst1=''.join(str(input('Wprowadz tekst: '))).lower()
x=int(input('Wprowadz wartosc przesuniecia >=1 '))
print(cezar(tekst1,x))
 
def cezar(tekst,przesuniecie):
tekst=list(tekst)
 
for i in range(len(tekst)):
if not tekst[i].isspace():
temp=ord(tekst[i])
while temp+przesuniecie>122:
temp-=26
tekst[i]=chr(temp+przesuniecie)
else:
tekst[i]=' '
tekst=''.join(i for i in tekst)
 
return tekst
 
if __name__=="__main__":
main()

a tu cezar chyba działa dla każdego przesunięcia, no i ze spacjami

edit@: z dekompresją
Kod
def main():
tekst1=''.join(str(input('Wprowadz tekst: '))).lower()
x=int(input('Wprowadz wartosc przesuniecia >=1 '))
k=CezarK(tekst1,x)
print(k)
d=CezarD(k,x)
print(d)
 
def CezarK(tekst,przesuniecie):
tekst=list(tekst)
 
for i in range(len(tekst)):
if not tekst[i].isspace():
temp=ord(tekst[i])
while temp+przesuniecie>122:
temp-=26
tekst[i]=chr(temp+przesuniecie)
else:
tekst[i]=' '
tekst=''.join(i for i in tekst)
 
return tekst
 
def CezarD(tekst2, przesuniecie2):
tekst2,przesuniecie2=list(tekst2),(26-przesuniecie2%26)
 
 
for i in range(len(tekst2)):
if not tekst2[i].isspace():
temp1=ord(tekst2[i])
while temp1+przesuniecie2>122:
temp1-=26
tekst2[i]=chr(temp1+przesuniecie2)
else:
tekst2[i]=' '
tekst2=''.join(i for i in tekst2)
 
return tekst2
 
if __name__=="__main__":
main()
Zapisane
« Odpowiedz #13 : 03:57 04/12/17 »
Guaz Offline
Advanced Python User

Zobacz profil
**

Reputacja: 24
Płeć: Mężczyzna
Wiadomości: 168


Po prostu miałem na myśli fakt że według listy zadań, kod morsa trzeba było tylko umieć przetłumaczyć w obie strony. Jednak bez pliku z którego wczytujesz słownik, ciężko to ocenić jak działa ;d. Logika zachowana, więc raczej powinno być ok Uśmiech

Co do cezara, wystarczyłoby w tym:
Kod
>>> def cezar(word, move):
...     from string import ascii_uppercase as upp
...     leng = len(upp)
...     return "".join([upp[(upp.index(i)+move)%leng] for i in word.upper()])
...
>>> cezar("abcdefz",1)
'BCDEFGA'
dodać
Kod
if not i.isspace() else i
po upp aby dostać spacje Chichot. Ale słuszna uwaga - zapomniałem o tym leo ^^.
No i cezar ten też działa w obie strony. Podając mu minusową wartość - więc po co dawać dwie funkcje skoro jedna robi to samo ;>?

 
Zapisane

Python 3.5.2 / Mint
« Odpowiedz #14 : 11:46 04/12/17 »
leo9997 Offline
Hello World!

Zobacz profil
*

Reputacja: 2
Płeć: Mężczyzna
Wiadomości: 44


Morse'a zostawiam tak, chyba że potrafisz go jeszcze zoptymalizować Mrugnięcie, w załączniku dodam 'Morse.txt'.
Kod
def main():
s=input('Podaj tekst do tłumaczenia ')
k=Kompresja(s)
print(k)
d=Dekompresja(k)
print(d)
 
def Morse():
tabK,tabD={},{}
with open("Morse.txt", "r", encoding="ANSI") as file:
for i in file:
i=i.split()
tabK[i[0]]=i[1]
tabD[i[1]]=i[0]
return tabK,tabD
 
def Kompresja(string):
dictK,dictD=Morse()
result=''
 
for i in string.upper()+' ':
if not i.isspace():      
result+=dictK[i]+'|'
else:
result=result.rstrip('|')+' '
return result                        
 
def Dekompresja(arg):
dictK,dictD=Morse()
wynik=''
 
for i in arg.split():
i=i.split('|')
for k in range(len(i)):
wynik+=dictD[i[k]]
wynik+=' '
return wynik
 
if __name__=="__main__":
main()
 

Tego skróconego Cezara nie bardzo rozumiem, próbowałem poszukać w necie, ale nie bardzo to jest wytłumaczone. + nie działa mi to jeśli chciałbym pobierać dane od użytkownika 0.o. W linijce z return wyrzuca błąd  "ValueError: substring not found"
Zapisane
Strony: [1]   Do góry
Drukuj
Skocz do:  

© 2007 - 2017 Polish Python Coders Group
Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines | Theme by PixelSlot