From f7110aa12561a8275f5dc8c415041776a2ece07f Mon Sep 17 00:00:00 2001 From: Olli Graf Date: Fri, 19 Jan 2024 10:07:29 +0100 Subject: [PATCH 1/6] Experimentell: Erzeugen des Dockercontainers --- docker/Dockerfile | 22 ++ docker/fib/Dockerfile | 18 ++ docker/fib/app.py | 45 +++ docker/fib/fib_gen.py | 12 + docker/fib/static/css/normalize.css | 427 ++++++++++++++++++++++++++++ docker/fib/static/css/skeleton.css | 418 +++++++++++++++++++++++++++ docker/fib/templates/index.html | 26 ++ docker/pyvenv.cfg | 8 + docker/requirements.txt | 7 + 9 files changed, 983 insertions(+) create mode 100644 docker/Dockerfile create mode 100644 docker/fib/Dockerfile create mode 100644 docker/fib/app.py create mode 100644 docker/fib/fib_gen.py create mode 100644 docker/fib/static/css/normalize.css create mode 100644 docker/fib/static/css/skeleton.css create mode 100644 docker/fib/templates/index.html create mode 100644 docker/pyvenv.cfg create mode 100644 docker/requirements.txt diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..b4019af --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,22 @@ +# Verwenden Sie ein Basis-Image mit Python +FROM python:3.8 + +# Setzen Sie das Arbeitsverzeichnis innerhalb des Containers +WORKDIR /app + +# Kopieren Sie die Anwendungsabhängigkeiten in das Container-Image +COPY requirements.txt . + +# Installieren Sie die Abhängigkeiten +RUN pip install --no-cache-dir -r requirements.txt + +# Geben Sie den Port an, auf dem Ihre Flask-Anwendung ausgeführt wird +EXPOSE 8085 + +# Kopieren Sie den Rest des Codes in das Container-Image +COPY fib/*.py /app/ +COPY fib/static /app/static +COPY fib/templates /app/templates + +# Setzen Sie den Befehl aus, der Ihre Anwendung startet +CMD ["python", "app.py"] diff --git a/docker/fib/Dockerfile b/docker/fib/Dockerfile new file mode 100644 index 0000000..6632736 --- /dev/null +++ b/docker/fib/Dockerfile @@ -0,0 +1,18 @@ +# Verwenden Sie ein Basis-Image mit Python +FROM python:3.8 + +# Setzen Sie das Arbeitsverzeichnis innerhalb des Containers +WORKDIR /app + +# Kopieren Sie die Anwendungsabhängigkeiten in das Container-Image +COPY requirements.txt . +COPY FIB/*.py /app + +# Installieren Sie die Abhängigkeiten +RUN pip install --no-cache-dir -r requirements.txt + +# Kopieren Sie den Rest des Codes in das Container-Image +COPY . . + +# Setzen Sie den Befehl aus, der Ihre Anwendung startet +CMD ["python", "app.py"] diff --git a/docker/fib/app.py b/docker/fib/app.py new file mode 100644 index 0000000..be66980 --- /dev/null +++ b/docker/fib/app.py @@ -0,0 +1,45 @@ +from flask import Flask,render_template,request +from fib_gen import fib_generator +import logging + +logging.basicConfig( format='%(asctime)-15s [%(levelname)s] %(funcName)s: %(message)s', level=logging.DEBUG) +app = Flask(__name__) + +@app.route('/') +def index(): + return render_template('index.html') + +@app.route('/fib',methods=['GET','POST']) +def fib(): + fibg = fib_generator() + result = '' + logging.debug(f'request.method={request.method}') + if request.method == 'POST': + element = request.form['element'] + + logging.debug(f'berechne Element:{element}') + + n= int(element) + #formel= str(n-2) + '+' + str(n-1) + formel = '' # Berechnungsformel initialisieren. + if element != None: + for i in range(n+1): + fib = next(fibg) + if i == n-2: # fib(n-2) zur Berechnungsformel dazu + + formel += str(fib) + if i == n-1: # fib(n-1) mit + Zeichen zur Berechnungsformel dazu + formel += '+' + str(fib) + + logging.debug(f'Fibonacci-Zahl: {fib}') + logging.debug(f'formel={formel}') + result=str(fib) + elif request.method == 'GET': + logging.debug('GET-Request') + return render_template('index.html', result=result,formel=formel) + +if __name__ == '__main__': + app.run(host='0.0.0.0',port=8085, debug=True) + + + diff --git a/docker/fib/fib_gen.py b/docker/fib/fib_gen.py new file mode 100644 index 0000000..d51439a --- /dev/null +++ b/docker/fib/fib_gen.py @@ -0,0 +1,12 @@ +import sys + +def fib_generator(): + a,b = 0,1 + + while True: + yield a + a,b = b, a+b + + + + diff --git a/docker/fib/static/css/normalize.css b/docker/fib/static/css/normalize.css new file mode 100644 index 0000000..81c6f31 --- /dev/null +++ b/docker/fib/static/css/normalize.css @@ -0,0 +1,427 @@ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ + +audio, +canvas, +progress, +video { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9/10. + */ + +img { + border: 0; +} + +/** + * Correct overflow not hidden in IE 9/10/11. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Grouping content + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari. + */ + +figure { + margin: 1em 40px; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +/** + * Contain overflow in all browsers. + */ + +pre { + overflow: auto; +} + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +/* Forms + ========================================================================== */ + +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ + +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ + +button, +input, +optgroup, +select, +textarea { + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ + +button { + overflow: visible; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ + +textarea { + overflow: auto; +} + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ + +optgroup { + font-weight: bold; +} + +/* Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} \ No newline at end of file diff --git a/docker/fib/static/css/skeleton.css b/docker/fib/static/css/skeleton.css new file mode 100644 index 0000000..f28bf6c --- /dev/null +++ b/docker/fib/static/css/skeleton.css @@ -0,0 +1,418 @@ +/* +* Skeleton V2.0.4 +* Copyright 2014, Dave Gamache +* www.getskeleton.com +* Free to use under the MIT license. +* http://www.opensource.org/licenses/mit-license.php +* 12/29/2014 +*/ + + +/* Table of contents +–––––––––––––––––––––––––––––––––––––––––––––––––– +- Grid +- Base Styles +- Typography +- Links +- Buttons +- Forms +- Lists +- Code +- Tables +- Spacing +- Utilities +- Clearing +- Media Queries +*/ + + +/* Grid +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +.container { + position: relative; + width: 100%; + max-width: 960px; + margin: 0 auto; + padding: 0 20px; + box-sizing: border-box; } +.column, +.columns { + width: 100%; + float: left; + box-sizing: border-box; } + +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 85%; + padding: 0; } +} + +/* For devices larger than 550px */ +@media (min-width: 550px) { + .container { + width: 80%; } + .column, + .columns { + margin-left: 4%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } + + .one.column, + .one.columns { width: 4.66666666667%; } + .two.columns { width: 13.3333333333%; } + .three.columns { width: 22%; } + .four.columns { width: 30.6666666667%; } + .five.columns { width: 39.3333333333%; } + .six.columns { width: 48%; } + .seven.columns { width: 56.6666666667%; } + .eight.columns { width: 65.3333333333%; } + .nine.columns { width: 74.0%; } + .ten.columns { width: 82.6666666667%; } + .eleven.columns { width: 91.3333333333%; } + .twelve.columns { width: 100%; margin-left: 0; } + + .one-third.column { width: 30.6666666667%; } + .two-thirds.column { width: 65.3333333333%; } + + .one-half.column { width: 48%; } + + /* Offsets */ + .offset-by-one.column, + .offset-by-one.columns { margin-left: 8.66666666667%; } + .offset-by-two.column, + .offset-by-two.columns { margin-left: 17.3333333333%; } + .offset-by-three.column, + .offset-by-three.columns { margin-left: 26%; } + .offset-by-four.column, + .offset-by-four.columns { margin-left: 34.6666666667%; } + .offset-by-five.column, + .offset-by-five.columns { margin-left: 43.3333333333%; } + .offset-by-six.column, + .offset-by-six.columns { margin-left: 52%; } + .offset-by-seven.column, + .offset-by-seven.columns { margin-left: 60.6666666667%; } + .offset-by-eight.column, + .offset-by-eight.columns { margin-left: 69.3333333333%; } + .offset-by-nine.column, + .offset-by-nine.columns { margin-left: 78.0%; } + .offset-by-ten.column, + .offset-by-ten.columns { margin-left: 86.6666666667%; } + .offset-by-eleven.column, + .offset-by-eleven.columns { margin-left: 95.3333333333%; } + + .offset-by-one-third.column, + .offset-by-one-third.columns { margin-left: 34.6666666667%; } + .offset-by-two-thirds.column, + .offset-by-two-thirds.columns { margin-left: 69.3333333333%; } + + .offset-by-one-half.column, + .offset-by-one-half.columns { margin-left: 52%; } + +} + + +/* Base Styles +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +/* NOTE +html is set to 62.5% so that all the REM measurements throughout Skeleton +are based on 10px sizing. So basically 1.5rem = 15px :) */ +html { + font-size: 62.5%; } +body { + font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */ + line-height: 1.6; + font-weight: 400; + font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; + color: #222; } + + +/* Typography +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: 2rem; + font-weight: 300; } +h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;} +h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; } +h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; } +h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; } +h5 { font-size: 1.8rem; line-height: 1.5; letter-spacing: -.05rem; } +h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; } + +/* Larger than phablet */ +@media (min-width: 550px) { + h1 { font-size: 5.0rem; } + h2 { font-size: 4.2rem; } + h3 { font-size: 3.6rem; } + h4 { font-size: 3.0rem; } + h5 { font-size: 2.4rem; } + h6 { font-size: 1.5rem; } +} + +p { + margin-top: 0; } + + +/* Links +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +a { + color: #1EAEDB; } +a:hover { + color: #0FA0CE; } + + +/* Buttons +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +.button, +button, +input[type="submit"], +input[type="reset"], +input[type="button"] { + display: inline-block; + height: 38px; + padding: 0 30px; + color: #555; + text-align: center; + font-size: 11px; + font-weight: 600; + line-height: 38px; + letter-spacing: .1rem; + text-transform: uppercase; + text-decoration: none; + white-space: nowrap; + background-color: transparent; + border-radius: 4px; + border: 1px solid #bbb; + cursor: pointer; + box-sizing: border-box; } +.button:hover, +button:hover, +input[type="submit"]:hover, +input[type="reset"]:hover, +input[type="button"]:hover, +.button:focus, +button:focus, +input[type="submit"]:focus, +input[type="reset"]:focus, +input[type="button"]:focus { + color: #333; + border-color: #888; + outline: 0; } +.button.button-primary, +button.button-primary, +input[type="submit"].button-primary, +input[type="reset"].button-primary, +input[type="button"].button-primary { + color: #FFF; + background-color: #33C3F0; + border-color: #33C3F0; } +.button.button-primary:hover, +button.button-primary:hover, +input[type="submit"].button-primary:hover, +input[type="reset"].button-primary:hover, +input[type="button"].button-primary:hover, +.button.button-primary:focus, +button.button-primary:focus, +input[type="submit"].button-primary:focus, +input[type="reset"].button-primary:focus, +input[type="button"].button-primary:focus { + color: #FFF; + background-color: #1EAEDB; + border-color: #1EAEDB; } + + +/* Forms +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +input[type="email"], +input[type="number"], +input[type="search"], +input[type="text"], +input[type="tel"], +input[type="url"], +input[type="password"], +textarea, +select { + height: 38px; + padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ + background-color: #fff; + border: 1px solid #D1D1D1; + border-radius: 4px; + box-shadow: none; + box-sizing: border-box; } +/* Removes awkward default styles on some inputs for iOS */ +input[type="email"], +input[type="number"], +input[type="search"], +input[type="text"], +input[type="tel"], +input[type="url"], +input[type="password"], +textarea { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; } +textarea { + min-height: 65px; + padding-top: 6px; + padding-bottom: 6px; } +input[type="email"]:focus, +input[type="number"]:focus, +input[type="search"]:focus, +input[type="text"]:focus, +input[type="tel"]:focus, +input[type="url"]:focus, +input[type="password"]:focus, +textarea:focus, +select:focus { + border: 1px solid #33C3F0; + outline: 0; } +label, +legend { + display: block; + margin-bottom: .5rem; + font-weight: 600; } +fieldset { + padding: 0; + border-width: 0; } +input[type="checkbox"], +input[type="radio"] { + display: inline; } +label > .label-body { + display: inline-block; + margin-left: .5rem; + font-weight: normal; } + + +/* Lists +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +ul { + list-style: circle inside; } +ol { + list-style: decimal inside; } +ol, ul { + padding-left: 0; + margin-top: 0; } +ul ul, +ul ol, +ol ol, +ol ul { + margin: 1.5rem 0 1.5rem 3rem; + font-size: 90%; } +li { + margin-bottom: 1rem; } + + +/* Code +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +code { + padding: .2rem .5rem; + margin: 0 .2rem; + font-size: 90%; + white-space: nowrap; + background: #F1F1F1; + border: 1px solid #E1E1E1; + border-radius: 4px; } +pre > code { + display: block; + padding: 1rem 1.5rem; + white-space: pre; } + + +/* Tables +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +th, +td { + padding: 12px 15px; + text-align: left; + border-bottom: 1px solid #E1E1E1; } +th:first-child, +td:first-child { + padding-left: 0; } +th:last-child, +td:last-child { + padding-right: 0; } + + +/* Spacing +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +button, +.button { + margin-bottom: 1rem; } +input, +textarea, +select, +fieldset { + margin-bottom: 1.5rem; } +pre, +blockquote, +dl, +figure, +table, +p, +ul, +ol, +form { + margin-bottom: 2.5rem; } + + +/* Utilities +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +.u-full-width { + width: 100%; + box-sizing: border-box; } +.u-max-full-width { + max-width: 100%; + box-sizing: border-box; } +.u-pull-right { + float: right; } +.u-pull-left { + float: left; } + + +/* Misc +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +hr { + margin-top: 3rem; + margin-bottom: 3.5rem; + border-width: 0; + border-top: 1px solid #E1E1E1; } + + +/* Clearing +–––––––––––––––––––––––––––––––––––––––––––––––––– */ + +/* Self Clearing Goodness */ +.container:after, +.row:after, +.u-cf { + content: ""; + display: table; + clear: both; } + + +/* Media Queries +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +/* +Note: The best way to structure the use of media queries is to create the queries +near the relevant code. For example, if you wanted to change the styles for buttons +on small devices, paste the mobile query code up in the buttons section and style it +there. +*/ + + +/* Larger than mobile */ +@media (min-width: 400px) {} + +/* Larger than phablet (also point when grid becomes active) */ +@media (min-width: 550px) {} + +/* Larger than tablet */ +@media (min-width: 750px) {} + +/* Larger than desktop */ +@media (min-width: 1000px) {} + +/* Larger than Desktop HD */ +@media (min-width: 1200px) {} diff --git a/docker/fib/templates/index.html b/docker/fib/templates/index.html new file mode 100644 index 0000000..c2c6d49 --- /dev/null +++ b/docker/fib/templates/index.html @@ -0,0 +1,26 @@ + + + + + + + Fibonacci Zahlen berechnen + + + +

Fibonacci Generator

+
+ +
+ +

Formel: {{formel}}

+

Fibonacci-Zahl: {{result}}

+
+ + diff --git a/docker/pyvenv.cfg b/docker/pyvenv.cfg new file mode 100644 index 0000000..b121c6f --- /dev/null +++ b/docker/pyvenv.cfg @@ -0,0 +1,8 @@ +home = /usr/bin +implementation = CPython +version_info = 3.11.2.final.0 +virtualenv = 20.17.1+ds +include-system-site-packages = false +base-prefix = /usr +base-exec-prefix = /usr +base-executable = /usr/bin/python3 diff --git a/docker/requirements.txt b/docker/requirements.txt new file mode 100644 index 0000000..fc55b79 --- /dev/null +++ b/docker/requirements.txt @@ -0,0 +1,7 @@ +blinker==1.7.0 +click==8.1.7 +Flask==3.0.1 +itsdangerous==2.1.2 +Jinja2==3.1.3 +MarkupSafe==2.1.3 +Werkzeug==3.0.1 From dceb2d773077cf3fcc5685b17b1bc8f898d794d4 Mon Sep 17 00:00:00 2001 From: Olli Graf Date: Tue, 20 Feb 2024 07:15:11 +0100 Subject: [PATCH 2/6] first commit --- camera/.gitignore | 3 +++ camera/test-python.jpg | Bin 0 -> 67495 bytes camera/testcam.py | 15 +++++++++++++++ 3 files changed, 18 insertions(+) create mode 100644 camera/.gitignore create mode 100644 camera/test-python.jpg create mode 100644 camera/testcam.py diff --git a/camera/.gitignore b/camera/.gitignore new file mode 100644 index 0000000..c6415d1 --- /dev/null +++ b/camera/.gitignore @@ -0,0 +1,3 @@ +bin +lib + diff --git a/camera/test-python.jpg b/camera/test-python.jpg new file mode 100644 index 0000000000000000000000000000000000000000..620d26f3f3ec7cd2083cccd8830b09cb32af7da8 GIT binary patch literal 67495 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 literal 0 HcmV?d00001 diff --git a/camera/testcam.py b/camera/testcam.py new file mode 100644 index 0000000..d2f75b6 --- /dev/null +++ b/camera/testcam.py @@ -0,0 +1,15 @@ +from picamera2 import Picamera2 +from libcamera import controls +from time import sleep + +picam = Picamera2() + +config = picam.create_preview_configuration() +picam.configure(config) + +picam.start() +picam.set_controls({"AfMode": controls.AfModeEnum.Continuous}) +sleep(2) +picam.capture_file("/tank/cameratests/terri/test-python.jpg") + +picam.close() From 31915dc7d6e4464d3ba322d821b2660e05fda8b9 Mon Sep 17 00:00:00 2001 From: Olli Graf Date: Mon, 4 Mar 2024 09:42:31 +0100 Subject: [PATCH 3/6] erste Vresion pistill.py --- camera/.gitignore | 2 +- camera/pistill.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100755 camera/pistill.py diff --git a/camera/.gitignore b/camera/.gitignore index c6415d1..b91b170 100644 --- a/camera/.gitignore +++ b/camera/.gitignore @@ -1,3 +1,3 @@ bin lib - +*.jpg diff --git a/camera/pistill.py b/camera/pistill.py new file mode 100755 index 0000000..3aa8dfd --- /dev/null +++ b/camera/pistill.py @@ -0,0 +1,35 @@ +#! /usr/bin/python + +from picamera2 import Picamera2 +from libcamera import controls +from time import sleep +import sys + +to_file='' +picam = Picamera2() + +def take_still(filename): + config = picam.create_preview_configuration() + picam.configure(config) + + picam.start() + picam.set_controls({"AfMode": controls.AfModeEnum.Continuous}) + sleep(5) + picam.capture_file(filename) + picam.close() + +def parseArgs(argv): + global to_file + count = 0 + for arg in argv: + if arg == '-o': + to_file = argv[count+1] + + count += 1 + +if __name__ =='__main__': + parseArgs(sys.argv) + print(f'to_file={to_file}') + take_still(to_file) + + From b94e080c9669a418435011d6ad3007a0b20cb5fd Mon Sep 17 00:00:00 2001 From: Olli Graf Date: Sat, 9 Mar 2024 11:26:56 +0100 Subject: [PATCH 4/6] argparse --- argparse/action.py | 26 ++++++++++++++++++++++++++ argparse/help.py | 11 +++++++++++ docker/Dockerfile | 14 +++++++------- docker/fib/Dockerfile | 18 ------------------ 4 files changed, 44 insertions(+), 25 deletions(-) create mode 100755 argparse/action.py create mode 100755 argparse/help.py delete mode 100644 docker/fib/Dockerfile diff --git a/argparse/action.py b/argparse/action.py new file mode 100755 index 0000000..1bfae4f --- /dev/null +++ b/argparse/action.py @@ -0,0 +1,26 @@ +#! /usr/bin/python3 + +import argparse + +def do_test(): + print('do_test()') + +parser = argparse.ArgumentParser(prog='action',description='Demonstration der Action',epilog='Ende der Hilfe') + +parser.add_argument('--update',help='update Hilfe') +parser.add_argument('--dry-run',help='dry-run Hilfe') +parser.add_argument('--verbose','-v', action='count') +parser.add_argument('--true', action='store_true') +parser.add_argument('-append', action='append', nargs=1) +parser.add_argument('--false', action='store_false') +parser.add_argument('--store', action='store') +parser.add_argument('--const', action = 'store_const', const=19) + +parser.add_argument('--delete', action = argparse.BooleanOptionalAction) +#parser.add_argument('--no-delete', action = argparse.BooleanOptionalAction) + + +args=parser.parse_args() +print(f'args={args}') +print(f'verbose={args.verbose}') + diff --git a/argparse/help.py b/argparse/help.py new file mode 100755 index 0000000..77a21cc --- /dev/null +++ b/argparse/help.py @@ -0,0 +1,11 @@ +#! /usr/bin/python3 + +import argparse + +parser = argparse.ArgumentParser(prog='HILFE',description='Demonstration der Hilfeseite',epilog='Ende der Hilfe im Epilog') + +parser.add_argument('--update',help='update Hilfe') +parser.add_argument('--dry-run',help='dry-run Hilfe') + +args=parser.parse_args() + diff --git a/docker/Dockerfile b/docker/Dockerfile index b4019af..2213b1d 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,22 +1,22 @@ -# Verwenden Sie ein Basis-Image mit Python +# Python Basis-Image FROM python:3.8 -# Setzen Sie das Arbeitsverzeichnis innerhalb des Containers +# Arbeitsverzeichnis innerhalb des Containers WORKDIR /app -# Kopieren Sie die Anwendungsabhängigkeiten in das Container-Image +# Anwendungsabhängigkeiten in das Container-Image kopieren COPY requirements.txt . -# Installieren Sie die Abhängigkeiten +# Abhängigkeiten installieren RUN pip install --no-cache-dir -r requirements.txt -# Geben Sie den Port an, auf dem Ihre Flask-Anwendung ausgeführt wird +# Port der Flask-Anwendung EXPOSE 8085 -# Kopieren Sie den Rest des Codes in das Container-Image +# eigenen Code in das Container-Image kopieren COPY fib/*.py /app/ COPY fib/static /app/static COPY fib/templates /app/templates -# Setzen Sie den Befehl aus, der Ihre Anwendung startet +# Befehl, der die Anwendung startet CMD ["python", "app.py"] diff --git a/docker/fib/Dockerfile b/docker/fib/Dockerfile deleted file mode 100644 index 6632736..0000000 --- a/docker/fib/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -# Verwenden Sie ein Basis-Image mit Python -FROM python:3.8 - -# Setzen Sie das Arbeitsverzeichnis innerhalb des Containers -WORKDIR /app - -# Kopieren Sie die Anwendungsabhängigkeiten in das Container-Image -COPY requirements.txt . -COPY FIB/*.py /app - -# Installieren Sie die Abhängigkeiten -RUN pip install --no-cache-dir -r requirements.txt - -# Kopieren Sie den Rest des Codes in das Container-Image -COPY . . - -# Setzen Sie den Befehl aus, der Ihre Anwendung startet -CMD ["python", "app.py"] From 3607e2ef694d18cc67b106fad7382bddbfae546d Mon Sep 17 00:00:00 2001 From: Olli Graf Date: Sun, 16 Jun 2024 14:25:18 +0200 Subject: [PATCH 5/6] teil 26 lambda Funktionen. --- gettattr/name.py | 17 +++++++++++++++++ gettattr/testname.py | 28 ++++++++++++++++++++++++++++ teil26/square.py | 7 +++++++ teil26/square_lambda.py | 5 +++++ 4 files changed, 57 insertions(+) create mode 100644 gettattr/name.py create mode 100644 gettattr/testname.py create mode 100644 teil26/square.py create mode 100644 teil26/square_lambda.py diff --git a/gettattr/name.py b/gettattr/name.py new file mode 100644 index 0000000..6c5987b --- /dev/null +++ b/gettattr/name.py @@ -0,0 +1,17 @@ + +class Name: + def __init__(self,vorname,name): + self.vorname = vorname + self.name = name + + def __getattr__(self,attr): + if attr == 'fullname': + return self.vorname + ' ' + self.name + elif attr == 'sortname': + return self.name + ',' + self.vorname + else: + raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{attr}'") + + + + diff --git a/gettattr/testname.py b/gettattr/testname.py new file mode 100644 index 0000000..74f3653 --- /dev/null +++ b/gettattr/testname.py @@ -0,0 +1,28 @@ +import unittest +import logging +from name import Name + +__LOGLEVEL__ = logging.DEBUG + +logging.basicConfig( format='%(asctime)-15s [%(levelname)s] %(funcName)s: %(message)s', level=__LOGLEVEL__) + +class TestName(unittest.TestCase): + + def setUp(self): + logging.debug('setting up test') + self.name = Name('Homer', 'Simpson') + + def test_getattr(self): + fullname = self.name.fullname + sortname = self.name.sortname + + + self.assertEqual('Homer Simpson', fullname) + self.assertEqual('Simpson,Homer', sortname) + + +if __name__ == '__main__': + logging.debug('Test startet.') + unittest.main() + + diff --git a/teil26/square.py b/teil26/square.py new file mode 100644 index 0000000..4f1589c --- /dev/null +++ b/teil26/square.py @@ -0,0 +1,7 @@ + + +def square(x): + return x** 2 + +sq5 = square(5) +print(f'{sq5}') diff --git a/teil26/square_lambda.py b/teil26/square_lambda.py new file mode 100644 index 0000000..6538a9d --- /dev/null +++ b/teil26/square_lambda.py @@ -0,0 +1,5 @@ + + + +square = lambda x: x** 2 +print(f'{square(5)}') From 432e73375a570bd10344a6635cdbe823cbb4c8cd Mon Sep 17 00:00:00 2001 From: Olli Graf Date: Sun, 16 Jun 2024 14:32:09 +0200 Subject: [PATCH 6/6] Readme.md aktualisiert. --- Readme.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 81afe68..0ea1707 100644 --- a/Readme.md +++ b/Readme.md @@ -22,5 +22,13 @@ CC-BY-SA Olli Graf |15 | GPIO| |16 | Testing| |17 | Datenbank| -|17 | Generatoren und list comprehension| +|18 | Generatoren und list comprehension| +|19 | flask| +|20 | virtuelle Umgebungen| +|21 | Interrupts & Signale| +|22 | NumPy| +|23 | MatPlotLib| +|24 | match| +|25 | reguläre Ausdrücke| +|26 | lambda Funktionen|