Początkujący ocena i sprawdzenie kodu.

Początkujący ocena i sprawdzenie kodu.
L8
  • Rejestracja:ponad 4 lata
  • Ostatnio:prawie 2 lata
  • Postów:33
0

Cześć.
Uczę się od niedawana pythona i skończyłem rozdział na funkcjach. Chciałem się trochę sprawdzić i wymyśliłem sobie program, podzieliłem na moduły, a teraz staram się go napisać krok po kroku.
Pierwszy moduł zakłada utworzeni pustej listy, do której będą dodawane odcinki uciętego profila oraz ilość występowania tego odcinka. Czyli jak mamy 5 odcinków o długości 500 mm to powinno dodać do lisy [500, 500, 500, 500, 500]. Całość ma być zapętlona tak żeby dodać dowolną liczbę elementów do listy.

Napisałem kod i działa.
Proszę kogoś doświadczonego o ocenę i czy może jest jakaś inna opcja, która sprawi że kod będzie bardziej prosty(krótszy). Czy można to napisać lepiej ?

Kopiuj
profile_dim = []

#Wpisanie długość odcinka oraz ile razy ma wystąpić na liście
active = True

while active:
	profile = []
	print('\nWpisanie "quit" spowoduje wyłączenie programu')
	lenght = input('Podaj długość uciętego profila: ')
	if lenght == 'quit':
		break
	else:
		lenght = int(lenght)


	multiply = int(input(f'Ile sztuk {lenght} wykonać?: '))
	if multiply == 'quit':
		break
	else:
		multiply = int(multiply)

	#Dodanie do listy oraz zwielokratniania elementów listy 
	profile.append(lenght)
	profile = profile*multiply
	print(profile)

	#Dodawanie elementów listy do głownej listy
	profile_dim.extend(profile)


	#Pytanie czy zakończyć dodawanie elementów do listy 

	ending = input('Czy zakończyć dodawanie elementó do listy ("tak"/"nie")')
	if ending == 'tak':
		active = False
	else:
		active = True

print(profile_dim)
Spearhead
  • Rejestracja:prawie 6 lat
  • Ostatnio:około 6 godzin
  • Postów:1002
1

Ten twój quit nie działa jak powinien, bo jak spróbujesz rzutować tekst nie będący liczbą na int, to wybuchnie wyjątkiem:

Kopiuj
>>> int(input(f'Ile sztuk {lenght} wykonać?: '))
Ile sztuk 0 wykonać?: f
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'f'

Powinieneś rzutować raz i to w bloku try-catch by się bronić przed wyjątkami w razie gdyby użyszkodnik wprowadził niesprawdzone dane.

Po drugie, wrzuć wszystko do jakiejś funkcji, działa wtedy szybciej, poza tym znika chociażby problem stosowania zmiennych globalnych (antywzorzec).

Komentarze tłumaczące oczywistości w stylu

Kopiuj
    #Dodawanie elementów listy do głownej listy
    profile_dim.extend(profile)

Nie są potrzebne. To wynika wprost z kodu. Komentarze służą do znaczenia rzeczy nieoczywistych i nie powinny być nadużywane. No ale do wyczucia dochodzi się z czasem.

Można by odpowiedzi przemielić dodatkowo lower() żeby zarówno wpisanie "Tak" jak i "tak" działało.

L8
  • Rejestracja:ponad 4 lata
  • Ostatnio:prawie 2 lata
  • Postów:33
0

@Spearhead:
Co do tego quit mam świadomość, że jak ktoś wpisze coś innego poza liczbą albo quit to program się wywali. Googlowałem try-catch i z tego co widzę to jeszcze nie ten etap mojej nauki. Pewnie w między czasie dojdę do tego. Ale odnotuję to sobie i wrócę jeżeli nie spotkam się z tym później.
Zacznę od tej strony: 8.Errors and Exceptions.

Ten kod będzie upakowany w funkcji teraz tylko wkleiłem tak, żeby poddać do oceny jego działanie.

Z komentarzami przyznaję rację.

Zaraz wrzucę linijkę z lower().
Czyli pomijając problem z quit, za który wezmę się później całość może wyglądać tak po uwzględnieniu Twoich uwag?:
Teraz zauważyłem, że jak wywołuję funkcję to mogę podać jakiekolwiek argumenty bo nie mają one znaczenia dla działania funkcji.

Kopiuj
def section_dec(lenght, multiply):
	'''Funkcja mająca na celu utworzenie listy z odcinkami pociętego profilu'''	
	#Wpisanie długość odcinka oraz ile razy ma wystąpić na liście
	profile_dim = []
	active = True

	while active:
		profile = []
		print('\nWpisanie "quit" spowoduje wyłączenie programu')
		lenght = input('Podaj długość uciętego profila: ')
		if lenght == 'quit':
			break
		else:
			lenght = int(lenght)


		multiply = int(input(f'Ile sztuk {lenght} wykonać?: '))
		if multiply == 'quit':
			break
		else:
			multiply = int(multiply)

		#Dodanie do listy oraz zwielokratniania elementów listy 
		profile.append(lenght)
		profile = profile*multiply
		print(profile)

		
		profile_dim.extend(profile)



		ending = input('Czy zakończyć dodawanie elementó do listy ("tak"/"nie")').lower()
		
		if ending == 'tak':
			active = False
		else:
			active = True

	return profile_dim

section = section_dec(0,0)
print(f'lista wszystkich przyciętych prfili: \n\t{section}')
Spearhead
  • Rejestracja:prawie 6 lat
  • Ostatnio:około 6 godzin
  • Postów:1002
1

Nie ma sensu aby funkcja section_dec przyjmowała argumenty, ponieważ i tak natychmiast je nadpisujesz wartościami wprowadzanymi przez użytkownika. Starczy

Kopiuj
def section_dec():
    # ...

Wywołanie głównej funkcji zwykle dodatkowo obtacza się w if __name_ == '__main__', jakbyś kiedyś chciał importować coś z tego modułu

Kopiuj
if __name__ == "__main__":
    section = section_dec()
    print(f'lista wszystkich przyciętych prfili: \n\t{section}')

Zmienna active jest w sumie zbędna. Zamiast tego możesz na końcu wychodzić tak samo jak wcześniej - breakiem lub returnem

Kopiuj
while True:
    # ...
    ending = input('Czy zakończyć dodawanie elementó do listy ("tak"/"nie")').lower()
    if ending == 'tak':
        break

Komunikat w sumie też można by przeformułować bo można wpisać również cokolwiek innego i będzie miało taki sam efekt jak "nie".

Dla spójności komentarze też można by pisać po angielsku.

Czy zgodnie z deklinacją nie powinno być czasem Podaj długość uciętego profilu zamiast Podaj długość uciętego profila?

Brak wyjątków dalej razi, podstawy możesz już sobie przeczytać, potem dojdziesz do szczegółów.

Reszta wydaje się w porządku jak na tak prosty program.

L8
  • Rejestracja:ponad 4 lata
  • Ostatnio:prawie 2 lata
  • Postów:33
0

@Spearhead:

Brak wyjątków dalej razi, podstawy możesz już sobie przeczytać, potem dojdziesz do szczegółów.>

A mógłbyś mi wstawić przykładowy kod ? Próbuję to ogarnąć ale albo coś mi nie wychodzi. Jeżeli podaję liczbę to zapętla się cały czas do jednej linii kodu abym podał długość uciętego profilu, albo wychodzi mi z programu.

Kopiuj
while True:
		profile = []
		print('\nWpisanie "quit" spowoduje wyłączenie programu')
		try:
			lenght = int(input('Podaj długość uciętego profilu w [mm]: '))
			break
		except ValueError:
			print("Opps! To nie jest liczba. Spróbój jeszcze raz...") 
Spearhead
  • Rejestracja:prawie 6 lat
  • Ostatnio:około 6 godzin
  • Postów:1002
1

Najprościej będzie wstawić continue i zresetować całą iterację pętli. Alternatywnie musisz w obu przypadkach wczytywania danych zawrzeć je w dodatkowej, wewnętrznej pętli while, która będzie się kręcić, dopóki nie wyjdziesz lub podasz wartości, która ma sens, w rodzaju:

Kopiuj
def section_dec():
    # ...
    while True:
        # ...
        while True:
            input_line = input('...')
            if input_line == 'quit':
                return
            try:
                length = int(input_line)
            except ValueError as e:
                continue
            break
        print(length)
        # ...

To obsługuje 3 przypadki

  • wpiszesz quit - wychodzi
  • wpiszesz liczbę - przechodzi dalej z nią
  • wpiszesz cokolwiek innego - pyta ponownie
siloam
  • Rejestracja:prawie 8 lat
  • Ostatnio:prawie 2 lata
  • Postów:99
0

Spójrz na wskazówki od Spearhead. Piszesz, że skończyłeś rozdział na funkcjach, a w Twoim kodzie nie ma ani jednej.


L8
  • Rejestracja:ponad 4 lata
  • Ostatnio:prawie 2 lata
  • Postów:33
0

@Spearhead: bardzo Ci dziękuję za poświęcony czas :) z całą pewnością te kilka postów nieoczekiwanie zaowocowało nabyciem nowej wiedzy.
Dla zainteresowanych try - exception jest fajnie wytłumaczone pod tym linkiem link.

Co do samego programu wklejam wersję finalną, pozwoliłem sobie dodać komentarze do bloku try-excep z opisem co robi poszczególna linijka:

Kopiuj
def section_dec():
	'''Funkcja mająca na celu utworzenie listy z odcinkami pociętego profilu'''	
	#Wpisanie długość odcinka oraz ile razy ma wystąpić na liście
	profile_dim = []

	while True:
		profile = []
		print('\nWpisanie "quit" spowoduje wyłączenie programu')

		while True:

			length =input('Podaj długość uciętego profilu w [mm]: ')
			if length == 'quit':
				return #Jeżeli jest quit zamyka funkcję section_dec() i wstawia wartość None
			try: 
				length = int(length) #Jeżeli zdaje test przechodzi do break i zamyka pętle. 
			except ValueError as e:
				print(f'Upss.. Podana wartość nie jest liczbą. Spróbuj jeszcze raz \n{e}')
				continue #Jeżeli jest błąd wyświetla komunikat i continue pomija pozostałą część kodu i rozpoczyna nową iterację wewnątrz pętli. 
			break
			
		while True:
			
			multiply = input(f'Ile sztuk {length} wykonać?: ')
			if multiply == 'quit':
				return
			try: 
				multiply = int(multiply)
			except ValueError as e:
				print(f'Upss.. Podana wartość nie jest liczbą. Spróbuj jeszcze raz \n{e}')
				continue
			break
		
		#Dodanie do listy oraz zwielokratniania elementów listy 
		profile.append(length)
		profile = profile*multiply
		print(profile)

			profile_dim.extend(profile)

		ending = input('Czy zakończyć dodawanie elementó do listy (wpisz "tak")').lower()
		
		if ending == 'tak':
			break
		
	return profile_dim

section = section_dec()
print(f'lista wszystkich przyciętych prfili: \n\t{section}')
AF
  • Rejestracja:prawie 7 lat
  • Ostatnio:około 11 godzin
  • Postów:172
0

Zauważ, że masz powtórzony fragment kodu, który możesz wynieść do osobnej funkcji:

Kopiuj
        while True:

            length =input('Podaj długość uciętego profilu w [mm]: ')
            if length == 'quit':
                return #Jeżeli jest quit zamyka funkcję section_dec() i wstawia wartość None
            try: 
                length = int(length) #Jeżeli zdaje test przechodzi do break i zamyka pętle. 
            except ValueError as e:
                print(f'Upss.. Podana wartość nie jest liczbą. Spróbuj jeszcze raz \n{e}')
                continue #Jeżeli jest błąd wyświetla komunikat i continue pomija pozostałą część kodu i rozpoczyna nową iterację wewnątrz pętli. 
            break

        while True:

            multiply = input(f'Ile sztuk {length} wykonać?: ')
            if multiply == 'quit':
                return
            try: 
                multiply = int(multiply)
            except ValueError as e:
                print(f'Upss.. Podana wartość nie jest liczbą. Spróbuj jeszcze raz \n{e}')
                continue
            break

Deklarując:

Kopiuj
def get_number(msg):
        while True:
            number =input(msg)
            if length == 'quit':
                return
            try: 
                number = int(length)
            except ValueError as e:
                print(f'Upss.. Podana wartość nie jest liczbą. Spróbuj jeszcze raz \n{e}')
                continue
            return number

Możesz jej użyć zamiast poprzednich 2 fragmentów:

Kopiuj
length = get_number('Podaj długość uciętego profilu w [mm]: ')
multiply = get_number(f'Ile sztuk {length} wykonać?: ')

Dodatkowo jeżeli get_number zwróci None (po wpisaniu 'quit') powiniśmy wyjść z programu - a obecnie przechodzimy do kolejnych operacji. Np. jak wpiszę quit przy poberaniu length, to następnie będziemy mieli 'Ile sztuk None wykonać?:'.

Tutaj deklarujesz pustą listę:

Kopiuj
profile = []

Następuje to zaraz po while True. Zauważ, że następnie robisz:

Kopiuj
profile.append(length)
profile = profile*multiply

Możesz pominąć deklarację listy na początku i zrobić:

Kopiuj
profile = [length] * multiply

Tutaj nie musisz używać zmiennej:

Kopiuj
        ending = input('Czy zakończyć dodawanie elementó do listy (wpisz "tak")').lower()

        if ending == 'tak':
            break

vs

Kopiuj
if input('Czy zakończyć dodawanie elementó do listy (wpisz "tak")').lower() == 'tak':
    break
AF
  • Rejestracja:prawie 7 lat
  • Ostatnio:około 11 godzin
  • Postów:172
0

I ogólna uwaga co do kodu. Wolę trzymać się tego by funkcja miała jedną odpowiedzialność. W tym przypadku section_dec powinna pobierać odcinki, do tego dodałbym funkcję pobierającą 1 odcinek:

Kopiuj
def section_dec():
    '''Funkcja mająca na celu utworzenie listy z odcinkami pociętego profilu''' 
    #Wpisanie długość odcinka oraz ile razy ma wystąpić na liście
    profile_dim = []

    while True:
        profile_dim.append(get_section())
        if input('Czy zakończyć dodawanie elementó do listy (wpisz "tak")').lower() == 'tak':
            break
    return profile_dim

def get_section():
    length = get_number('Podaj długość uciętego profilu w [mm]: ')
    multiply = get_number(f'Ile sztuk {length} wykonać?: ')
    return [length] * multiply

Plus oczywiście obsługa 'quit'.

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)