|
3D Rendering Techniques and Algorithms
|
Multi-threading, Getting on the Same 'Platform', and Adding some New GeometryThe first three assignments were pretty strenuous, but have given us a clear appreciation for three major parts of 3D realistic image synthesis. In assignment 1, we focused on determining what we saw at a pixel; in assignment 2, on what it should look like; and in assignment 3, on adding reflection and refraction. In this assignment, we take one step forward - looking at multi-threading with out current renderer; and one step back - getting on the same page in terms of the rendering 'platform' we have for future work in the class. By the same platform, I mean that we have articulated the problem in a common way to facilitate the explorations we do for the rest of this course. Specifically - we are all using the same interfaces on dynamically loaded objects so we can easily extend all aspects of our renderer simply by writing new objects that use those interfaces. The assignment for this week has several parts:
Deliverables for this Week
Multi-threadingThe deal with multi-threading is that the environment is static during the rendering of the frame (image), so, we should be able to do all image computations (intersecting objects, ray geometry, color computations) simultaneously on different threads. One way to do this is to dedicate a rendering thread-per-processor (and almost every current CPU is multi-core). More threads than this would slow down rendering as your threads would be competing for CPU. Thus, if there are 4 processors, the image computation should take about a quarter of the time; and if there are 8 processors, about an eighth of the time. You might ask about competition with other processes on the computer. I find my computer is using very little CPU most of the time, so this is not really an issue.So, how do we use a thread per processor within the assignment 3 program? There are many approaches one could take. I find that thinking of computing the color for a pixel as a unit of work is quite natural and all I need to do is create a pixel color computation class that can run in a thread. The Pixel Rendering Class The pixel rendering class looks something like this: class RenderPixel implements Runnable { private Assignment4 m_parent; private int m_nX; private int m_nY; private Line3f m_ray = new Line3f(); private RayIntersection m_intersection = null; RenderPixel(final Assignment4 parent) { m_parent = parent; } public void run() { // render pixels while there are pixels to render while (m_parent.dispatchPixel(this)) { m_intersection = new RayIntersection(); RGBf rgb = m_parent.getPixelColor(m_ray, m_intersection, m_parent.m_lights, m_parent.m_geometry, null, m_parent.m_rgbBkg, 5, 15); m_parent.setPixel(m_nX, m_nY, new Color(rgb.r, rgb.g, rgb.b)); } // let the main thread know we are done synchronized (m_parent.m_threadLock) { m_parent.m_threadCt--; if (m_parent.m_threadCt <= 0) { // this is the last thread still running - the image is // done - release the main thread m_parent.m_threadLock.notify(); } } } } The class must implement Runnable so it can be run by a thread. The member variables for the class contain the location of the pixel, the ray for the pixel and the ray intersection. The information for a pixel is obtained by alling the dispatchPixel method on the parent class, and once the pixel color it computed, it is set by calling the setPixel method of the parent class. Note that when there are no more pixels, the thread will do a little cleanup with the parent. Starting the Rendering Threads Within the RenderScene method, we replace the pixel rendering loop with a loop that starts the pixel rendering threads: // now start the threads final int nProcessors = Runtime.getRuntime().availableProcessors(); System.out.println("Starting " + nProcessors + " rendering threads on " + nProcessors + " processors"); // The deal here is we start the threads and keep a count of the running threads. This count is // protected by the thread lock. Once the threads are started, they run till there are no // more pixels, acquire the lock, and decrement the thread count. If the count drops to 0, then // the last thread (the one that dropped the count to 0) notifies the thread lock so this thread // catch (exit the redraw function. // // This thread (the one we are in right now) needs to stop here because we lose the gc after it // returns. There are alternate ways to implement this -- this thread could also be computung pixels. // I find it hard (as in needlessly confusing - especially when reviewing code later) to implement the // multiple use for this thread, so I just block this thread while the rendering threads do their stuff. synchronized (m_threadLock) { m_threadCt = 0; for (int iThread = 0; iThread < nProcessors; iThread++) { m_threadCt++; new Thread(new RenderPixel(this)).start(); } // wait for the threads to complete rendering the image. try { m_threadLock.wait(); } catch (final Throwable t) { // the wait was interrupted, probably because the window closed } } In this example each thread starts rendering pixels when it is created. After all rendering threads are created, the main thread waits until the last rendering thread finishes. Note that a rendering thread count is incremented for each thread that is started. In the RenderPixel.run method, when there are nom more pixels the thread count is decremented; and when it drops to 0 the main thread is notified so it can continue. Dispatching Pixels Within the Assignment45 class and RenderScene method, the screen parameters are made global so they can be referenced by the pixel dispatcher. The pixel dispatcher method looks like: synchronized boolean dispatchPixel(final RenderPixel renderThread) { // this function is synchronized because we want to limit the access to the current pixel position to a single // thread. The thread comes in, pixel positions are computed and the pixel indices incremented and then // the function returns. while (m_nYcur < m_nYmax) { try { // setup the ray and intersection for this pixel final Point3f ptPixel = new Point3f(); ptPixel.setValue(m_ptTargetUL). addVector(m_vSide.cloneVector3f().scale((float) (m_nXcur - m_nXmin) * m_fIncX)). addVector(m_vUp.cloneVector3f().scale((float) (m_nYcur - m_nYmin) * m_fIncY)); renderThread.m_ray.setValue(m_ptEye, ptPixel); renderThread.m_nX = m_nXcur; renderThread.m_nY = m_nYcur; } catch (final Throwable t) { // something bad happened - color code this pixel yellow t.printStackTrace(); setPixel(m_nXcur, m_nYcur, Color.YELLOW); } m_nXcur++; if (m_nXcur >= m_nXmax) { m_nXcur = m_nXmin; m_nYcur++; } return true; } System.out.println("no more pixels for this thread: " + renderThread.toString()); return false; } Note that the dispatch looks very much like the previous loop through pixels, except the increment is triggered by a call to the dispatcher. Collecting Colors into the Image This is pretty simple, once the RenderPixel has determined a color for the pixel, it calls this method to set the color for the pixel. Setting the color looks something like this: void setPixel(final int nX, final int nY, final Color clr) { // this function is synchronized on m_gc so access to the gc is thread safe synchronized (m_gc) { m_bi.setRGB(nX, nY, clr.getRGB()); m_gc.setColor(clr); m_gc.drawRect(nX, nY, 1, 1); } } Note the synchronization on the graphics context so that only one thread can be setting the color at any time. Performance I'm running on an older iMac 3.4 GHz Intel Core i7, 4 core hyper-threaded (8 simultaneous threads). Running Assignment3b to generate the test image took on average 916ms. Rendering this with 8 threads, I would expect a rendering time of 115ms. When I did render with 8 threads the average rendering time was 633ms. I tried this again at full-screen resolution and the average fame times were 4558ms and 6539ms for multi-thread and single thread respectively. The multi-threaded performance was much worse than expected, very disappointing - reducing rendering time to 69% of single threaded rendering time instead of the expected 12.5% Turns out this disappointment is largely related to Java memory allocation and garbage collection - and gets far worse for complex high-resolution images with lots of transparency and reflection. The short explanation is that Java completely manages memory and does not put method-local objects on the stack. Rendering uses a lot of method-local temporary objects; and each time one is created, it synchronizes the memory allocator between all of the threads. Thus, the threads are spending most of their time waiting for the memory allocator to become available rather than on the rendering task at hand. For a detailed discussion of this see multi-threading. Getting on a Common PlatformUp to now you have been writing your own ray-tracing platform, let's get on a common and tested platform so you can start to focus on the interesting extensions in an extensible environment. By a common platform, I mean that we have articulated the problem in a common way to facilitate the explorations we do for the rest of this course. Specifically - we are all using the same interfaces on dynamically loaded objects so we can easily extend all aspects of our renderer simply by writing new objects that use those interfaces. Everything that you have written up to this point exists in the ray tracing library. Additionally, the library includes loading the scene to be rendered from an XML file (in vogue at the time, I would use JSON if I were doing this again) - but these common formatting fads are somewhat irrelevant if you know what exactly you want to represent, see . Run the framework with the environments I supplied just to get familiar with things. Write a couple new .xml environments and submit them. Yes, we are working with a very limited set of geometries and cameras -- we'll fix that in the next couple weeks. Adding a New Geometry or Test EnvironmentThese were the new additions from the 2004 class - for your class, pick others such as spline surfaces, fractals, torus, superquadric, .obj files, other procedurally generated objects (geodesic sphere, Stickley chair or table), etc.
|


Issue 6582:
Removing style sheets dynamically breaks CSS panel
Removing all style sheets
Steps to reproduce
- Open Firebug
- Switch to the CSS panel
- Click this button to remove all stylesheets
- The Location button as well as the Edit button should be hidden (or deactivated)
- The CSS panel should show an info that there are no style sheets inside the page


Professional Resume
Environmental sciences professional experienced in field operations, team leadership, and technical writing. Proficient with geospatial technologies, geophysical field operations, and environmental remediation projects. Professional interests include geospatial analysis, Python scripting, remote sensing, and GIS web application development.
Graduated from the University of Montana with a Bachelor of Science degree in geology in 2009. Completed the University of Denver GIS Certificate program in August 2014, and will graduate from the University of Denver in 2015 with a Master of Science degree in GIS.


Copyright (c) 2003-2004 by The BioBike Team (contact Jeff Shrager for more information)
There are a huge number of biological knowledge and data bases. Some, like TAIR, are dedicated to collecting everything about a single organism, and some, like KEGG or the NCBI, are dedicated to gathering knowledge about a broad range of organisms. Although these are generally useful and useable for the limited set of explorations that they are preprogrammed to do, few have "open functionality." Open functionality is what programming languages have: You can write any program you want (given some persistence and know-how). Open functionality is important for computational biology because biology is a living science; Biologists (and computational biologists) are always thinking up new questions that they would like answered, but which are not yet addresed by existing data and knowledge bases. Even if the data or knowledge is already easily available, it usually takes a skilled programmer, and significant effort, to implement a new computation. In part this is just the time required for engineering, but also when one is putting together your own algorithms, one has to get together all the data, reformat it to work with one's program, and install a bunch of tools, not to mention having to know some arcane programming language! As a result, nearly every lab depends upon software engineers, who are usually not biologists, and who spend huge amounts of time putting together programs to answer specific biological questions. As a result, although biologists are swimming in data, we usually need programmers in order to ask novel questions of it.
BioBike is an approach to reducing the distance between biologists and biocomputation by providing an integrated, on-line, programmable biological knowledge base. In many other scientific areas, students use programmable tools to address complex questions. For example, most undergraduate engineers are trained to use matlab, a matrix-based programming language, as a tool for thought in engineering. But biologists don't have a tool of that sort, and certainly nothing like that is integrated into their training. BioBike is a sort of matlab for biological knowledge, where instead of matrices you have a knowledge base which integrates biological knowledge about particular organisms, their genomes and proteomes, and which provides tools to conveniently operate on that knowledge.
BioBike itself is a very simple, very efficient biology-specific programming language embedded in an integrated biological knowledge-base, and accessible through the web. In the best case, biologists themselves would be able to log into the system and write their own simple programs to ask novel biological questions without the help of (or with very little help from) software engineers.
The CIW/NASA Multi-Cyano BioBike server is a first try at implementing the complete BioBike vision. The knowledge base will eventually contain integrated knowledge about all of the fully sequenced cyanobacterial strains. (Currently we have 13 in the set, and expect to include perhaps 20 in the next year as their sequences are published.) The BioBike Web Listener (hosted at The Carnegie Inst. of Washington) currently implements a nearly complete core of the BioBike language, and has on-board an extensive array of tools for both sequence and microarray data analysis. The knowledge base for each cyanobacterium is linked into a Gene Ontology backbone, and the knowledge base includes the precomputed "cross blast" and orthology of every gene against every other gene in every other organism.
Most importantly, the core BioBike language itself -- including a very efficient compiler to make complex analyses run fast -- is completely implemented, and available for immediate use. Cyanobacteriologists can log onto the server TODAY and begin to ask biological questions about these organisms, including importing and integrating their own data into the system.
We want to make BioBike as simple and flexible a tool for working with biological knowledge as Excel is for working with tables. Even beyond this, we are trying to make BioBike into a complete Knowledge Operating System; Whereas Unix and Windows are operating systems for ASCII strings and files, and there are operating systems for tables (such as Oracle), we envision BioBike, and its more general spinoffs, as operating systems for knowledge! The current BioBike implementation actually has many of the facilities of an operating system, including an integrated file system and multi-processing, but the representational basis for BioBike is knowledge, not files or tables. To reach the vision of an operating system for knowledge will take more work than our small, mostly volunteeer team has in us, but it's something to strive for.
The BioBike Vision is of biologist-driven open functionality ranging over integrated knowledge and data bases. The CIW/NASA Multi-Cyano server is just the first experimental implementation of this vision. As we interact with more and more biologists and computational biologists, we expect that the vision will grow and evolve.
You can experiment with the demo version of the CIW/NASA Multi-Cyano BioBike server by accessing the BioBike documentation core, and clicking through to the demo server. If you'd like to help us reach the vision, please let Jeff Shrager (jshrager@stanford.edu), the project director.
The biologists, students, and engineers who have contributed to this project so far include: Jeff Shrager (PI), JP Massar (core engineering lead), Mike Travers (knowledge framework and interface engineering lead), Jeff Elhai, Julian Brooke, Devaki Bhaya, Arthur Grossman, Bob Haxo, Monica Jain, Ashvin Kumar, Pat Langley, Andrew Pohorille, Marc Santoro, Karl Schweighofer, Dan Siroker, Colin Smith, Serdar Uckun, and Sumudu Watugala.
Thanks to Franz Inc. and LispWorks for contributions supporting both BioLisp and the BioBike server, which runs on Franz's ACL engine and AllegroServe.
This work was supported, in part, by NASA's program in Astrobiology and Fundamental Biology through a Biological Science Research Program grant.


2016 monthly gross income for top films released in 2016
Focus Features Pictures had steady year with equally profitable films for most of the year.
In September there was a suge in profit with teh most films released during that time.
Highest Grossing Month for the Studio: April, $28.0 Million
Lowest Grossing Month for the Studio: September, $27.6 Million
Average Grossing Month for the Studio: $27.8 Million
Highest Grossing Individual Film: Coraline, $ 62.0 Million
Average Gross For Film: $ 4.7 Million


My name is Andrew Au Yeung, I am a Senior at Stony Brook University pursuing a Bachelor of Science in Computer Science (CS). Who am I? I am Web Developer by title, but at heart I am just a person who loves technology. This is why I am studying CS.


Interested in working together? Please leave me a message via the form below and I will get back to you as soon as possible.


Volunteer With Us
Volunteering for Meals on Wheels is a great way to make a huge impact in a short amount of time. By delivering meals you bring nutritious food and a friendly visit to eight to 10 seniors and people with disabilities in your community. Anyone can deliver meals, and it’s a great volunteer opportunity for families and teams of employees, as well. Sign up today and find out how easy and rewarding it is to bring nutrition and independence to your neighbors!
Last year our volunteers made an amazing impact. What will you do this year?
Individual & Small Group Volunteers
Our Service Area
This is a placeholder for the map of service area locations.


Contact Information
If any further information is required, we may be contacted at our help desk:
7381095922 or<PHONE_NUMBER>
You can also mail us at students.organisers@gmail.com


Multiplication table
Choose a number in the selector to see its
multiplication table
till the
index 10
.
Choose a number
2
3
4
5
6
7
8
9
10


Upset over formation of BJP govt in Maharashtra, man attempts suicide
Devendra Fadnavis took oath early on Saturday morning for the second consecutive term as the state chief minister.
by ANIYavatmal: A 45-year-old Shiv Sena supporter allegedly attempted suicide here apparently upset over the formation of Bharatiya Janata Party (BJP) government in the state.
Police said Ramesh Balu Jadhav was in an inebriated condition and could have taken the step under the influence of alcohol.
This incident happened in Digras city of Yavatmal district on Saturday. Jadhav, a resident of Washim district of the state was visiting Digras when he heard the news about the formation of BJP government and allegedly slashed his wrist with a blade.
"The person (Jadhav) was intoxicated. Our personnel took him to a hospital from where he was discharged within 10 minutes. Jadhav did not injure himself over the formation of the BJP government in the state," said Sonaji Amle, Police Inspector, Digras.
After prolonged uncertainty over the government formation that lasted for nearly a month, Devendra Fadnavis took oath early on Saturday morning for the second consecutive term as the state chief minister, while Ajit Pawar was sworn-in as his deputy chief minister.
Catch the latest news, live coverage and in-depth analyses from India and World. Follow us on Facebook and Twitter.


Bergamot and bay gin recipe
by Xanthe ClayFlavouring your own gin is easy and, done right, delicious. Kate Hawkings, the drinks expert and author of Aperitif (Quadrille, £16.99) suggested this combination – she uses Beefeater gin but any fairly mild one will do.
Bergamots, the aromatic citrus that gives Earl Grey tea its perfumed flavour, are occasionally available at this time of year from greengrocers. Natoora is selling them via Ocado and Abel & Cole stocks them too. Failing that, use grapefruit and a strip of orange (ideally Seville orange if you find an early one) instead.
Prep time: 15 minutes, plus 1 week macerating
MAKES
One 75ml bottle
INGREDIENTS
- 1 bergamot, or a small grapefruit, and an orange, ideally Seville
- 1 x 75ml bottle of gin
- 2 fresh bay leaves
- Sugar syrup, to taste
METHOD
- Scrub the fruit and peel off the zest in strips using a potato peeler (you’ll only need one strip from the orange).  Replace the cap and leave for a week or so before tasting to see if it’s ready – it might need longer maceration.
- When the flavour suits you, decant the gin out of the bottle and into a fresh bottle, leaving behind the zest and bay leaves. Taste it and add sugar syrup if you like.


--- layout: post title: New Jersey Marathon Training Run card-image: https://user-images.githubusercontent.com/46349226/55626691-2f239b00-577a-11e9-889b-f3720b19a53a.jpg post-image: https://user-images.githubusercontent.com/46349226/55627474-3f3c7a00-577c-11e9-90f5-b45888756fc1.jpg ---
Date Time: 3/30/2019 7:00/8:00AM
Meet up: The Corner Cafe and Bistro
10 Centennial Dr. Long Branch, NJ 07740
由新马官兔负责人Otto和他的团队免费提供连续5周的训练非常成功和热闹，参加者受益良多。接下来还有兩个周末的训练，本周末安排在周六3/30，欢迎大家继续参加！
本周的训练之后，东奔西跑群还特别为大家安排了在附近的Franklin Lake Park的跑后野餐会，并提供食物和饮料，给新州附近华人跑友们提供互相认识和交流切磋的机会。
MOCA感谢东奔西跑和其他跑团的大力支持，3月30号星期六的训练也将作为MOCA Spike 150的第二次活动-NJ Marathon Training Run隆重推出！届时MOCA公益团队将分享Spike 150的详细信息，尤其是NJM的跑者如何参与并支持Spike 150的活动，欢迎大家踊跃报名参加这次训练！
MOCA Spike 150: Running Forward With Our Stories！在美国跨洲铁路建成完工150周年之际推出，旨在宣传纪念华工的贡献，凝聚全美各地的华人跑团跑者，一起用奔跑的脚步讲述我们自己的故事，并为MOCA募款，建设保存和展示在美华人历史的永久馆址，使这部分历史拥有屬於自己的家！
The Pace Team Coordinator for NJM, Otto Lam, and his team will provide a free 5-week training. Training runs will start at 7AM (Full Marathon) and 8AM (Half Marathon) at Corner Cafe & Bistro, 10 Centennial Dr., Long Branch, NJ 07740. We had great runs for the first two weeks with many participants.
There will be a picnic gathering right after the training that day in the nearby park, Franklin Lake Park from 10:30-12:30, so that the Chinese runners from NJ can get to know each other and socialize. For the GPS, you can use the address: 21 Lakeview Ave, West Long Branch, NJ 07764. All runners are welcome to join this fantastic event; we are going to have a great time!
Training 训练：
7AM/8AM Address：
The Corner Cafe and Bistro
10 Centennial Dr. Long Branch, NJ 07740
Full (18 miles): 7AM
https://routes.rungoapp.com/route/aBOSfqdLoY
Half (10 miles): 8AM
https://routes.rungoapp.com/route/FqHe62s211
Picnic 野餐：
Franklin Lake Park
GPS address:
21 Lakeview Ave, West Long Branch, NJ 07764。
时间: 10:30am-12:30pm


New Game
Settings
{{currentQuestion}}
I Know This
Skip
Correct:
{{score.correct}}
Skipped:
{{score.skipped}}
Time Remaining:
{{timeRemaining}}
{{s}}
Close
Game Time:
Custom Text:
Set Custom Text


Ever since I started working on Marvin.js, it has been a goal to create an AI that was capable of generating human readable (and understandable) text. This is the result of that project. It took some time, but here it is! I am quite sure
there are better, faster, and easier methods, but this was the goal and it turned out better than I expected.
Why I made it
It has always fascinated me how computers would replicate human language. Years ago I thought they might just program the grammar of a language into the computer. But, as I was working on Marvin.js, I decided I wanted to know. So, I searched
on the internet and, eventually, found a way how it could be done.
How it works
The network trains by first converting all the characters from the input text to indeces from a character list, since the network can only accept a numerical input. Then, the network cycles through every character and it looks at a certain amount of characters before it. The (indeces of the) characters before the current character are the input for the Neural Network, while the desired output is the current character. The network then predicts what character should be next. The result is compared to the desired result and the network is altered accordingly. It then cycles to the next character and repeats the process. It does this until the entire input text has
been trained. It does this cycle thousands of times, which can take a long time. When network has cycled enough times, the network is able to recreate the input text. And, if the input text was sufficiently large, it can generate unique sentences that weren't in the original file. Also, it learns our grammar: capital letters, periods, commas, etc.
Can I try it?
The software is still in development. Though, there already is an early version that is capable of learning to generate text. You can visit the GitHub repository and it's listed under "examples".


Press n or j to go to the next uncovered block, b, p or k for the previous block.
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| useFetchFromFirstPage.ts |
|
33.33% | 5/15 | 50% | 1/2 | 66.67% | 2/3 | 33.33% | 5/15 |
| useNews.ts |
|
72.73% | 32/44 | 61.9% | 13/21 | 33.33% | 4/12 | 77.5% | 31/40 |
| usePaginateArticles.ts |
|
45.83% | 11/24 | 50% | 5/10 | 60% | 3/5 | 50% | 11/22 |
| useRefreshArticles.ts |
|
26.67% | 4/15 | 25% | 1/4 | 50% | 2/4 | 28.57% | 4/14 |


Drop DMN table from your desktop or
create a new table
to get started.
Ooops, we could not display the DMN table.
cause of the problem
download
DMN table


Your Savings, Your Earnings
Search
Toggle navigation
Home
Dashboard
Monitoring
Diagnostic
CFD Simulation
AI Optimization
Settings
Profile
User Account
Log Out
Welcome:
Admin
Simulation Control Parameter Setting
1. Change the mode to manual Mode
2. Specify a
Set Point Value
under the Set Point Column
3. Click
Start Simulation
Button
Name
Value
Set Point
Mode
Auto
Manual
Auto
Manual
Auto
Manual
Auto
Manual
Auto
Manual
Auto
Manual
Commit Controls
Start Simulation
Simulation Environment
Model View
Heat View
Simulation Result
System Information:
Data Center Name
: XYZ Super Computer Data Center
Data Center Location
: 1 ABC Road, Singapore 202356
IT Capacity
: 800 kWh
Cooling Capacity
: 800 kWh
Simulation Result:
PUE Reduction
: 2%
Over-Heating
: No
IT Saving
: k$ 10
Cooling Saving
: k$ 231
Top View
Side View
Floor View


The Title
The subtitle
Create a post today
Sign up
Blog
Home
Profile
Subscriptions
Mine
About
Login
Sign up
Suggestions
Trending
Subscriptions
My Own
«
1
2
3
4
5
»


Site Name
The site name must match the name on the site's business licence, if you have one.
Provide this site's name.
{{ doingBusinessAsName }}
Required
Site ID
Provide the site's
ID{{ isCommunityPharmacy() ? '. For example, BC00000XXX.' :
' or PEC Code. This is a 3-letter code. For example, JZY'
}}
Site ID
Required
Must be a 3-letter code
Must be in format BC00000XXX
Site ID has already been used by another site
This is a new pharmacy, and we have a Site ID.
This is a new pharmacy, and we don't have a Site ID.
This site is already operational and submitting PharmaNet transactions, and we have a Site ID.


uadmin.F¶
Back to Customizing Records Page
F is a field.
Structure:
type F struct {
Name string
DisplayName string
ColumnName string
Type string
TypeName string
Value interface{}
Help string
Max interface{}
Min interface{}
Format string
DefaultValue string
Required bool
Pattern string
PatternMsg string
Hidden bool
ReadOnly string
Searchable bool
Filter bool
ListDisplay bool
FormDisplay bool
CategoricalFilter bool
Translations []translation
Choices []Choice
IsMethod bool
ErrMsg string
ProgressBar map[float64]string
LimitChoicesTo func(interface{}, *User) []Choice
UploadTo string
Encrypt bool
Approval bool
NewValue interface{}
OldValue interface{}
ChangedBy string
ChangeDate *time.Time
ApprovalAction ApprovalAction
ApprovalDate *time.Time
ApprovalBy string
ApprovalID uint
Stringer bool
}
Parameters:
Name - The name of the field
DisplayName - The name that you want to display in the model. It is an alias name.
ColumnName - The column name of the field
Type - The field type (e.g. file, list, progress_bar)
TypeName - The data type of the field (e.g. string, int, float64)
Value - The value that you want to assign in a field
Help - An instruction given to understand more details about the field or how to assign a value in a field
Max - The maximum value the user can assign. It is applicable for numeric characters.
Min - The minimum value the user can assign. It is applicable for numeric characters.
Format - Implements formatted I/O with functions (e.g. %s - string, %d - Integer)
DefaultValue - A value assigned automatically if you want to add a new record
Required - A field that user must perform the given task(s). It cannot be skipped or left empty.
Pattern - A regular expression
PatternMsg - An error message if the user assigns a value that did not match the requested format
Hidden - A feature to hide the component in the editing section of the form
ReadOnly - A field that cannot be modified
Searchable - A feature that allows the user to search for a field or column name
Filter - A feature that allows the user to filter the record assigned in a model
ListDisplay - A feature that will hide the field in the viewing section of the model if the value returns false
FormDisplay - A feature that will hide the field in the editing section of the model if the value returns false
CategoricalFilter - A feature that allows the user to filter the record assigned in a model in the form of combo box
Translations - For multilingual fields
Choices - A struct for the list of choices
IsMethod - Check if the method should be included in the field list
ErrMsg - An error message displayed beneath the input field
ProgressBar - A feature used to measure the progress of the activity
LimitChoicesTo - A feature used to append the fetched records in the drop down list
UploadTo - A path where to save the uploaded files
Encrypt - A feature used to encrypt the value in the database
Approval - A feature used to set an approval permission in the field
NewValue - A value that you want to replace from the old value
OldValue - A value that was assigned before
ChangedBy - Returns the username who changed the value of the field record
ChangeDate - The date when the value of the field record was changed
ApprovalAction - A selection of approval actions. There are two selections: Approved and Declined.
ApprovalDate - The date when the value of the field record was approved
ApprovalBy - Returns the username who approved the value of the field record
ApprovalID - Returns the user ID who approved the value of the field record
Stringer - A feature that assigns a field as a unique type
There are 2 ways you can do for initialization process using this function: one-by-one and by group.
One-by-one initialization:
func main(){
// Some codes
f := uadmin.F{}
f.Name = "Name"
f.DisplayName = "DisplayName"
f.ColumnName = "column_name"
f.Type = "Type"
f.Value = "Value"
}
By group initialization:
func main(){
// Some codes
f := uadmin.F{
Name: "Name",
DisplayName: "DisplayName",
ColumnName: "name",
Type: "Type",
Value: "Value",
}
}
In the following examples, we will use “by group” initialization process.
Example #1: String Data Type¶
In this example, we will discuss the following:
Change the actual name that is different from the name initialized in the model struct
Assign a value automatically if you are creating a new record
Assign a help note to instruct the user what to do on that field
Set the field as Required
Set a pattern and error message where only letters are acceptable
Hide the field in the form and list
Disable editing in a field
Allows searching and filtering record(s)
Adding an error message tag
Encrypt the value of the name in the database
String Data Type (Links)¶
Suppose you have this field in the Category model that has a primary key of 1 as shown below:
Go to main.go and apply the following codes below:
func main(){
// Some codes
// Field configurations
field := uadmin.F{
Name: "Name",
TypeName: "string", // Data Type
Format: "%s", // String
}
// Model schema configurations
modelschema := uadmin.ModelSchema{
Name: "Category", // Model name
ModelName: "category", // URL
ModelID: 1, // Primary key
Fields: []uadmin.F{field},
}
// Call the field variable assigned in an array
// Fields[0] = field
modelschemafield := modelschema.Fields[0]
// Call the schema of "category" where the field name is "Name"
// modelschema.ModelName = "category"
// modelschemafield.Name = "Name"
category := uadmin.Schema[modelschema.ModelName].FieldByName(modelschemafield.Name)
// Assign the TypeName field value to the Name field in Category model
category.TypeName = modelschemafield.TypeName
// Assign the Format field value to the Name field in Category model
category.Format = modelschemafield.Format
}
Run your application, go to the Category model and click Add New Category button on the top right corner of the screen. As expected, we got the same result.
Name Field in Category Model - DisplayName¶
Now let’s replace the actual field name. In order to do that, declare a value in the DisplayName field inside uadmin.F function then assign that value to the DisplayName field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
DisplayName: "Category Name",
}
// Some codes
// Assign the DisplayName field value to the Name field in Category
// model
category.DisplayName = modelschemafield.DisplayName
}
Run your application and go to Category model. As expected, the name has changed to “CATEGORY NAME”.
Name Field in Category Model - DefaultValue¶
You can also assign a value in the Name field automatically when creating a new record. In order to do that, declare a value in the DefaultValue field inside uadmin.F function then assign that value to the DefaultValue field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
DefaultValue: "Type here",
}
// Some codes
// Assign the DefaultValue field value to the Name field in Category
// model
category.DefaultValue = modelschemafield.DefaultValue
}
Run your application, go to the Category model and click Add New Category button on the top right corner of the screen. As expected, “Type here” value has assigned automatically in the Name field.
Name Field in Category Model - Help¶
Let’s assign a help note in the Name field to instruct the user what to do on that field. In order to do that, declare a value in the Help field inside uadmin.F function then assign that value to the Help field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
Help: "Input a category name for your Todo List.",
}
// Some codes
// Assign the Help field value to the Name field in Category model
category.Help = modelschemafield.Help
}
Run your application, go to the Category model and click Add New Category button on the top right corner of the screen. As expected, the help note was displayed below the input Name field.
Name Field in Category Model - Required¶
Let’s set a feature where the user needs to fill up the Name field. If the value is empty, the user will prompt the user that the value of the Name field should be assigned. In order to do that, declare a value in the Required field inside uadmin.F function then assign that value to the Required field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
Required: true,
}
// Some codes
// Assign the Required field value to the Name field in Category
// model
category.Required = modelschemafield.Required
}
Run your application, go to the Category model and click Add New Category button on the top right corner of the screen. If you notice, there is an asterisk (*) symbol located on the top right after the “Name:”. Let’s leave the Name field value as it is. If you click Save, the system will prompt the user that the Name must be filled out.
Name Field in Category Model - Pattern and PatternMsg¶
Let’s set a feature where the user can assign letters only in the Name field. In order to do that, declare a value in the Required field inside uadmin.F function then assign that value to the Required field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
Pattern: "^[a-zA-Z _]*$",
PatternMsg: "Your input must be a letter.",
}
// Some codes
// Assign the Pattern field value to the Name field in Category model
category.Pattern = modelschemafield.Pattern
// Assign the PatternMsg field value to the Name field in Category
// model
category.PatternMsg = modelschemafield.PatternMsg
}
Run your application, go to the Category model and click Add New Category button on the top right corner of the screen. Let’s assign a numeric value in the Name field. If you click Save, the system will prompt the user the the value of the Name field must assign letters only.
Name Field in Category Model - Searchable¶
Let’s set a feature where the user can search the name in the Category model. In order to do that, declare a value in the Searchable field inside uadmin.F function then assign that value to the Searchable field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
Searchable: true,
}
// Some codes
// Assign the Searchable field value to the Name field in Category model
category.Searchable = modelschemafield.Searchable
}
Run your application and go to the Category model. As expected, there is a search engine at the top of the model form. Suppose you have two records as shown below:
Let’s search “Work” and see what happens.
Name Field in Category Model - Filter and CategoricalFilter¶
Let’s set a feature where the user can filter the name in the Category model. In order to do that, declare a value in the Filter and CategoricalFilter fields inside uadmin.F function then assign that value to those fields in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
Filter: true,
CategoricalFilter: true,
}
// Some codes
// Assign the Filter field value to the Name field in Category model
category.Filter = modelschemafield.Filter
// Assign the CategoricalFilter field value to the Name field in
// Category model
category.CategoricalFilter = modelschemafield.CategoricalFilter
}
Run your application and go to the Category model. As expected, the combo box form highlighted on the right side is the CategoricalFilter to notify the user that the Category Name is the field that will be filtered. Now click the Filter button. Suppose you have two records as shown below:
Assign “Work” in the Category Name. Click Filter button on the bottom right corner of the modal and see what happens.
As expected, the Category record has filtered out where the name contains “Work”.
Name Field in Category Model - ReadOnly¶
Let’s set a feature where the user cannot modify a Name field in the Category model. In order to do that, declare a value in the ReadOnly field inside uadmin.F function then assign that value to the ReadOnly field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
ReadOnly: "true",
}
// Some codes
// Assign the ReadOnly field value to the Name field in Category model
category.ReadOnly = modelschemafield.ReadOnly
}
Run your application, go to the Category model and click Add New Category button on the top right corner of the screen. As expected, the Name field is now Read Only that means the value cannot be modified.
Name Field in Category Model - ErrMsg¶
Let’s set a feature where an error message will be displayed beneath the input Name field. In order to do that, declare a value in the ErrMsg field inside uadmin.F function then assign that value to the ErrMsg field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
ErrMsg: "This field cannot be modified.",
}
// Some codes
// Assign the ErrMsg field value to the Name field in Category model
category.ErrMsg = modelschemafield.ErrMsg
}
Run your application, go to the Category model and click Add New Category button on the top right corner of the screen. As expected, the error message was displayed beneath the input Name field.
Name Field in Category Model - ListDisplay¶
Let’s set a feature that will hide the field or column name in the viewing section of the Category model. In order to do that, declare a value in the ListDisplay field inside uadmin.F function then assign that value to the ListDisplay field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
ListDisplay: false,
}
// Some codes
// Assign the ListDisplay field value to the Name field in Category
// model
category.ListDisplay = modelschemafield.ListDisplay
}
Run your application and go to the Category model. As expected, the Name Field in Category Model is now invisible in the list.
Name Field in Category Model - FormDisplay¶
Let’s set a feature that will hide the field in the editing section of the Category model. In order to do that, declare a value in the FormDisplay field inside uadmin.F function then assign that value to the FormDisplay field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
FormDisplay: false,
}
// Some codes
// Assign the FormDisplay field value to the Name field in Category
// model
category.FormDisplay = modelschemafield.FormDisplay
}
Run your application, go to the Category model and click Add New Category button on the top right corner of the screen. As expected, the Name Field is now invisible in the Category model.
Name Field in Category Model - Encrypt¶
Suppose you have two records as shown below:
Let’s encrypt the value of the Name field in the Category Model. In order to do that, declare a value in the Encrypt field inside uadmin.F function then assign that value to the Encrypt field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
Encrypt: true,
}
// Some codes
// Assign the Encrypt field value to the Name field in Category model
category.Encrypt = modelschemafield.Encrypt
}
Run your application. From your project folder, open uadmin.db with DB Browser for SQLite.
Click on Execute SQL.
Get all records by typing this command: SELECT * FROM categories then click the right arrow icon to execute your SQL command.
As expected, the Name value is encrypted in the database.
Example #2: Progress Bar¶
In this example, we will discuss the following:
Change the actual name that is different from the name initialized in the model struct
Set the type of the input field
Set the color and maximum value in the progress bar
Set the minimum and maximum limit the user can assign in the progress bar
Assign a value automatically if you are creating a new record
Progress Bar (Links)¶
Suppose you have this field in the Todo model that has a primary key of 1 as shown below:
Go to main.go and apply the following codes below:
func main(){
// Some codes
// Field configurations
field := uadmin.F{
Name: "Progress",
TypeName: "float64", // Data Type
Format: "%d", // Integer
}
// Model schema configurations
modelschema := uadmin.ModelSchema{
Name: "Todo", // Model name
ModelName: "todo", // URL
ModelID: 1, // Primary key
Fields: []uadmin.F{field},
}
// Call the field variable assigned in an array
// Fields[0] = field
modelschemafield := modelschema.Fields[0]
// Call the schema of "todo" where the field name is "Progress"
// modelschema.ModelName = "todo"
// modelschemafield.Name = "Progress"
todo := uadmin.Schema[modelschema.ModelName].FieldByName(modelschemafield.Name)
// Assign the TypeName field value to the Progress field in Todo model
todo.TypeName = modelschemafield.TypeName
}
Run your application and go to the Todo model. As expected, we got the same result.
Progress Field in Todo Model - DisplayName¶
Now let’s replace the actual field name. In order to do that, declare a value in the DisplayName field inside uadmin.F function then assign that value to the DisplayName field in the Todo model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
DisplayName: "Current Progress",
}
// Some codes
// Assign the DisplayName field value to the Progress field in Todo
// model
todo.DisplayName = modelschemafield.DisplayName
}
Run your application and go to the Todo model. As expected, the name has changed to “CURRENT PROGRESS”.
Progress Field in Todo Model - Type¶
Let’s convert the input type to the progress bar. In order to do that, declare a value in the Type field inside uadmin.F function then assign that value to the Type field in the Todo model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
Type: "progress_bar",
}
// Some codes
// Assign the Type field value to the Progress field in Todo model
todo.Type = modelschemafield.Type
}
Run your application and go to the Todo model. As expected, the field type has changed from regular to a progress bar. However, the appearance does not look good because we have not assigned the value and color of the progress bar yet.
Progress Field in Todo Model - ProgressBar¶
Let’s assign the value and the color of the progress bar. In order to do that, declare a value in the ProgressBar field inside uadmin.F function then assign that value to the ProgressBar field in the Todo model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
// 100.0 - maximum value
// #07c - blue color
ProgressBar: map[float64]string{100.0: "#07c"},
}
// Some codes
// Assign the ProgressBar field value to the Progress field in Todo
// model
todo.ProgressBar = modelschemafield.ProgressBar
}
Run your application and go to the Todo model. As expected, the appearance of the progress bar is now good enough.
Progress Field in Todo Model - Max and Min¶
Let’s set a limitation where the user can assign a value between the range of 0 and 100. In order to do that, declare a value in the Max and Min fields inside uadmin.F function then assign that value to those fields in the Todo model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
Max: "100",
Min: "0",
}
// Some codes
// Assign the Max field value to the Progress field in Todo model
todo.Max = modelschemafield.Max
// Assign the Min field value to the Progress field in Todo model
todo.Min = modelschemafield.Min
}
Run your application and go to the Todo model. Let’s put a numeric value outside the range of 0 and 100 in the Progress field and see what happens.
Progress Field in Todo Model - DefaultValue¶
You can also assign a value in the Progress field automatically when creating a new record. In order to do that, declare a value in the DefaultValue field inside uadmin.F function then assign that value to the DefaultValue field in the Todo model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
DefaultValue: "50",
}
// Some codes
// Assign the DefaultValue field value to the Progress field in Todo
// model
todo.DefaultValue = modelschemafield.DefaultValue
}
Run your application, go to the Todo model and click Add New Todo button on the top right corner of the screen. As expected, “50” value has assigned automatically in the Progress field.
Example #3: Choices¶
In this example, we will discuss the following:
Build choices
Hide the field in the form and list
Choices (Links)¶
Suppose you have the given source code in friend.go where Nationality is the type of the drop down list:
// Nationality ...
type Nationality int
// Chinese ...
func (Nationality) Chinese() Nationality {
return 1
}
// Filipino ...
func (Nationality) Filipino() Nationality {
return 2
}
// Others ...
func (Nationality) Others() Nationality {
return 3
}
And you have this field in the Friend model that has a primary key of 1 containing three choices which are Chinese, Filipino, and Others as shown below:
Go to main.go and apply the following codes below:
func main(){
// Some codes
// Field configurations
field := uadmin.F{
Name: "Nationality",
Type: "list",
TypeName: "Nationality",
}
// Model schema configurations
modelschema := uadmin.ModelSchema{
Name: "Friend", // Model name
ModelName: "friend", // URL
ModelID: 1, // Primary key
Fields: []uadmin.F{field},
}
// Call the field variable assigned in an array
// Fields[0] = field
modelschemafield := modelschema.Fields[0]
// Call the schema of "friend" where the field name is "Nationality"
// modelschema.ModelName = "friend"
// modelschemafield.Name = "Nationality"
friend := uadmin.Schema[modelschema.ModelName].FieldByName(modelschemafield.Name)
// Assign the Type field value to the Nationality field in Friend model
friend.Type = modelschemafield.Type
// Assign the TypeName field value to the Nationality field in Friend
// model
friend.TypeName = modelschemafield.TypeName
}
Run your application, go to the Friend model and click Add New Friend button on the top right corner of the screen. As expected, we got the same result.
Nationality Field in Friend Model - Choices¶
Let’s build a choice that includes Chinese and Filipino and excludes Others. In order to do that, declare a value in the Choices field inside uadmin.F function then assign that value to the Choices field in the Friend model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
// K is the ID of the choice
// V is the value of the choice
Choices: []uadmin.Choice{
{K: 0, V: " - "},
{K: 1, V: "Chinese"},
{K: 2, V: "Filipino"},
},
}
// Some codes
// Assign the Choices field value to the Nationality field in Friend
// model
friend.Choices = modelschemafield.Choices
}
Run your application, go to the Friend model and click Add New Friend button on the top right corner of the screen. As expected, Chinese and Filipino choices are included in the list.
Nationality Field in Friend Model - ListDisplay¶
Let’s set a feature that will hide the field or column name in the viewing section of the Friend model. In order to do that, declare a value in the ListDisplay field inside uadmin.F function then assign that value to the ListDisplay field in the Friend model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
ListDisplay: false,
}
// Some codes
// Assign the ListDisplay field value to the Nationality field in
// Friend model
friend.ListDisplay = modelschemafield.ListDisplay
}
Run your application and go to the Friend model. As expected, the Nationality Field in the Friend Model is now invisible in the list.
Nationality Field in Friend Model - FormDisplay¶
Let’s set a feature that will hide the field in the editing section of the Friend model. In order to do that, declare a value in the FormDisplay field inside uadmin.F function then assign that value to the FormDisplay field in the Friend model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
FormDisplay: false,
}
// Some codes
// Assign the FormDisplay field value to the Nationality field in
// Friend model
friend.FormDisplay = modelschemafield.FormDisplay
}
Run your application, go to the Friend model and click Add New Friend button on the top right corner of the screen. As expected, the Nationality Field is now invisible in the Friend model.
Example #4: Upload To¶
In this example, we will discuss the following:
Set the type of the input field
Set the field as Required
Set a path where to upload the files
Adding an error message tag
Hide the field in the form and list
Upload To (Links)¶
Suppose you have this field in the Category model that has a primary key of 1 as shown below:
Go to main.go and apply the following codes below:
func main(){
// Some codes
// Field configurations
field := uadmin.F{
Name: "File",
TypeName: "string",
}
// Model schema configurations
modelschema := uadmin.ModelSchema{
Name: "Category", // Model name
ModelName: "category", // URL
ModelID: 1, // Primary key
Fields: []uadmin.F{field},
}
// Call the field variable assigned in an array
// Fields[0] = field
modelschemafield := modelschema.Fields[0]
// Call the schema of "category" where the field name is "File"
// modelschema.ModelName = "category"
// modelschemafield.Name = "File"
category := uadmin.Schema[modelschema.ModelName].FieldByName(modelschemafield.Name)
// Assign the TypeName field value to the File field in Category model
category.TypeName = modelschemafield.TypeName
}
Run your application, go to the Category model and click Add New Category button on the top right corner of the screen. As expected, we got the same result.
File Field in Category Model - Type¶
Let’s convert the input type to the file. In order to do that, declare a value in the Type field inside uadmin.F function then assign that value to the Type field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
Type: "file",
}
// Some codes
// Assign the Type field value to the File field in Category model
category.Type = modelschemafield.Type
}
Run your application and go to the Category model. As expected, the field type has changed from regular to a file input.
File Field in Category Model - Required¶
Let’s set a feature where the user needs to fill up the File field. If the value is empty, the user will prompt the user that the value of the File field should be assigned. In order to do that, declare a value in the Required field inside uadmin.F function then assign that value to the Required field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
Required: true,
}
// Some codes
// Assign the Required field value to the File field in Category model
category.Required = modelschemafield.Required
}
Run your application, go to the Category model and click Add New Category button on the top right corner of the screen. If you notice, there is an asterisk (*) symbol located on the top right after the “File:”. Let’s leave the File field value as it is. If you click Save, nothing will happen until you fill out the File field.
File Field in Category Model - UploadTo¶
Let’s set a feature where the uploaded file will save in the specified path on your project folder. In order to do that, declare a value in the UploadTo field inside uadmin.F function then assign that value to the UploadTo field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
UploadTo: "/media/files/",
}
// Some codes
// Assign the UploadTo field value to the File field in Category model
category.UploadTo = modelschemafield.UploadTo
}
Run your application, go to the Category model and click Add New Category button on the top right corner of the screen. Let’s add a new record that includes the uploaded file from your computer (e.g. Windows Installation.pdf).
Result:
From your project folder, go to /media/files/(generated_folder_name)/. As expected, the “Windows Installation.pdf” file was saved on that path.
File Field in Category Model - ErrMsg¶
Let’s set a feature where an error message will be displayed beneath the input File field. In order to do that, declare a value in the ErrMsg field inside uadmin.F function then assign that value to the ErrMsg field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
ErrMsg: "Invalid format",
}
// Some codes
// Assign the ErrMsg field value to the File field in Category model
category.ErrMsg = modelschemafield.ErrMsg
}
Run your application, go to the Category model and click the existing record that you have. As expected, the error message was displayed beneath the input File field.
File Field in Category Model - ListDisplay¶
Let’s set a feature that will hide the field or column name in the viewing section of the Category model. In order to do that, declare a value in the ListDisplay field inside uadmin.F function then assign that value to the ListDisplay field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
ListDisplay: false,
}
// Some codes
// Assign the ListDisplay field value to the File field in Category
// model
category.ListDisplay = modelschemafield.ListDisplay
}
Run your application and go to the Category model. As expected, the File Field in the Category Model is now invisible in the list.
File Field in Category Model - FormDisplay¶
Let’s set a feature that will hide the field in the editing section of the Category model. In order to do that, declare a value in the FormDisplay field inside uadmin.F function then assign that value to the FormDisplay field in the Category model.
func main(){
// Some codes
// Field configurations
field := uadmin.F{
// Some codes
FormDisplay: false,
}
// Some codes
// Assign the FormDisplay field value to the File field in Category
// model
category.FormDisplay = modelschemafield.FormDisplay
}
Run your application, go to the Category model and click Add New Category button on the top right corner of the screen. As expected, the File Field is now invisible in the Category model.
Example #5: Approval¶
In this example, we will discuss on how to set an approval permission in the field.
Suppose you have “johndoe” account in the User model that is not an admin.
User permissions are set for that user in Approvals and Friends models without an approval access.
And you have the Name field in the Friend model that has a primary key of 1 as shown below:
Go to main.go and apply the following codes below:
func main(){
// Some codes
// Field configurations
field := uadmin.F{
Name: "Name",
TypeName: "string", // Data Type
Format: "%s", // String
Approval: true,
}
// Model schema configurations
modelschema := uadmin.ModelSchema{
Name: "Friend", // Model name
ModelName: "friend", // URL
ModelID: 1, // Primary key
Fields: []uadmin.F{field},
}
// Call the field variable assigned in an array
// Fields[0] = field
modelschemafield := modelschema.Fields[0]
// Call the schema of "friend" where the field name is "Name"
// modelschema.ModelName = "friend"
// modelschemafield.Name = "Name"
friend := uadmin.Schema[modelschema.ModelName].FieldByName(modelschemafield.Name)
// Assign the TypeName field value to the Name field in Friend model
friend.TypeName = modelschemafield.TypeName
// Assign the Format field value to the Name field in Friend model
friend.Format = modelschemafield.Format
// Assign the Approval field value to the Name field in Friend model
friend.Approval = modelschemafield.Approval
}
Run your application and login your account using “johndoe”.
As you can see, only the Approvals and Friends models are accessible in the dashboard. It is based on the user permission that was assigned on that user. Now click on “FRIENDS”.
Click “Add New Friend” to create a new record.
Let’s input the following field for this record.
Result
Based on the result, the name does not show up because we need an approval to someone who has approval access. Now logout johndoe account then login an admin account.
From uAdmin dashboard, go to the Friends model, click the record that you have created, and in the input box of the Name field, there is a yellow warning sign on the left side that means it needs an approval to someone who has approval access. Now click the highlighted area below.
The admin will review the record that was created by a “johndoe” user. If you think his record is satisfactory, choose Approved in Approval Action then click Save and Continue on the bottom right corner of the screen.
It is shown that the one who approved the record is an admin with an approved date. Now click View Record button to see the result.
The input Name field has a checkmark sign that means the record created by “johndoe” was approved.


Weekend Challenge Numero Uno
Employee First Name
Employee Last Name
ID Number
Job Title
Annual Salary
Monthly Expenditures
Employee List
First Name
Last Name
ID Number
Job Title
Annual Salary


Shadow
问题描述 :
There is a great fleet of spaceship in the planet. The fleet has ONE battle-cruiser and several fighters. A fighter can make a sphere magnetic shield which the radiation can’t pass through. When the fleet is in the space, the battle-cruiser and the magnetic shields can make shadows on the ground if the radiation comes.
When the radiation hit the planet, people in Orez will be destroyed except they go into the shadow of the fleet. So we want to know the area of the safety shadow.
To simplify this problem, you can consider that: the ground is an infinity plane, the radiation is parallel light, a fighter is a point, and the battle-cruiser is a 3D convex hull.
输入:
For each case, the first line contains five integers: N, M, Dx, Dy and Dz. N is the number of fighters. M points in/on the battle-cruiser will be given later. The convex hull of these M points is the shape of the battle-cruiser. (Dx, Dy, Dz) is the direction vector of the radiation. Dz is negative.
Each of the next N lines contains four integers Xi, Yi, Zi and Pi , representing a fighter. (Xi, Yi, Zi) is the coordinate of the fighter (also the center of the sphere shield made by the fighter). Pi is the radius of the shield.
Each of the next M lines contains three integers Xi, Yi and Zi. (Xi, Yi Zi) is a point in/on the battle-cruiser.
All the Xi, Yi are in the range of [0, 100]; all the Zi are in the range of [20,100];
0< Pi <= 20; N+M<=500, and the ground is the plane Z=0.
Please note that several fighters may stay at the same position, and a fighter can stay inside or on the cruiser.
The input ends with 0 0 0 0 0.
输出:
For each case, the first line contains five integers: N, M, Dx, Dy and Dz. N is the number of fighters. M points in/on the battle-cruiser will be given later. The convex hull of these M points is the shape of the battle-cruiser. (Dx, Dy, Dz) is the direction vector of the radiation. Dz is negative.
Each of the next N lines contains four integers Xi, Yi, Zi and Pi , representing a fighter. (Xi, Yi, Zi) is the coordinate of the fighter (also the center of the sphere shield made by the fighter). Pi is the radius of the shield.
Each of the next M lines contains three integers Xi, Yi and Zi. (Xi, Yi Zi) is a point in/on the battle-cruiser.
All the Xi, Yi are in the range of [0, 100]; all the Zi are in the range of [20,100];
0< Pi <= 20; N+M<=500, and the ground is the plane Z=0.
Please note that several fighters may stay at the same position, and a fighter can stay inside or on the cruiser.
The input ends with 0 0 0 0 0.
样例输入:
2 4 1 1 -1 25 22 30 14 24 32 27 15 32 40 21 21 30 21 20 21 22 20 30 22 0 0 0 0 0
样例输出:
1539.3185
不是龙，标题已经说了是基因突变的“不明生物”，肯定是共济会和邪恶的小灰人搞的鬼，以此阻止人类觉醒和扬升…
不是龙，标题已经说了是基因突变的“不明生物”，肯定是共济会和邪恶的小灰人搞的鬼，以此阻止人类觉醒和扬升…
我刚果去Google了，真这样。。。
我刚果去Google了，真这样。。。
我刚果去Google了，真这样。。。
我刚果去Google了，真这样。。。
我刚果去Google了，真这样。。。
我刚果去Google了，真这样。。。
我刚果去Google了，真这样。。。
我刚果去Google了，真这样。。。
我刚果去Google了，真这样。。。
我刚果去Google了，真这样。。。
我刚果去Google了，真这样。。。
跟书上的解法不一样，不知道哪个效率要高些
这个是代码高亮功能，那就再换一个颜色
可以用公式。主要为了说明动态规划，如果要打表的话，这种方法也是较简单和高效的
int L[m+1][n+1];这样定义出错，这个在gcc上可以编译通过 在VS上不行 应该改为new 或者vector
这个也是算法导论的习题
失误失误，转载错了。已经改正，抱歉。
为什么暴力求解方法循环到sqrt(n) 就可以了呢
博主，你这个是wordpress哪个主题啊，不错哦~
…. 配图居然是没方向的。。
simple, however efficient. A lot of instances it is difficult to get that a??perfect balancea?? among usability and appearance. I must say that youa??ve done a exceptional task with this. Also, the blog masses quite fast for me on Web explore.
刚开始学，非常好
这张页面太松散拉，重新编辑一下，弄紧凑一点。
多谢提醒，是漏掉了
很好，注释很详细啊


The All Blacks are the most successful sports franchise in history. They have won three World Cups and won more than three-quarters of the matches they have played in their 125-year history, more than any major national sports team. Many New Zealand fans go to rugby matches wondering not whether their team will win, but rather by how much.


FindOpenMP¶
Finds Open Multi-Processing (OpenMP) support.
This module can be used to detect OpenMP support in a compiler. If the compiler supports OpenMP, the flags required to compile with OpenMP support are returned in variables for the different languages. The variables may be empty if the compiler does not need a special flag to support OpenMP.
Variables¶
The module exposes the components C
, CXX
, and Fortran
.
Each of these controls the various languages to search OpenMP support for.
Depending on the enabled components the following variables will be set:
OpenMP_FOUND
- Variable indicating that OpenMP flags for all requested languages have been found. If no components are specified, this is true if OpenMP settings for all enabled languages were detected.
OpenMP_VERSION
- Minimal version of the OpenMP standard detected among the requested languages, or all enabled languages if no components were specified.
This module will set the following variables per language in your
project, where <lang>
is one of C, CXX, or Fortran:
OpenMP_<lang>_FOUND
- Variable indicating if OpenMP support for
<lang>
was detected. OpenMP_<lang>_FLAGS
- OpenMP compiler flags for
<lang>
, separated by spaces.
For linking with OpenMP code written in <lang>
, the following
variables are provided:
OpenMP_<lang>_LIB_NAMES
- ;-list of libraries for OpenMP programs for
<lang>
. OpenMP_<libname>_LIBRARY
- Location of the individual libraries needed for OpenMP support in
<lang>
. OpenMP_<lang>_LIBRARIES
- A list of libraries needed to link with OpenMP code written in
<lang>
.
Additionally, the module provides IMPORTED
targets:
OpenMP::OpenMP_<lang>
- Target for using OpenMP from
<lang>
.
Specifically for Fortran, the module sets the following variables:
OpenMP_Fortran_HAVE_OMPLIB_HEADER
- Boolean indicating if OpenMP is accessible through
omp_lib.h
. OpenMP_Fortran_HAVE_OMPLIB_MODULE
- Boolean indicating if OpenMP is accessible through the
omp_lib
Fortran module.
The module will also try to provide the OpenMP version variables:
OpenMP_<lang>_SPEC_DATE
- Date of the OpenMP specification implemented by the
<lang>
compiler. OpenMP_<lang>_VERSION_MAJOR
- Major version of OpenMP implemented by the
<lang>
compiler. OpenMP_<lang>_VERSION_MINOR
- Minor version of OpenMP implemented by the
<lang>
compiler. OpenMP_<lang>_VERSION
- OpenMP version implemented by the
<lang>
compiler.
The specification date is formatted as given in the OpenMP standard:
yyyymm
where yyyy
and mm
represents the year and month of
the OpenMP specification implemented by the <lang>
compiler.


Menu
Personal data privacy
Login & Sign Up
Sign in or Create a New Account.
I have a Account.
I need a Account.


--- title: CP4IM --- New on our projects page: The CP4IM project (Constraint Programming for Itemset Mining) uses Gecode in data mining applications.


This little blog is dedicated to my final project, in which it will be possible to follow the evolution and the development of the tasks required for the elaboration of the same one. For this you will have several blogs where you can see and read the tasks we talked about previously.
Elastest
TFG project
Motivation
Related
Benefits
Locations
List item


Terms of Reference: Developmental Evaluation
About Mosaik Education
Mosaik Education supports refugees to access higher education through academic guidance and skills programmes that are designed with the refugee community and leverage technology. As a new charity, Mosaik Education is working at the forefront of innovation in refugee education. We are seeking to bring about a systemic change that empowers a community of refugees and civil society to shape and lead education through open resources, technology, participatory design and community leadership.
Today, only 3 percent of eligible refugees have access to higher education, compared to 37 percent of global youth. This limits their potential to become self-reliant, integrate and contribute in their host communities, and to help reconstruct their home country when they return.
Why now
Mosaik Education was registered in 2018. Since then, Mosaik Education has been designing, developing and testing its programmes, which aim to support refugees in overcoming key barriers in accessing higher education. Mosaik has supported over 200 refugees through its programmes in Jordan and Lebanon, funded by Open Society Foundations, UK Aid and the University of East London.
Mosaik Education’s programmes, and the organisation itself, are at a crucial point of development. Internal monitoring, evaluation and learning (MEL) activities (baseline/endline data, feedback surveys, and after action review workshops) have highlighted positive outcomes of Mosaik’s activities, as well as early evidence of intended impact. There has also been a significant increase in interest in Mosaik programmes from organisations across the sector, representing an opportunity to scale our activities up.
The context in which Mosaik Education operates has also changed since the organisation’s establishment. UNHCR has set a target to increase the proportion of refugees accessing university globally to 15% by 2030. Academic research and grey literature published in the past two years has also highlighted needs in other contexts that correspond to Mosaiks guidance and skills programmes.
Whilst Mosaik has a broad strategic vision for achieving scale and maximising impact, this moment presents an opportunity to evaluate Mosaik’s approach in light of learning and contextual changes. Mosaik Education is seeking an external consultant to conduct a Developmental Evaluation to help Mosaik, its funders and other stakeholders identify:
- How effective have Mosaik’s programmes been to date, and what opportunities are there for improvement?; and
- How can Mosaik develop its business model to reach sustainability and scale?
The Developmental Evaluation
The Developmental Evaluation will have two areas of focus: the programmatic part will focus on efficacy and opportunities for improvement in Mosaik’s current programmes. Specifically, this evaluation will focus on activities that are funded by Open Society Foundations in Jordan. These include an academic guidance programme that provides advice and skills on how refugees can access higher education; and an English language programme that uses an experimental ‘Teaching Unplugged’ approach to support refugees’ acquisition of English.
The second area of focus is the business model of the charity and how it should grow in light of contextual developments and the findings from the programmatic part of the evaluation.
The Developmental Evaluation will be able to build on existing internal MEL data, as well as collecting new data by engaging with Mosaik team members and stakeholders. As this is a Developmental Evaluation will also have the opportunity to learn with the team during the final quarter if its current project. to answer the following key questions:
Efficacy and improvement of Mosaik’s programmes
- What has and has not worked out as expected?
- Are there unintended benefits or consequences developing from Mosaik’s programmes?
- How have Mosaik’s programmes been adapted since their design and development? Have these adaptations been successful?
- How should Mosaik’s programmes be adapted going forward?
- What value has partnerships added to the programme? What are principles of good partnerships that could be used in future partnerships and in answering scaling questions below?
Reaching sustainability and scale:
- What business models can Mosaik draw on to ensure sustainability of impact?
- What role do Mosaik’s programmes hold, compared to comparator programmes and organisations within the field of higher education for refugees?
- How can these models support Mosaik maintaining a balance between ‘adaptiveness’ and efficiency whilst achieving scale?
- How might Mosaik test and develop these business models?
Deliverables and timelines
Mosaik is looking for an evaluator to bring their unique approach to the delivery and write-up of this evaluation. There are key outputs that must be delivered:
- A final report covering the key questions outlined above. The report should balance between efficacy and improvement of programming (60%), and future scale and sustainability (40%).
- Two workshops with the Mosaik team: one to establish the developmental evaluation process; and the second to consider adaptations and improvements to its programme.
- A set of key discussion and decision points flowing from report recommendations that can be used for a strategy discussion with Mosaik trustees.
Mosaik Education requires the final report to be completed by the end of August 2020, allowing for findings to be used at the Mosaik trustee board meeting in September. Therefore, the evaluator needs to be able to deliver to the following timetable:
- Mid-May to June: Desk review of existing documentation, development of draft inception report and Developmental Evaluation plan;
- June to mid-August: data collection, running reflection and learning activities with the Mosaik team;
- Mid to end of August: compilation of draft and final reports; Mosaik review and feedback.
Qualifications and experience required of the individual or team undertaking the evaluation
- Extensive technical knowledge, skills and expertise in evaluation design, concepts, and approaches, and evaluating complex issues, in particular.
- Evidence of delivering high quality developmental evaluations
- Experience with small / start-up organisations is a significant advantage.
- Evaluation experience in international development and/or humanitarian aid.
- Experience of refugee education, youth programming and/or the MENA contexts a significant advantage.
- Facilitation skills and experience, with particular experience of organisational learning.
- Experience undertaking this remotely using online tools is a significant advantage.
- Knowledge and experience of non-profit strategic planning and social innovation business models. Experience in the context of education is a significant advantage.
- Attention to detail, especially related to documenting data and associated processes.
- Excellent written communication and report writing skills in English.
- Strong analytical skills to support both qualitative and quantitative research.
- Confidence in working collaboratively with a remote team.
Resources available to conduct the evaluation
- The maximum budget for this evaluation is £7900, though we welcome bids below this as value for money will be a key criteria in evaluating bids
- MEL Data available to the evaluator
- Data collected from programme participants including baseline, final, feedback and biannual impact measurement data.Two biannual internal MEL reports on collecting data from across programmes.
- Data from after action review workshops with participants, volunteers and partners of the academic guidance programme held in September 2019; and a short evaluation of the Mosaik English class methods, completed as part of a volunteer’s post-graduate project.
Proposal
Please submit a brief proposal (maximum two pages) outlining the approach and experience of the team or individual, a budget, the CVs of the team or individual, and examples of past work to<EMAIL_ADDRESS>by 28 April.
We plan to review proposals and conduct interviews on a rolling basis, so early submission is highly encouraged!


Chapter 31 Introduction to R Markdown
Rmarkdown is an authoring framework for creating a variety of data-driven documents reproducibly with R. This e-book is itself a set of RMarkdown documents, assembled with the {bookdown} package. In many ways, Rmarkdown is a critical package for the R ecosystem, as it is a key enabler of reproducible reports in many formats. RMarkdown is a simple formatting syntax that allows you to mix text and code to document data analysis, and author MS Word, MS Powerpoint, HTML, PDF, web dashboards, web apps, and poster documents. Rmarkdown documents are fully reproducible and support more than a dozen output formats. If your data changes, or you decide to change a part of your analysis, you can reproduce the entire (new version) of the document with a single click of the Knit button (You can also use Cmd/Ctrl+Shift+K). This button is found at the top of the top left pane in RStudio.
When you click the Knit button a document will be generated that includes both text content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this (which will run and produce output below. In this case, showing the contents of the covid_testing dataset.):
<- medicaldata::covid_testing
covid glimpse(covid)
## Rows: 15,524
## Columns: 17
## $ subject_id <dbl> 1412, 533, 9134, 8518, 8967, 11048…
## $ fake_first_name <chr> "jhezane", "penny", "grunt", "meli…
## $ fake_last_name <chr> "westerling", "targaryen", "rivers…
## $ gender <chr> "female", "female", "male", "femal…
## $ pan_day <dbl> 4, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9…
## $ test_id <chr> "covid", "covid", "covid", "covid"…
## $ clinic_name <chr> "inpatient ward a", "clinical lab"…
## $ result <chr> "negative", "negative", "negative"…
## $ demo_group <chr> "patient", "patient", "patient", "…
## $ age <dbl> 0.0, 0.0, 0.8, 0.8, 0.8, 0.8, 0.8,…
## $ drive_thru_ind <dbl> 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0…
## $ ct_result <dbl> 45, 45, 45, 45, 45, 45, 45, 45, 45…
## $ orderset <dbl> 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1…
## $ payor_group <chr> "government", "commercial", NA, NA…
## $ patient_class <chr> "inpatient", "not applicable", NA,…
## $ col_rec_tat <dbl> 1.4, 2.3, 7.3, 5.8, 1.2, 1.4, 2.6,…
## $ rec_ver_tat <dbl> 5.2, 5.8, 4.7, 5.0, 6.4, 7.0, 4.2,…
The Knit button (at the top of the top left pane of RStudio) runs
render("file.Rmd", output = document-type)
for you in a
background (clean) session of R.
31.1 What Makes an Rmarkdown document?
An Rmarkdown document is a plain-text file with the *.Rmd file extension. It is composed of four types of content:
The YAML header (at the top), surrounded at top and bottom by 3 dashes (—)
Text narrative - the meat of your manuscript
Code chunks, surrounded at top and bottom by 3 back-ticks (```), and the
chunk header
in braces, like {r plot-figure}- Note that the first code chunk is always named
setup
and is often used to load libraries and set up document options.
- Note that the first code chunk is always named
Inline code, which does calculations in your text to provide calculated values like means, medians, and p values.
This essentially provides an interface like a ‘lab notebook’ for data analysis. You can use code chunks to run the analysis, and text to document what you are doing in the analysis, how it worked, and interpret the results. When the analysis is ready, you can polish up your document to produce a final manuscript.
Code outputs, including tables and plots, are incorporated into the document.
You can choose to show or hide the code chunks in the final document with options in the chunk header, like:
{r, echo = FALSE}
- runs code, but does not show it.
or
{r, echo = TRUE}
- runs code and shows the code.
31.2 Trying out RMarkdown with a Mock Manuscript
Open up RStudio.
Start a new Project. Click - File - New Project… - Version Control > - Git >
Now paste the following into the Repository URL:
box
https://github.com/higgi13425/rmd4medicine.git
add a directory name, like
rmd4medicine
click on
Create Project
Find the Files tab in the lower right quadrant.
Click to open the
prep
folderClick to open the
mockstudy_analysis.Rmd
file.
This file should open in the top left quadrant of RStudio. If there are warnings at the top of the file that you need to install packages, click on the Install button.
31.3 Inserting Code Chunks
You can add code to your document to process your data and display results.
To insert a code chunk into your Rmarkdown document, click on the green
+c
button at the top center of the top left pane in RStudio.
The dropdown menu will allow you to choose R code or several other computer languages, For now, click on R.
This inserts a gray code chunk, which starts and stops with 3 back-ticks. The starting back-ticks are followed by braces containing a lower-case r, designating what follows as R code.
You can name your individual code chunks with specific names, based on what they do. You can click to the right of the lower-case r, before the closing brace, and add a space, then a name for the code chunk. If the chunk name contains multiple words, connect these with hyphens, as in the code chunk below. Avoid spaces, periods, and underscores in chunk names.
head(covid)
## # A tibble: 6 × 17
## subject_id fake_f…¹ fake_…² gender pan_day test_id clini…³
## <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 1412 jhezane wester… female 4 covid inpati…
## 2 533 penny targar… female 7 covid clinic…
## 3 9134 grunt rivers male 7 covid clinic…
## 4 8518 melisan… swyft female 8 covid clinic…
## 5 8967 rolley karsta… male 8 covid emerge…
## 6 11048 megga karsta… female 8 covid oncolo…
## # … with 10 more variables: result <chr>, demo_group <chr>,
## # age <dbl>, drive_thru_ind <dbl>, ct_result <dbl>,
## # orderset <dbl>, payor_group <chr>, patient_class <chr>,
## # col_rec_tat <dbl>, rec_ver_tat <dbl>, and abbreviated
## # variable names ¹fake_first_name, ²fake_last_name,
## # ³clinic_name
31.3.1 Code Chunk Icons
You may have noticed 3 small icons at the top right of each code chunk. From left to right, these are a (settings) gear, a downward arrowhead with a green baseline (run all of the preceding chunks), and a rightward (run) arrow. Check these out and experiment with them.
| Icon | Uses |
|---|---|
| Settings Gear | Allows you to
|
| Run Chunks Above (down arrow) | Runs all of the preceding code chunks, including the setup chunk |
| Run Chunk (rightward arrow) | Runs the entire current chunk |
31.4 Including Plots
You can also embed plots using code chunks, for example:
%>%
covid ggplot() +
aes(x = pan_day, y = ct_result) +
geom_point() +
labs(title = "COVID Testing in First 100 Days of Pandemic",
x = "Pandemic Day, 2020",
y = "Cycle Threshold \n45 is a Negative Test")
Note that the echo = FALSE
parameter was added to the top of the
plot
code chunk to prevent printing of the R code that generated the
plot. This is an example of a chunk option.
31.5 Including Tables
You can also use code chunks to include tables in your document.
%>%
covid count(demo_group, gender) %>%
gt() %>%
tab_header(title = "Demographics of COVID Testing",
subtitle = "By Group and Gender") %>%
tab_source_note(source_note = "From CHOP, 2020") %>%
cols_label(demo_group = "Group",
gender = "Gender",
n = "Count")
| Demographics of COVID Testing | ||
| By Group and Gender | ||
| Group | Gender | Count |
|---|---|---|
| client | female | 314 |
| client | male | 290 |
| misc adult | female | 1214 |
| misc adult | male | 1227 |
| other adult | female | 126 |
| other adult | male | 97 |
| patient | female | 6178 |
| patient | male | 6077 |
| unidentified | male | 1 |
| From CHOP, 2020 |
Note that this code chunk is using the {gt} package to format the table.
Other popular approaches to table formatting include the {flextable}
package and the knitr::kable()
function.
31.6 Including Links and Images
31.6.1 Links
You can add hypertext links to your text (without a code chunk) with a description in square brackets followed immediately by the URL in (parentheses), like this:
[text description here](http://www.link.com)
As an example, the link to the Rmarkdown cheatsheet can be found at this link.
31.6.2 Images
You can add images to your text if they are in the same project as your
Rmarkdown document. You have to specify the path to the image file
correctly. It is often helpful to collect your images in an images
folder or a figures
folder. If you have already generated your figures
with other R scripts, they can be placed into your manuscript document
from a figures
folder.
You can add images to your text with an exclamation point, followed by a caption in square brackets followed immediately by the path to the image file in (parentheses), on a line of its own, separated from the text, like this:
![Caption for this Figure 1](images/figure_1.png)
You can also insert an image using a code chunk and the knitr function
include_image()
, like this, which gives you more options to control
figure size, alignment, height, and width with code chunk options:
::include_graphics('images/datasaurus-dozen.png') knitr
(note that echo = TRUE and eval=FALSE as code chunk options means that this code is shown, but not run)
An example shown below is an image of the “datasaurus dozen” used to
illustrate what summary measures can hide in data distributions, as seen
below in 12 data distributions with the same mean and standard
deviation, one of which happens to look like a T. Rex. You should always
visualize your data. There might be a dinosaur in there.
(note that echo = FALSE and eval=TRUE as code chunk options means that the code chunk used to include this image code is run, but not shown)
Source for Image: https://juliasilge.com/blog/datasaurus-multiclass/
31.7 Other languages in code chunks
You can use a number of different open-source languages in addition to R if needed to do your data analysis, including SQL, shell code with Unix Bash, C, C++ via Rcpp, Stan, and D3. Any of these options can be chosen from the Insert Code button dropdown (green +c button).
31.8 Code Chunk Options
When you are working through a data analysis, you usually want to
display the code that led to a result. For the final manuscript, you may
want to hide the code and just display the results. You can accomplish
this with echo=TRUE
to display code, and echo=FALSE
to hide the
code.
Code chunk options should be added to the top of each code chunk, in the
chunk header
after the name of the code chunk, and separated from the
chunk name (and from each other) by commas.
The chunk header (material between the braces) must be written on one line. You must not break the line with a return, or it will not work.
| Option | Values | Output |
|---|---|---|
| eval | TRUE/FALSE | Whether or not the code is run. |
| echo | TRUE/FALSE | Show or hide the code |
| include | TRUE/FALSE | Whether or not the
resulting output of a
code chunk is displayed
in the document. FALSE
means that the code
will run, but will not
display results.
include = FALSE is
often used for the setup
chunk. |
| warning | TRUE/FALSE | Whether warnings generated from your code will be displayed in the document. |
| message | TRUE/FALSE | Whether messages generated from your code will be displayed in the document. |
| fig.align | default, left, right, center | Where on the page the
output figure should
align. Text options
should be in quotes,
likefig.align = "right" |
| fig.width | default = 7 | figure width in inches |
| fig .height | default = 7 | figure height in inches |
| error | TRUE/FALSE | If TRUE , will not stop
building the document if
there is an error in a
code chunk. |
| cache | TRUE/FALSE | If TRUE , will store
the results and not
re-run the chunk.
Helpful for long, slow
calculations. But watch
out for this if your
data change and your
results do not(!!). |
Note that there are many more chunk options which you can use if needed, and these can be found here.
31.9 How It All (Rmarkdown + {knitr} + Pandoc) Works
Rmarkdown is an R-flavored version of the markdown
language. This is a
universal, open-source markup language for creating formatted documents
from plain text. Markdown documents end with the file extension *.md.
An open-source program named pandoc
converts *.md documents to output
documents like MS Word, PDF, HTML, MS Powerpoint, etc.
When you click the Knit button or run the render() function, R Markdown feeds the .Rmd file to knitr, which executes all of the code chunks and creates a new markdown (.md) document which includes the code and its output.
The markdown file generated by {knitr} is then processed by pandoc
which is responsible for creating the finished format.
This may sound complicated, but R Markdown makes it extremely simple by encapsulating all of the above processing into a single render() function (or the Knit button).
31.10 Knitting and Editing (and re-Knitting() Your Rmd document
Find the Knit button at the top of the file, and click it to convert
this *.Rmd
. It will automagically knit the document first to markdown
(to *.md
and then from *.md
to *.HTML
.
Scroll through the document to see what has been created.
Go back to the Rmd document.
Now try the following:
in the YAML header, edit the author to your name
edit the date to the current (or a different) date
edit the output from
html_document
toword_document
find the
glimpse
code chunk. After the chunk nameglimpse
, add a comma, then the optionecho=FALSE
Add this same option to a few of of the other code chunks (feel free to use copy-paste, but make sure you don’t end up with duplicate commas, as this will cause errors)
Now click on the Knit button again.
You should get a new version of the document, now in MS Word format, with the code chunks hidden, and a new author and date. The Word document is in a particular default format, but you can change this by specifying a template word file in the YAML header.
31.11 Try Out Other Chunk Options
Try adding different chunk options, including
include = FALSE
eval = FALSE, echo = TRUE
eval=TRUE, echo = FALSE
31.12 The setup
chunk
The setup
chunk is a special code chunk, which is usually the first
code chunk at the top of your RMarkdown document. Typically it includes
two types of code:
- libraries to be loaded
- data to be loaded in the background
and often looks something like this:
library(tidyverse)
library(here)
<- read_csv(here("data/my_data_file.csv")) data
(note that for display purposes, I am using the chunk options
eval = FALSE, echo = TRUE
, while in a real setup chunk, I would use
include = FALSE
, which runs the code but does not display the code nor
the output. I also had to change the chunk name to setup2
because only
unique chunk names are allowed).
Scroll to the setup
chunk at the top of your Rmd document to see what
a working setup chunk looks like.
31.13 Markdown syntax
Markdown is a popular markup language that allows you to add formatting
elements to text, including bold, italics, and code
formatting.
We make text Bold by surrounding the words with double asterisks. We
make text Italic by surrounding the words with single underscores or
single asterisks. We make text Bold and Italic by surrounding the
words with triple underscores or triple asterisks. We can make text in
code-font
by surrounding it with single back-ticks.
You can also format level 1 to level 5 headings. These are done by preceding the heading (on its own line) with 1-5 hashtags.
31.15 Line Breaks and Page Breaks
If you simply hit return in your *.Rmd document, you will see a line
break in your text. But this is only a semantic
line break, as the
knitted document will smush these lines together.
You can create a deliberate line break by adding 2 or more spaces
to
the end of a line of text. This will work in any output format.
The downside of this is that these line breaks are not visible, until you Knit the document.
Line breaks can be inserted (for HTML output) by
using
html
tags
The HTML tag for line breaks is <br>
. But these are kind of
annoying to type,
and 2 spaces at the end of each line is pretty
easy, but less visible when you are looking at the text in the Rmd.
Note that you need a blank line before headers for them to be recognized as headers and formatted properly
31.16 Making Lists
31.16.1 Ordered Lists
You can create an ordered list by preceding items with numbers and period:
- First
- Second
- Third
31.18 Inline Code
You will often want to insert a result into your text, like a percent reduction in an endpoint, or a p value. Rather than copying and pasting from somewhere else (which are prone to error, or forgetting to update), you can do these calculations right in your text, using inline R code. For example, if you want to say that we evaluated NN COVID PCR tests for this study, you can calculate how many rows in your dataset with R, right in the text.
To do this, you bracket the code with single back-ticks, and start with
the letter r immediately after the first back-tick, so that Rmarkdown
knows that R code is coming. After the lower-case r
, you can insert
your code expression, like nrow(covid)
to give you the number of rows
(observations). Putting this together, this looks like
`r nrow(covid)`
. When you insert this in the
middle of a sentence in your text (inline code), this lets you write
sentences in your manuscript like the following, which calculate the
actual number in the text (and automatically update when your data
changes):
We evaluated 15524 COVID PCR tests in this
study.
31.18.1 Try inserting some in-line R code
Try this yourself. Select the correct code to insert the proper results, as illustrated below (note that these would be surrounded by single back-ticks)
The mean cycle threshold in this study wasCorrect answers should produce this output when knit:
The mean cycle threshold in this study was 44.122 and the standard deviation was 3.98.
31.19 A Quick Quiz
- Which code chunk option hides the code?
- Which code chunk always comes first, and includes libraries and data import steps?
- What is the name of the code block (and the markup language it is
written in), set off with 3 hyphens(—) at the very top of your
Rmarkdown document, that tells
pandoc
how to format the final document? - What symbols do you use to make text bold in Rmarkdown?
- Which {knitr} function do you use to add images to your document with a code chunk?